GL Studio C++ Runtime API
gls_metadata_attributes.h
Go to the documentation of this file.
1 /*! \file
2  \brief Defines templated metadata classes for DisplayObjects and other uses.
3 
4  \par Copyright Information
5 
6  Copyright (c) 2017 by The DiSTI Corporation.<br>
7  11301 Corporate Blvd; Suite 100<br>
8  Orlando, Florida 32817<br>
9  USA<br>
10  <br>
11  All rights reserved.<br>
12 
13  This Software contains proprietary trade secrets of DiSTI and may not be
14 reproduced, in whole or part, in any form, or by any means of electronic,
15 mechanical, or otherwise, without the written permission of DiSTI. Said
16 permission may be derived through the purchase of applicable DiSTI product
17 licenses which detail the distribution rights of this content and any
18 Derivative Works based on this or other copyrighted DiSTI Software.
19 
20  NO WARRANTY. THE SOFTWARE IS PROVIDED "AS-IS," WITHOUT WARRANTY OF ANY KIND,
21 AND ANY USE OF THIS SOFTWARE PRODUCT IS AT YOUR OWN RISK. TO THE MAXIMUM EXTENT
22 PERMITTED BY APPLICABLE LAW, DISTI AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES
23 AND CONDITIONS, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
24 IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY AND/OR FITNESS FOR A
25 PARTICULAR PURPOSE, TITLE, AND NON-INFRINGEMENT, WITH REGARD TO THE SOFTWARE.
26 
27  LIMITATION OF LIABILITY. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW,
28 IN NO EVENT SHALL DISTI OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
29 INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION,
30 DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
31 INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR
32 INABILITY TO USE THE SOFTWARE, EVEN IF DISTI HAS BEEN ADVISED OF THE POSSIBILITY
33 OF SUCH DAMAGES. DISTI'S ENTIRE LIABILITY AND YOUR EXCLUSIVE REMEDY SHALL NOT
34 EXCEED FIVE DOLLARS (US$5.00).
35 
36  The aforementioned terms and restrictions are governed by the laws of the
37 State of Florida and the United States of America.
38 
39 */
40 #ifndef INCLUDED_GLS_METADATA_ATTRIBUTES_H
41 #define INCLUDED_GLS_METADATA_ATTRIBUTES_H
42 
43 #include "display.h"
44 #include "disti_metadata.h"
45 #include "dynamic_array.h"
46 #include "gls_include.h"
47 #include "list.h"
48 #include "material.h"
49 #include "util.h"
50 #include "vertex.h"
51 
52 #include <cassert>
53 #include <climits>
54 #include <cstdarg>
55 #include <cstdio>
56 #include <cstdlib>
57 #include <cstring>
58 #include <sstream>
59 #ifdef __VXWORKS__
60 # include <ctype.h>
61 #else
62 # include <cctype>
63 #endif
64 
65 
66 
67 #ifdef DISTI_HAS_CPP11
68 # include <functional>
69 #endif
70 
71 namespace disti
72 {
73 
74 const DistiAttributeBase::CallbackID DISTI_INVALID_CALLBACK_ID = ~0u;
75 
76 // Force the attribute classes to be instanciated
77 // so that they will be exported from the dll
78 // NOTE: These are not necessary if the class is instanciated or specialized elsewhere - BB
79 //template class DistiAttribute<unsigned char>;
80 
81 // DistiAttribute<bool> Specialization
82 template<>
83 inline long DistiAttribute<bool>::ValueInt() { return (long)*_attribPtr; }
84 template<>
85 inline void DistiAttribute<bool>::ValueInt( long val )
86 {
87  *_attribPtr = ( val != 0 );
88  CallCallback();
89 }
90 
91 template<>
92 inline std::ostream& DistiAttribute<bool>::WriteValue( std::ostream& outstr )
93 {
94  outstr << *_attribPtr;
95 
96  return outstr;
97 }
98 
99 // helper function used to remove converting int to bool performance warning on certain compilers
100 template<class T>
101 T ConvertToIntOrBool( int value )
102 {
103  return value;
104 }
105 template<>
106 inline bool ConvertToIntOrBool( int value )
107 {
108  return value != 0;
109 }
110 
111 template<class T>
112 T ReadValueAsIntOrBool( std::istream& instr )
113 {
114  std::string value;
115  instr >> value;
116  T temp;
117  if( strcasecmp( value.c_str(), "TRUE" ) == 0 )
118  {
119  temp = true;
120  }
121  else if( strcasecmp( value.c_str(), "FALSE" ) == 0 )
122  {
123  temp = false;
124  }
125  else
126  {
127  // Check based on an integer value
128  temp = ConvertToIntOrBool<T>( atoi( value.c_str() ) );
129  }
130  return temp;
131 }
132 
133 template<>
134 inline std::istream& DistiAttribute<bool>::ReadValue( std::istream& instr )
135 {
136  *_attribPtr = ReadValueAsIntOrBool<bool>( instr );
137  CallCallback();
138  return instr;
139 }
140 
141 // DistiAttribute<int> Specialization
142 template<>
143 inline long DistiAttribute<int>::ValueInt() { return (long)*_attribPtr; }
144 template<>
145 inline void DistiAttribute<int>::ValueInt( long val )
146 {
147  *_attribPtr = (int)val;
148  CallCallback();
149 }
150 
151 // DistiAttribute<short> Specialization
152 template<>
153 inline long DistiAttribute<short>::ValueInt() { return (long)*_attribPtr; }
154 template<>
155 inline void DistiAttribute<short>::ValueInt( long val )
156 {
157  *_attribPtr = (short)val;
158  CallCallback();
159 }
160 
161 // DistiAttribute<unsigned short> Specialization
162 template<>
163 inline long DistiAttribute<unsigned short>::ValueInt() { return (long)*_attribPtr; }
164 template<>
166 {
167  *_attribPtr = (unsigned short)val;
168  CallCallback();
169 }
170 
171 // DistiAttribute<unsigned char> Specialization
172 template<>
173 inline long DistiAttribute<unsigned char>::ValueInt() { return (long)*_attribPtr; }
174 template<>
176 {
177  *_attribPtr = (unsigned char)val;
178  CallCallback();
179 }
180 
181 template<>
182 inline std::ostream& DistiAttribute<unsigned char>::WriteValue( std::ostream& outstr )
183 {
184  // If we don't cast to int, an actual character will be written. We want a number.
185  outstr << (int)*_attribPtr;
186  return outstr;
187 }
188 
189 template<>
190 inline std::istream& DistiAttribute<unsigned char>::ReadValue( std::istream& instr )
191 {
192  // If we don't cast to int, an actual character will be read. We want a number.
193  // Also, integer types should be able to read as TRUE or FALSE to preserve backwards compatibility for certain attributes (formerly handled by DistiAttributeUCharOrBool)
194  *_attribPtr = static_cast<unsigned char>( ReadValueAsIntOrBool<int>( instr ) );
195  CallCallback();
196  return instr;
197 }
198 
199 template<>
200 inline std::istream& DistiAttribute<int>::ReadValue( std::istream& instr )
201 {
202  // integer types should be able to read as TRUE or FALSE to preserve backwards compatibility for certain attributes (formerly handled by DistiAttributeUCharOrBool)
203  *_attribPtr = ReadValueAsIntOrBool<int>( instr );
204  CallCallback();
205  return instr;
206 }
207 
208 template<>
209 inline std::istream& DistiAttribute<unsigned int>::ReadValue( std::istream& instr )
210 {
211  // integer types should be able to read as TRUE or FALSE to preserve backwards compatibility for certain attributes (formerly handled by DistiAttributeUCharOrBool)
212  *_attribPtr = ReadValueAsIntOrBool<unsigned int>( instr );
213  CallCallback();
214  return instr;
215 }
216 
217 // DistiAttribute<float> Specialization
218 template<>
219 inline long DistiAttribute<float>::ValueInt() { return (long)*_attribPtr; }
220 
221 template<>
222 inline void DistiAttribute<float>::ValueInt( long val )
223 {
224  *_attribPtr = (float)val;
225  CallCallback();
226 }
227 
228 /** Special case for transitioning from a bool to an int
229  * Reads True or False, or integers.
230  * Writes only integers.
231  */
232 class DistiAttributeUCharOrBool : public DistiAttribute<unsigned char>
233 {
234 public:
235  GLS_EXPORT DistiAttributeUCharOrBool( CallbackMethodCallerBase* callback, const AttributeName& name, unsigned char* attribPtr );
236  GLS_EXPORT DistiAttributeUCharOrBool( CallbackMethodCallerBase* callback, const AttributeName& name, unsigned char value );
237 
238  virtual GLS_EXPORT DistiAttributeBase& operator=( const DistiAttributeBase& oldClass );
239 
240  virtual GLS_EXPORT long ValueInt();
241  virtual GLS_EXPORT void ValueInt( long val );
242 
243  virtual GLS_EXPORT std::ostream& WriteValue( std::ostream& outstr );
244  virtual GLS_EXPORT std::istream& ReadValue( std::istream& instr );
245 };
246 
247 /** For fixed length float arrays
248  */
250 {
251  float* _array;
252  int _length;
253 
254 public:
255  GLS_EXPORT DistiAttributeFloatArray( CallbackMethodCallerBase* callback, const AttributeName& name, float* floatArray, int length );
256  virtual GLS_EXPORT ~DistiAttributeFloatArray();
257 
258  virtual GLS_EXPORT bool OkToWrite() const;
259 
260  virtual GLS_EXPORT std::ostream& WriteValue( std::ostream& outstr );
261  virtual GLS_EXPORT std::istream& ReadValue( std::istream& instr );
262 };
263 
264 /** For fixed length double arrays
265  */
267 {
268  double* _array;
269  int _length;
270 
271 public:
272  GLS_EXPORT DistiAttributeDoubleArray( CallbackMethodCallerBase* callback, const AttributeName& name, double* doubleArray, int length );
273  virtual GLS_EXPORT ~DistiAttributeDoubleArray();
274 
275  virtual GLS_EXPORT bool OkToWrite() const;
276 
277  virtual GLS_EXPORT std::ostream& WriteValue( std::ostream& outstr );
278  virtual GLS_EXPORT std::istream& ReadValue( std::istream& instr );
279 };
280 
281 /** An enumeration for Texture Mode */
282 static DistiAttributeEnumDefList TextureModeEnumList(
283  (char*)"TEXTURE_MAP_MODULATE", TEXTURE_MAP_MODULATE,
284  (char*)"TEXTURE_MAP_DECAL", TEXTURE_MAP_DECAL,
285  (char*)"TEXTURE_MAP_BLEND", TEXTURE_MAP_BLEND,
286  (char*)"TEXTURE_MAP_REPLACE", TEXTURE_MAP_REPLACE,
287  NULL );
288 
289 /** Disti Attribute Texture Mode Enum */
290 template<class containerClass>
291 class DistiAttributeTextureModeEnum : public DistiAttributeEnum<containerClass, const int, int>
292 {
293 public:
294  DISTI_DEPRECATED( "This identifier is forbidden by the C++ standard. Use BaseClass instead." )
297  using BaseClass::_pairList;
298 
299  typedef void ( containerClass::*SetMethodType )( const int );
300  typedef int ( containerClass::*GetMethodType )();
301 
302  DistiAttributeTextureModeEnum<containerClass>( containerClass* frame, SetMethodType setMethod, GetMethodType getMethod, const AttributeName& name )
303  : DistiAttributeEnum<containerClass, const int, int>( frame, setMethod, getMethod, name )
304  {
305  _pairList = &TextureModeEnumList;
306  }
307 };
308 
309 /** An enumeration for Texture Filter */
310 static DistiAttributeEnumDefList TextureFilterEnumList(
311  (char*)"TEXTURE_FILTER_NEAREST", TEXTURE_FILTER_NEAREST,
312  (char*)"TEXTURE_FILTER_LINEAR", TEXTURE_FILTER_LINEAR,
313  (char*)"TEXTURE_FILTER_NEAREST_MIPMAP_NEAREST", TEXTURE_FILTER_NEAREST_MIPMAP_NEAREST,
314  (char*)"TEXTURE_FILTER_LINEAR_MIPMAP_LINEAR", TEXTURE_FILTER_LINEAR_MIPMAP_LINEAR,
315  (char*)"TEXTURE_FILTER_NEAREST_MIPMAP_LINEAR", TEXTURE_FILTER_NEAREST_MIPMAP_LINEAR,
316  (char*)"TEXTURE_FILTER_LINEAR_MIPMAP_NEAREST", TEXTURE_FILTER_LINEAR_MIPMAP_NEAREST,
317  NULL );
318 
319 /** Disti Attribute Texture Filter Enum */
320 template<class containerClass>
321 class DistiAttributeTextureFilterEnum : public DistiAttributeEnum<containerClass, const int, int>
322 {
323 public:
324  DISTI_DEPRECATED( "This identifier is forbidden by the C++ standard. Use BaseClass instead." )
327  using BaseClass::_pairList;
328 
329  typedef void ( containerClass::*SetMethodType )( const int );
330  typedef int ( containerClass::*GetMethodType )();
331 
332  DistiAttributeTextureFilterEnum<containerClass>( containerClass* frame, SetMethodType setMethod, GetMethodType getMethod, const AttributeName& name )
333  : DistiAttributeEnum<containerClass, const int, int>( frame, setMethod, getMethod, name )
334  {
335  _pairList = &TextureFilterEnumList;
336  }
337 };
338 
339 /** An enumeration for Polygon Mode */
340 static DistiAttributeEnumDefList PolyModeEnumList(
341  (char*)"POLY_MODE_UNDEFINED", POLY_MODE_UNDEFINED,
342  (char*)"POLY_MODE_POINTS", POLY_MODE_POINTS,
343  (char*)"POLY_MODE_OUTLINE", POLY_MODE_OUTLINE,
344  (char*)"POLY_MODE_FILLED", POLY_MODE_FILLED,
345  (char*)"POLY_MODE_FILL_AND_OUTLINE", POLY_MODE_FILL_AND_OUTLINE,
346  NULL );
347 
348 /** Disti Attribute Poly Mode Enum */
349 template<class containerClass>
350 class DistiAttributePolyModeEnum : public DistiAttributeEnum<containerClass, const int, int>
351 {
352 public:
353  DISTI_DEPRECATED( "This identifier is forbidden by the C++ standard. Use BaseClass instead." )
356  using BaseClass::_pairList;
357 
358  typedef void ( containerClass::*SetMethodType )( const int );
359  typedef int ( containerClass::*GetMethodType )();
360 
361  DistiAttributePolyModeEnum<containerClass>( containerClass* frame, SetMethodType setMethod, GetMethodType getMethod, const AttributeName& name )
362  : DistiAttributeEnum<containerClass, const int, int>( frame, setMethod, getMethod, name )
363  {
364  _pairList = &PolyModeEnumList;
365  }
366 };
367 
368 /** An enumeration for Polygon End Mode */
369 static DistiAttributeEnumDefList PolyEndEnumList(
370  (char*)"POLY_OPEN", POLY_OPEN,
371  (char*)"POLY_CLOSED", POLY_CLOSED,
372  NULL );
373 
374 /** Disti Attribute Poly End Enum */
375 template<class containerClass>
376 class DistiAttributePolyEndEnum : public DistiAttributeEnum<containerClass, int, int>
377 {
378 public:
379  DISTI_DEPRECATED( "This identifier is forbidden by the C++ standard. Use BaseClass instead." )
382  using BaseClass::_pairList;
383 
384  typedef void ( containerClass::*SetMethodType )( int );
385  typedef int ( containerClass::*GetMethodType )();
386 
387  DistiAttributePolyEndEnum<containerClass>( containerClass* frame, SetMethodType setMethod, GetMethodType getMethod, const AttributeName& name )
388  : DistiAttributeEnum<containerClass, int, int>( frame, setMethod, getMethod, name )
389  {
390  _pairList = &PolyEndEnumList;
391  }
392 };
393 
394 /** An enumeration for Shading enum */
395 static DistiAttributeEnumDefList ShadingEnumList(
396  (char*)"FLAT", SHADING_FLAT,
397  (char*)"GOURAUD", SHADING_GOURAUD,
398  NULL );
399 
400 /** Disti Attribute Shading Enum */
401 template<class containerClass>
402 class DistiAttributeShadingEnum : public DistiAttributeEnum<containerClass, const int, int>
403 {
404 public:
405  DISTI_DEPRECATED( "This identifier is forbidden by the C++ standard. Use BaseClass instead." )
408  using BaseClass::_pairList;
409 
410  typedef void ( containerClass::*SetMethodType )( const int );
411  typedef int ( containerClass::*GetMethodType )();
412 
413  DistiAttributeShadingEnum<containerClass>( containerClass* frame, SetMethodType setMethod, GetMethodType getMethod, const AttributeName& name )
414  : DistiAttributeEnum<containerClass, const int, int>( frame, setMethod, getMethod, name )
415  {
416  _pairList = &ShadingEnumList;
417  }
418 };
419 
420 /** An enumeration for ColorMaterialMode enum */
421 template<class containerClass>
422 class DistiAttributeColorMaterialModeEnum : public DistiAttributeEnum<containerClass, const int, int>
423 {
424 public:
425  DISTI_DEPRECATED( "This identifier is forbidden by the C++ standard. Use BaseClass instead." )
428  using BaseClass::_pairList;
429 
430  typedef void ( containerClass::*SetMethodType )( const int );
431  typedef int ( containerClass::*GetMethodType )();
432 
433  DistiAttributeColorMaterialModeEnum<containerClass>( containerClass* frame, SetMethodType setMethod, GetMethodType getMethod, const AttributeName& name )
434  : DistiAttributeEnum<containerClass, const int, int>( frame, setMethod, getMethod, name )
435  {
436  static DistiAttributeEnumDefList ColorMaterialModeEnum(
437  (char*)"NO_COLOR_MATERIAL", NO_COLOR_MATERIAL,
438  (char*)"DIFFUSE_COLOR_MATERIAL", DIFFUSE_COLOR_MATERIAL,
439  (char*)"AMBIENT_COLOR_MATERIAL", AMBIENT_COLOR_MATERIAL,
440  (char*)"DIFFUSE_AND_AMBIENT_COLOR_MATERIAL", DIFFUSE_AND_AMBIENT_COLOR_MATERIAL,
441  (char*)"EMISSION_COLOR_MATERIAL", EMISSION_COLOR_MATERIAL,
442  (char*)"SPECULAR_COLOR_MATERIAL", SPECULAR_COLOR_MATERIAL,
443  NULL );
444 
445  _pairList = &ColorMaterialModeEnum;
446  }
447 
448  virtual GLS_EXPORT bool OkToWrite() const { return false; }
449 };
450 
451 /** An enumeration for Protection */
452 template<class containerClass>
453 class DistiAttributeProtectionEnum : public DistiAttributeEnum<containerClass, const int, int>
454 {
455 public:
456  DISTI_DEPRECATED( "This identifier is forbidden by the C++ standard. Use BaseClass instead." )
459  using BaseClass::_pairList;
460 
461  typedef void ( containerClass::*SetMethodType )( const int );
462  typedef int ( containerClass::*GetMethodType )();
463 
464  DistiAttributeProtectionEnum<containerClass>( containerClass* frame, SetMethodType setMethod, GetMethodType getMethod, const AttributeName& name )
465  : DistiAttributeEnum<containerClass, const int, int>( frame, setMethod, getMethod, name )
466  {
467  static DistiAttributeEnumDefList ProtectionEnumList(
468  (char*)"PUBLIC", PUBLIC,
469  (char*)"PRIVATE", PRIVATE,
470  (char*)"PROTECTED", PROTECTED,
471  NULL );
472  _pairList = &ProtectionEnumList;
473  }
474 };
475 
476 /** An enumeration for Alpha Mode */
477 static DistiAttributeEnumDefList AlphaModeEnumList(
478  (char*)"ALPHA_MODE_UNDEFINED", ALPHA_MODE_UNDEFINED,
479  (char*)"ALPHA_MODE_OPAQUE", ALPHA_MODE_OPAQUE,
480  (char*)"ALPHA_MODE_2_LEVEL", ALPHA_MODE_2_LEVEL,
481  (char*)"ALPHA_MODE_256_LEVEL", ALPHA_MODE_256_LEVEL,
482  NULL );
483 
484 /** Disti Attribute Alpha Mode Enum */
485 template<class containerClass>
486 class DistiAttributeAlphaModeEnum : public DistiAttributeEnum<containerClass, const int, int>
487 {
488 public:
489  DISTI_DEPRECATED( "This identifier is forbidden by the C++ standard. Use BaseClass instead." )
492  using BaseClass::_pairList;
493 
494  typedef void ( containerClass::*SetMethodType )( const int );
495  typedef int ( containerClass::*GetMethodType )();
496 
497  DistiAttributeAlphaModeEnum<containerClass>( containerClass* frame, SetMethodType setMethod, GetMethodType getMethod, const AttributeName& name )
498  : DistiAttributeEnum<containerClass, const int, int>( frame, setMethod, getMethod, name )
499  {
500  _pairList = &AlphaModeEnumList;
501  }
502 };
503 
504 /** An attribute for a char* string
505  */
507 {
508  char* _local;
509 
510 protected:
511  char** _attribPtr;
512 
513 public:
514  // This constructor makes the bold assumption that it can modify the contents
515  // of the supplied char*, by realocating the memory.
516  GLS_EXPORT DistiAttributeString( CallbackMethodCallerBase* callback, const AttributeName& name, char** attribPtr );
517 
518  // Creates local storage, and will resize as needed
519  GLS_EXPORT DistiAttributeString( CallbackMethodCallerBase* callback, const AttributeName& name, char* initialValue );
520  virtual GLS_EXPORT ~DistiAttributeString();
521 
522  // Be careful with this
523  GLS_EXPORT char* LocalStorageString();
524  virtual GLS_EXPORT bool OkToWrite() const;
525 
526  virtual GLS_EXPORT std::ostream& WriteValue( std::ostream& outstr );
527  virtual GLS_EXPORT std::istream& ReadValue( std::istream& instr );
528 };
529 
530 /** Derived from DistiAttributeString, the only difference is that it
531  * reads and writes encoded strings instead of clear strings.
532  */
534 {
535 public:
536  GLS_EXPORT DistiAttributeEncodedString( CallbackMethodCallerBase* callback, const AttributeName& name, char** attribPtr );
537 
538  // Creates local storage, and will resize as needed
539  GLS_EXPORT DistiAttributeEncodedString( CallbackMethodCallerBase* callback, const AttributeName& name, char* initialValue );
540 
541  // Normally ValueString just returns the value of WriteValue, but for encoded strings
542  // this is probably not what we want, so have ValueString work with the unencoded string
543  virtual GLS_EXPORT std::string ValueString();
544  virtual GLS_EXPORT void ValueString( const std::string& s );
545 
546  virtual GLS_EXPORT std::ostream& WriteValue( std::ostream& outstr );
547  virtual GLS_EXPORT std::istream& ReadValue( std::istream& instr );
548 };
549 
550 /** Derived from DistiAttributeStdString, the only difference is that it
551  * reads and writes encoded strings instead of clear strings.
552  */
554 {
555 public:
556  GLS_EXPORT DistiAttributeEncodedStdString( CallbackMethodCallerBase* callback, const AttributeName& name, std::string* attribPtr );
557 
558  // Creates local storage, and will resize as needed
559  GLS_EXPORT DistiAttributeEncodedStdString( CallbackMethodCallerBase* callback, const AttributeName& name, std::string initialValue );
560 
561  GLS_EXPORT bool OkToWrite() const DISTI_METHOD_OVERRIDE;
562 
563  // Normally ValueString just returns the value of WriteValue, but for encoded strings
564  // this is probably not what we want, so have ValueString work with the unencoded string
565  GLS_EXPORT std::string ValueString() DISTI_METHOD_OVERRIDE;
566  GLS_EXPORT void ValueString( const std::string& s ) DISTI_METHOD_OVERRIDE;
567 
568  GLS_EXPORT std::ostream& WriteValue( std::ostream& outstr ) DISTI_METHOD_OVERRIDE;
569  GLS_EXPORT std::istream& ReadValue( std::istream& instr ) DISTI_METHOD_OVERRIDE;
570 };
571 /** For fixed length char array */
573 {
574  char* _string;
575  int _length;
576 
577 public:
578  GLS_EXPORT DistiAttributeFixedString( CallbackMethodCallerBase* callback, const AttributeName& name, char* string, int length );
579  virtual GLS_EXPORT ~DistiAttributeFixedString();
580 
581  virtual GLS_EXPORT std::ostream& WriteValue( std::ostream& outstr );
582  virtual GLS_EXPORT std::istream& ReadValue( std::istream& instr );
583 };
584 
585 /** Attribute for std::string */
586 class DistiAttributeStdString : public DistiAttribute<std::string>
587 {
588  std::string _localStorageString;
589 
590 public:
591  // This constructor has the storage external
592  GLS_EXPORT DistiAttributeStdString( CallbackMethodCallerBase* callback, const AttributeName& name, std::string* attribPtr );
593 
594  // Creates local storage, and will resize as needed
595  GLS_EXPORT DistiAttributeStdString( CallbackMethodCallerBase* callback, const AttributeName& name, std::string initialValue );
596  virtual GLS_EXPORT ~DistiAttributeStdString();
597 
598  // Be carefull with this
599  GLS_EXPORT std::string* LocalStorageString();
600 
601  virtual GLS_EXPORT bool OkToWrite() const;
602 
603  virtual GLS_EXPORT std::ostream& WriteValue( std::ostream& outstr );
604  virtual GLS_EXPORT std::istream& ReadValue( std::istream& instr );
605 };
606 
607 /** Attribute for Location */
609 {
610 public:
611  GLS_EXPORT DistiAttributeLocation( CallbackMethodCallerBase* callback, const AttributeName& name, Vertex* attribPtr );
612  virtual GLS_EXPORT ~DistiAttributeLocation();
613 
614  virtual GLS_EXPORT std::ostream& WriteValue( std::ostream& outstr );
615  virtual GLS_EXPORT std::istream& ReadValue( std::istream& instr );
616 };
617 
618 /** Attribute for a dictionary of attributes */
620 {
621 protected:
622  DistiAttribDict* _dict;
623 
624 public:
625  GLS_EXPORT DistiAttributeDictionaryAttribute( const AttributeName& name, DistiAttribDict* dict );
626 
627  virtual GLS_EXPORT bool OkToWrite() const;
628 
629  virtual void Add( DistiAttributeBase* attr ) { _dict->Add( attr ); }
630  virtual GLS_EXPORT std::ostream& WriteValue( std::ostream& outstr );
631  virtual GLS_EXPORT std::istream& ReadValue( std::istream& instr );
632 };
633 
634 /** Attribute for a dictionary of attributes that cares for its siblings */
636 {
637 protected:
638  DistiAttribDict* _dict;
639  DistiAttributeBase* _sibling;
640  bool _hasRead;
641 
642 public:
644 
645  virtual GLS_EXPORT bool OkToWrite() const;
646 
647  virtual void Add( DistiAttributeBase* attr ) { _dict->Add( attr ); }
648  virtual GLS_EXPORT std::ostream& WriteValue( std::ostream& outstr );
649  virtual GLS_EXPORT std::istream& ReadValue( std::istream& instr );
650 };
651 
652 //----------------------------------------------------------------------------
653 //----------------------------------------------------------------------------
654 /** \class DistiAttributeStdMap
655  * An attribute for a std::map
656  */
657 template<class Map_t>
659 {
660  Map_t* _attribPtr;
661 
662 public:
663  //------------------------------------------------------------------------
665  CallbackMethodCallerBase* callback, const AttributeName& name, Map_t* attribPtr )
666  : DistiAttributeBase( callback, name, false )
667  , _attribPtr( attribPtr )
668  {
669  }
670  //------------------------------------------------------------------------
672  : DistiAttributeBase( callback, name, true )
673  , _attribPtr( new Map_t() )
674  {
675  }
676  //------------------------------------------------------------------------
677  virtual ~DistiAttributeStdMap()
678  {
679  if( _localStorage )
680  delete _attribPtr;
681  _attribPtr = NULL;
682  }
683  //------------------------------------------------------------------------
684  virtual bool OkToWrite() const
685  {
686  return _attribPtr != 0 && _attribPtr->size();
687  }
688  //------------------------------------------------------------------------
689  static std::string GetEmptyValue() { return "$$DISTI_EMPTY$$"; }
690  //------------------------------------------------------------------------
691  virtual std::ostream& WriteValue( std::ostream& outstr )
692  {
693  outstr << "\n"
694  << DistiAttribDict::SpacingString() << "{\n";
695  DistiAttribDict::SpacingInc();
696 
697  if( _attribPtr )
698  {
699  typename Map_t::iterator i;
700  for( i = _attribPtr->begin(); i != _attribPtr->end(); ++i )
701  {
702  std::ostringstream str;
703  str << i->second;
704  const std::string second = str.str();
705 
706  outstr << DistiAttribDict::SpacingString() << i->first << " "
707  << ( second.empty() ? GetEmptyValue() : second ) << '\n';
708  }
709  }
710 
711  DistiAttribDict::SpacingDec();
712  outstr << DistiAttribDict::SpacingString() << "}\n";
713 
714  return outstr;
715  }
716  //------------------------------------------------------------------------
717  virtual std::istream& ReadValue( std::istream& instr )
718  {
719  instr.ignore( INT_MAX, '{' );
720 
721  if( instr.good() )
722  {
723  std::stringstream fontStream;
724  instr.get( *fontStream.rdbuf(), '}' );
725  if( instr.good() )
726  {
727  instr.ignore( 1 );
728  while( fontStream.good() )
729  {
730  // Get rid of all the leading white space before reading the key
731 #ifdef _WIN32
732  std::stringstream::char_type c;
733 #else
734  // std::stringstream::char_type c; causes a parse error before `;' on Linux
735  char c;
736 #endif
737  do
738  {
739  fontStream.get( c );
740  } while( fontStream.good() && isspace( c ) );
741 
742  if( fontStream.good() )
743  {
744  fontStream.putback( c );
745 
746 #if _WIN32 && _MSC_VER < 1300 // if _MSC_VER < vc70
747  Map_t::key_type key;
748  Map_t::referent_type value;
749 #else
750  typename Map_t::key_type key;
751  typename Map_t::mapped_type value;
752 #endif
753  std::string strVal;
754  fontStream >> key;
755  std::getline( fontStream >> std::ws, strVal );
756 
757  if( strVal != GetEmptyValue() )
758  {
759  std::istringstream str( strVal );
760  str >> value;
761  }
762 
763  ( *_attribPtr )[ key ] = value;
764  }
765  }
766  }
767  }
768  return instr;
769  }
770 }; // end DistiAttributeStdMap
771 
772 /** \class DistiAttributeVertexArray
773  * An attribute for either a Vector or Vertex
774  */
775 template<class T> // Either Vector or Vertex
777 {
778 protected:
779  T** _attribPtr;
780  typedef T* Tptr;
781  unsigned int* _numVertices;
782  unsigned int _numElements;
783  bool _fixedArray;
784  bool _compatabilityMode;
785 
786 public:
787  void SetCompatabilityMode( bool mode ) { _compatabilityMode = mode; }
788  // For variable length arrays
789  DistiAttributeVertexArray( CallbackMethodCallerBase* callback, const AttributeName& name, T** attribPtr, unsigned int* numVertices )
790  : DistiAttributeBase( callback, name, false )
791  , _attribPtr( attribPtr )
792  , _numVertices( numVertices )
793  , _numElements( 0 )
794  , _fixedArray( false )
795  {
796  _compatabilityMode = true;
797  }
798  // For fixed arrays
799  DistiAttributeVertexArray( CallbackMethodCallerBase* callback, const AttributeName& name, T* attribPtr, unsigned int numElements )
800  : DistiAttributeBase( callback, name, true )
801  , _attribPtr( new Tptr( attribPtr ) )
802  , _numVertices( NULL )
803  , _numElements( numElements )
804  , _fixedArray( true )
805  {
806  _compatabilityMode = true;
807  }
808 
809  virtual ~DistiAttributeVertexArray()
810  {
811  if( ( _fixedArray || _localStorage ) && _attribPtr )
812  delete _attribPtr;
813  _attribPtr = NULL;
814  }
815 
816  virtual bool OkToWrite() const
817  {
818  return ( *_attribPtr != NULL );
819  }
820 
821  virtual std::ostream& WriteValue( std::ostream& outstr )
822  {
823  if( *_attribPtr != NULL )
824  {
825  unsigned int numVerts = _numElements;
826  if( !_fixedArray )
827  {
828  outstr << *_numVertices;
829  numVerts = *_numVertices;
830  }
831  DistiAttribDict::SpacingInc();
832  for( unsigned int i = 0; i < numVerts; i++ )
833  {
834  outstr << '\n';
835  outstr << ( *_attribPtr )[ i ];
836  }
837  DistiAttribDict::SpacingDec();
838  }
839  return outstr;
840  }
841  virtual std::istream& ReadValue( std::istream& instr )
842  {
843  unsigned int numVerts = _numElements;
844 
845  if( !_fixedArray )
846  {
847  instr >> numVerts;
848  *_numVertices = numVerts;
849 
850  // Remove old storage if any
851  if( *_attribPtr != NULL )
852  delete[] * _attribPtr;
853 
854  // Create new storage
855  if( numVerts > 0 )
856  *_attribPtr = new T[ numVerts ];
857  else
858  *_attribPtr = NULL;
859  }
860 
861  if( !_compatabilityMode )
862  {
863  char buf[ 1024 ];
864  // Get newline character
865  instr.getline( buf, 1024 );
866  }
867 
868  for( unsigned int i = 0; i < numVerts; i++ )
869  {
870  if( !_compatabilityMode )
871  {
872  char buf[ 1024 ];
873  instr.getline( buf, 1024 );
874 #ifdef GLS_DEBUG
875  int count =
876 #endif
877  std::sscanf( buf, "%f %f %f",
878  &( ( *_attribPtr )[ i ].x ),
879  &( ( *_attribPtr )[ i ].y ),
880  &( ( *_attribPtr )[ i ].z ) );
881 #ifdef GLS_DEBUG
882  assert( 3 == count );
883 #endif
884  }
885  else
886  {
887  instr >> ( *_attribPtr )[ i ];
888  }
889  }
890  CallCallback();
891  return instr;
892  }
893 
894  virtual bool operator==( const DistiAttributeBase& rArg )
895  {
896  DistiAttributeVertexArray<T>* r = dynamic_cast<DistiAttributeVertexArray<T>*>( const_cast<DistiAttributeBase*>( &rArg ) );
897  if( !r )
898  {
899  return DistiAttributeBase::operator==( rArg );
900  }
901 
902  if( !( _name == r->_name ) || _numElements != r->_numElements )
903  return false;
904 
905  for( unsigned int i = 0u; i < _numElements; ++i )
906  {
907  T leftVert = ( *_attribPtr )[ i ];
908  T rightVert = ( *r->_attribPtr )[ i ];
909  if( !disti::Equal( leftVert.x, rightVert.x ) || !disti::Equal( leftVert.y, rightVert.y ) || !disti::Equal( leftVert.z, rightVert.z ) )
910  {
911  return false;
912  }
913  }
914 
915  return true;
916  }
917 };
918 
919 /** An attribute for either a Vector or Vertex */
920 template<>
922 {
923 protected:
924  Vertex** _attribPtr;
925  typedef Vertex* Tptr;
926  unsigned int* _numVertices;
927  unsigned int _numElements;
928  bool _fixedArray;
929  bool _compatabilityMode;
930 
931 public:
932  void SetCompatabilityMode( bool mode ) { _compatabilityMode = mode; }
933  // For variable length arrays
934  DistiAttributeVertexArray( CallbackMethodCallerBase* callback, const AttributeName& name, Vertex** attribPtr, unsigned int* numVertices )
935  : DistiAttributeBase( callback, name, false )
936  , _attribPtr( attribPtr )
937  , _numVertices( numVertices )
938  , _numElements( 0 )
939  , _fixedArray( false )
940  {
941  _compatabilityMode = true;
942  }
943  // For fixed arrays
944  DistiAttributeVertexArray( CallbackMethodCallerBase* callback, const AttributeName& name, Vertex* attribPtr, unsigned int numElements )
945  : DistiAttributeBase( callback, name, true )
946  , _attribPtr( new Tptr( attribPtr ) )
947  , _numVertices( NULL )
948  , _numElements( numElements )
949  , _fixedArray( true )
950  {
951  _compatabilityMode = true;
952  }
953 
954  virtual ~DistiAttributeVertexArray()
955  {
956  if( ( _fixedArray || _localStorage ) && _attribPtr )
957  delete _attribPtr;
958  _attribPtr = NULL;
959  }
960 
961  virtual bool OkToWrite() const
962  {
963  return ( *_attribPtr != NULL );
964  }
965 
966  virtual std::ostream& WriteValue( std::ostream& outstr )
967  {
968  if( *_attribPtr != NULL )
969  {
970  unsigned int numVerts = _numElements;
971  if( !_fixedArray )
972  {
973  outstr << *_numVertices;
974  numVerts = *_numVertices;
975  }
976  DistiAttribDict::SpacingInc();
977  for( unsigned int i = 0; i < numVerts; i++ )
978  {
979  outstr << '\n';
980  outstr << ( *_attribPtr )[ i ];
981  }
982  DistiAttribDict::SpacingDec();
983  }
984  return outstr;
985  }
986  virtual std::istream& ReadValue( std::istream& instr )
987  {
988  unsigned int numVerts = _numElements;
989 
990  if( !_fixedArray )
991  {
992  instr >> numVerts;
993  *_numVertices = numVerts;
994 
995  // Remove old storage if any
996  if( *_attribPtr != NULL )
997  delete[] * _attribPtr;
998 
999  // Create new storage
1000  *_attribPtr = new Vertex[ numVerts ];
1001  }
1002 
1003  if( !_compatabilityMode )
1004  {
1005  char buf[ 1024 ];
1006  // Get newline character
1007  instr.getline( buf, 1024 );
1008  }
1009 
1010  for( unsigned int i = 0; i < numVerts; i++ )
1011  {
1012  if( !_compatabilityMode )
1013  {
1014  char buf[ 1024 ];
1015  instr.getline( buf, 1024 );
1016  int r, g, b, a;
1017 #ifdef GLS_DEBUG
1018  int count =
1019 #endif
1020  std::sscanf( buf, "%f %f %f %d %d %d %d",
1021  &( ( *_attribPtr )[ i ].x ),
1022  &( ( *_attribPtr )[ i ].y ),
1023  &( ( *_attribPtr )[ i ].z ),
1024  &r, &g, &b, &a );
1025 #ifdef GLS_DEBUG
1026  assert( 7 == count );
1027 #endif
1028 
1029  ( *_attribPtr )[ i ].color.RGBA( (unsigned char)r, (unsigned char)g, (unsigned char)b, (unsigned char)a );
1030  }
1031  else
1032  {
1033  instr >> ( *_attribPtr )[ i ];
1034  }
1035  }
1036  CallCallback();
1037  return instr;
1038  }
1039 
1040  virtual bool operator==( const DistiAttributeBase& rArg )
1041  {
1042  DistiAttributeVertexArray<Vertex>* r = dynamic_cast<DistiAttributeVertexArray<Vertex>*>( const_cast<DistiAttributeBase*>( &rArg ) );
1043  if( !r )
1044  {
1045  return DistiAttributeBase::operator==( rArg );
1046  }
1047 
1048  if( !( _name == r->_name ) || _numElements != r->_numElements )
1049  return false;
1050 
1051  for( unsigned int i = 0u; i < _numElements; ++i )
1052  {
1053  Vertex leftVert = ( *_attribPtr )[ i ];
1054  Vertex rightVert = ( *r->_attribPtr )[ i ];
1055  if( !disti::Equal( leftVert.x, rightVert.x ) || !disti::Equal( leftVert.y, rightVert.y ) || !disti::Equal( leftVert.z, rightVert.z ) || leftVert.color != rightVert.color )
1056  {
1057  return false;
1058  }
1059  }
1060 
1061  return true;
1062  }
1063 };
1064 
1065 /** This is used specifically for changing from TexturePoints as Vertexs to TexturePoints as Vectors.
1066  * It uses file version information to decide when expect what.
1067  */
1069 {
1070 public:
1071  // For fixed arrays
1072  DistiAttributeTexturePointArray( CallbackMethodCallerBase* callback, const AttributeName& name, Vector* attribPtr, unsigned int numElements )
1073  : DistiAttributeVertexArray<Vector>( callback, name, attribPtr, numElements )
1074  {
1075  }
1076 
1077  virtual std::ostream& WriteValue( std::ostream& outstr )
1078  {
1079  unsigned int numVerts = _numElements;
1080 
1081  for( unsigned int i = 0; i < numVerts; i++ )
1082  {
1083  outstr << '\n';
1084  outstr << ( *_attribPtr )[ i ];
1085  }
1086  return outstr;
1087  }
1088 
1089  virtual std::istream& ReadValue( std::istream& instr )
1090  {
1091  unsigned int numVerts = _numElements;
1092 
1093  for( unsigned int i = 0; i < numVerts; i++ )
1094  {
1095  // Get the whole line and then stream it into the Vector.
1096  // Before version 3.0, GL Studio files had full Vertex data
1097  // including color information stored after the location.
1098  // Reading whole lines comsumes this color information which is
1099  // then discarded.
1100  std::string line;
1101  std::getline( instr, line );
1102  // There must have been a leading newline, so read the first line again
1103  if( i == 0 && line.length() == 0 )
1104  std::getline( instr, line );
1105 
1106  std::stringstream strm( line );
1107  strm >> ( *_attribPtr )[ i ];
1108  }
1109  CallCallback();
1110  return instr;
1111  }
1112 };
1113 
1114 /** \class DistiAttributeNeverWrite
1115  * Allows for the normal template to be used to load a value but never write it out
1116  * This is used for compatability mostly.
1117  */
1118 template<class T>
1120 {
1121 public:
1122  DistiAttributeNeverWrite( CallbackMethodCallerBase* callback, const AttributeName& name, T* attribPtr )
1123  : DistiAttribute<T>( callback, name, attribPtr )
1124  {
1125  }
1126  DistiAttributeNeverWrite( CallbackMethodCallerBase* callback, const AttributeName& name, const T& initialValue )
1127  : DistiAttribute<T>( callback, name, initialValue )
1128  {
1129  }
1130 
1131  virtual bool OkToWrite() const { return false; }
1132 };
1133 
1134 /** \class DistiAttributeAlias
1135  * Give an alternate name to an existing attribute.
1136  * This is used for compatability mostly. i.e. GlsTextBox "String" as an alias of "Text".
1137  */
1139 {
1140 public:
1141  DistiAttributeAlias( CallbackMethodCallerBase* callback, const AttributeName& name, const AttributeName& originalName, DistiAttribDict* dict )
1142  : DistiAttributeBase( callback, name, false )
1143  , _originalAttribName( originalName )
1144  , _dictionary( dict )
1145  {
1146  }
1147 
1148  /** \see DistiAttributeBase */
1149  virtual DISTI_EXPORT bool OkToWrite() const DISTI_METHOD_OVERRIDE;
1150 
1151  /** \see DistiAttributeBase */
1152  virtual DISTI_EXPORT bool ValueChanged() DISTI_METHOD_OVERRIDE;
1153 
1154  /** \see DistiAttributeBase */
1155  virtual DISTI_EXPORT void ResetValueChanged() DISTI_METHOD_OVERRIDE;
1156 
1157  /** \see DistiAttributeBase */
1158  virtual DISTI_EXPORT std::string ValueString() DISTI_METHOD_OVERRIDE;
1159 
1160  /** \see DistiAttributeBase */
1161  virtual DISTI_EXPORT void ValueString( const std::string& s ) DISTI_METHOD_OVERRIDE;
1162 
1163  /** \see DistiAttributeBase */
1164  virtual DISTI_EXPORT long ValueInt() DISTI_METHOD_OVERRIDE;
1165 
1166  /** \see DistiAttributeBase */
1167  virtual DISTI_EXPORT void ValueInt( long val ) DISTI_METHOD_OVERRIDE;
1168 
1169  /** \see DistiAttributeBase */
1170  virtual DISTI_EXPORT double ValueFloat() DISTI_METHOD_OVERRIDE;
1171 
1172  /** \see DistiAttributeBase */
1173  virtual DISTI_EXPORT void ValueFloat( double val ) DISTI_METHOD_OVERRIDE;
1174 
1175  /** \see DistiAttributeBase */
1176  virtual DISTI_EXPORT std::ostream& WriteValue( std::ostream& outstr ) DISTI_METHOD_OVERRIDE;
1177 
1178  /** \see DistiAttributeBase */
1179  virtual DISTI_EXPORT std::istream& ReadValue( std::istream& instr ) DISTI_METHOD_OVERRIDE;
1180 
1181  /** \see DistiAttributeBase */
1182  virtual DISTI_EXPORT bool operator==( const DistiAttributeBase& r ) DISTI_METHOD_OVERRIDE;
1183 
1184  /** \see DistiAttributeBase */
1185  virtual DISTI_EXPORT CallbackID RegisterObserver( AttributeObserver* callback ) DISTI_METHOD_OVERRIDE;
1186  /** \see DistiAttributeBase */
1187  virtual DISTI_EXPORT void UnregisterObserver( CallbackID id ) DISTI_METHOD_OVERRIDE;
1188  /** \see DistiAttributeBase */
1189  virtual DISTI_EXPORT void NotifyObservers() DISTI_METHOD_OVERRIDE;
1190 
1191 protected:
1192  AttributeName _originalAttribName;
1193  DistiAttribDict* _dictionary;
1194 };
1195 
1196 /** \class DistiAttributeDynamicArray
1197  * An attribute for a dynamic array
1198  * T must be related to DynamicArray
1199  */
1200 template<class T, bool showIndex /* In the output */>
1202 {
1203  T* _attribPtr;
1204 
1205 public:
1206  DistiAttributeDynamicArray( CallbackMethodCallerBase* callback, const AttributeName& name, T* attribPtr )
1207  : DistiAttributeBase( callback, name, false )
1208  , _attribPtr( attribPtr )
1209  {
1210  }
1211 
1212  // Create a new DynamicArray using local storage
1214  : DistiAttributeBase( callback, name, true )
1215  , _attribPtr( new T() )
1216  {
1217  }
1218 
1220  {
1221  if( _localStorage )
1222  delete _attribPtr;
1223  _attribPtr = NULL;
1224  }
1225 
1226  bool OkToWrite() const DISTI_METHOD_OVERRIDE
1227  {
1228  return ( _attribPtr != NULL && _attribPtr->Capacity() );
1229  }
1230 
1231  std::ostream& WriteValue( std::ostream& outstr ) DISTI_METHOD_OVERRIDE
1232  {
1233  if( _attribPtr != NULL )
1234  {
1235  unsigned numEntries = _attribPtr->Count();
1236  outstr << numEntries;
1237 
1238  DistiAttribDict::SpacingInc();
1239 
1240  for( unsigned i = 0; i < numEntries; i++ )
1241  {
1242  outstr << '\n';
1243 
1244  if( showIndex )
1245  {
1246  outstr << DistiAttribDict::SpacingString() << i << " ";
1247  }
1248  outstr.width( 1 );
1249  outstr << DistiAttribDict::SpacingString() << ( *_attribPtr )[ i ] << " ";
1250  }
1251  DistiAttribDict::SpacingDec();
1252  }
1253  return outstr;
1254  }
1255 
1256  std::istream& ReadValue( std::istream& instr ) DISTI_METHOD_OVERRIDE
1257  {
1258  unsigned numEntries = 0;
1259  instr >> numEntries;
1260 
1261  _attribPtr->Count( numEntries ); // Set count of objects in
1262  for( unsigned i = 0; i < numEntries; i++ )
1263  {
1264  // We read the entry number, which may differ from the index if values are skipped.
1265  unsigned entry = i;
1266  if( showIndex )
1267  {
1268  instr >> entry;
1269  }
1270  instr >> ( *_attribPtr )[ entry ];
1271  }
1272  CallCallback();
1273  return instr;
1274  }
1275 };
1276 
1277 /** \class DistiAttributeStdVector
1278  * An attribute for a std::vector
1279  * T must be related to std::vector
1280  */
1281 template<class T, bool showIndex /* In the output */>
1283 {
1284 private:
1285  T* _attribPtr;
1286 
1288 
1289 public:
1290  DistiAttributeStdVector( CallbackMethodCallerBase* callback, const AttributeName& name, T* attribPtr )
1291  : DistiAttributeBase( callback, name, false )
1292  , _attribPtr( attribPtr )
1293  {
1294  }
1295 
1296  // Create a new std::vector
1298  : DistiAttributeBase( callback, name, true )
1299  , _attribPtr( new T() )
1300  {
1301  }
1302 
1303  virtual ~DistiAttributeStdVector()
1304  {
1305  if( _localStorage )
1306  {
1307  delete _attribPtr;
1308  }
1309  _attribPtr = NULL;
1310  }
1311 
1312  virtual bool OkToWrite() const
1313  {
1314  return ( _attribPtr != NULL && _attribPtr->size() );
1315  }
1316 
1317  virtual std::ostream& WriteValue( std::ostream& outstr )
1318  {
1319  if( _attribPtr != NULL )
1320  {
1321  const std::size_t numEntries = _attribPtr->size();
1322  outstr << numEntries;
1323 
1324  DistiAttribDict::SpacingInc();
1325 
1326  for( std::size_t i = 0; i < numEntries; i++ )
1327  {
1328  outstr << '\n';
1329 
1330  if( showIndex )
1331  {
1332  outstr << DistiAttribDict::SpacingString() << i << " ";
1333  }
1334  outstr.width( 1 );
1335  outstr << DistiAttribDict::SpacingString() << ( *_attribPtr )[ i ] << " ";
1336  }
1337  DistiAttribDict::SpacingDec();
1338  }
1339  return outstr;
1340  }
1341 
1342  virtual std::istream& ReadValue( std::istream& instr )
1343  {
1344  if( _attribPtr != NULL )
1345  {
1346  int numEntries;
1347  instr >> numEntries;
1348 
1349  _attribPtr->resize( numEntries ); // Set count of objects in
1350  int entry;
1351  for( int i = 0; i < numEntries; i++ )
1352  {
1353  entry = i;
1354  if( showIndex )
1355  {
1356  instr >> entry;
1357  }
1358  instr >> ( *_attribPtr )[ entry ];
1359  }
1360  CallCallback();
1361  }
1362 
1363  return instr;
1364  }
1365 };
1366 
1367 /** An attribute for a DynamicArray of homogeneous items
1368  * T must have ReadValue and WriteValue methods
1369  * Replacement for DistiAttributeHomogeneousAttributeArray
1370  */
1371 template<class T>
1373 {
1374 public:
1375  typedef T* ( *CreateItemCb )();
1376 
1377 protected:
1378  DynamicArray<T*>* _array;
1379  CreateItemCb _createCb;
1380 
1381 public:
1382  // Constructor requires a dynamic array of T*.
1383  DistiAttributeHomogeneousItemArray( const AttributeName& name, DynamicArray<T*>* array, CreateItemCb createCb )
1384  : DistiAttributeBase( NULL, name, false )
1385  , _array( array )
1386  , _createCb( createCb )
1387  {
1388  }
1390 
1391  virtual bool OkToWrite() const { return _array && _array->Count(); }
1392 
1393  virtual std::ostream& WriteValue( std::ostream& outstr )
1394  {
1395  outstr << "\n"
1396  << DistiAttribDict::SpacingString() << "{\n";
1397  DistiAttribDict::SpacingInc();
1398  for( unsigned int i = 0; i < _array->Count(); i++ )
1399  {
1400  if( ( *_array )[ i ] )
1401  {
1402  outstr << DistiAttribDict::SpacingString();
1403  outstr << "Item: "; // Everything in the list is called Item
1404  ( ( *_array )[ i ] )->WriteValue( outstr );
1405  outstr << "\n";
1406  }
1407  }
1408  DistiAttribDict::SpacingDec();
1409  outstr << DistiAttribDict::SpacingString() << "}\n";
1410  return outstr;
1411  }
1412  virtual std::istream& ReadValue( std::istream& instr )
1413  {
1414  // Scan through the token including the ':'
1415  std::string buf;
1416 
1417  while( DistiAttribDict::ScanToken( instr, buf ) )
1418  {
1419  if( !buf.length() )
1420  continue;
1421 
1422  if( buf == "Item" )
1423  {
1424  // Eat the space between the : and the data
1425  instr.get();
1426  // Dynamically create it, and add it to the end of the list
1427  if( T* const createdItem = dynamic_cast<T*>( _createCb() ) )
1428  {
1429  _array->PushBack( createdItem );
1430  _array->Back()->ReadValue( instr );
1431  }
1432  }
1433  }
1434  return instr;
1435  }
1436 };
1437 /** The attribute used in generated code for accessing class properties
1438  * It can have a get method, set method, and an attribute pointer, or almost
1439  * any combination of the three.
1440  * T must have a default constructor, even if it doesn't initialize.
1441  * SetArgT is the argument type for the SetMethodType.
1442  * Specify this if the argument for the Set call is not "const &T".
1443  * GetReturnT is the return type for the GetMethodType.
1444  * Specify this if the return type for the Get call is not T
1445  * The get and set methods are called when the attribute interface is used for access.
1446  * If the methods are not provided, the attribute stream operators are used instead.
1447  * If the property does not have a method or attribute pointer, it will not be able to read/write its value.
1448  */
1449 template<class containerT, class T, class SetArgT = const T&, class GetReturnT = T>
1451 {
1452 public:
1453  DISTI_DEPRECATED( "This identifier is forbidden by the C++ standard. Use BaseClass instead." )
1454  typedef DistiAttribute<T> _BaseClass;
1455  typedef DistiAttribute<T> BaseClass;
1456  typedef void ( containerT::*SetMethodType )( SetArgT );
1457  typedef GetReturnT ( containerT::*GetMethodType )();
1458  typedef GetReturnT ( containerT::*GetMethodConstType )() const;
1459 
1460  float _precision;
1461  //T* _attribPtr;
1462  containerT* _container;
1463  SetMethodType _setMethod;
1464  GetMethodType _getMethod;
1465 
1466  // NULLs are OK
1467  DistiAttributeProperty( const AttributeName& name, containerT* frame, T* attribPtr, SetMethodType setMethod, GetMethodType getMethod )
1468  : BaseClass( NULL, name, attribPtr )
1469  , _precision( 0 )
1470  , _container( frame )
1471  , _setMethod( setMethod )
1472  , _getMethod( getMethod )
1473  {
1474  // Automatically use some precision for floats
1475  if( typeid( T ) == typeid( float ) || typeid( T ) == typeid( double ) || typeid( T ) == typeid( long double ) )
1476  {
1477  _precision = 10;
1478  }
1479  }
1480 
1481  virtual bool OkToWrite() const DISTI_METHOD_OVERRIDE
1482  {
1483  return ( this->_attribPtr || _getMethod );
1484  }
1485 
1486  // The DistiAttribute<> classes override the DistiAttributeBase implementation for these methods. Here, we revert back to the DistiAttributeBase implementation
1487 
1488  virtual std::string ValueString() DISTI_METHOD_OVERRIDE { return DistiAttributeBase::ValueString(); }
1489  virtual void ValueString( const std::string& s ) DISTI_METHOD_OVERRIDE { DistiAttributeBase::ValueString( s ); }
1490 
1491  virtual long ValueInt() DISTI_METHOD_OVERRIDE { return DistiAttributeBase::ValueInt(); }
1492  virtual void ValueInt( long val ) DISTI_METHOD_OVERRIDE { DistiAttributeBase::ValueInt( val ); }
1493 
1494  virtual double ValueFloat() DISTI_METHOD_OVERRIDE { return DistiAttributeBase::ValueFloat(); }
1495  virtual void ValueFloat( double val ) DISTI_METHOD_OVERRIDE { DistiAttributeBase::ValueFloat( val ); }
1496 
1497  virtual std::ostream& WriteValue( std::ostream& outstr ) DISTI_METHOD_OVERRIDE
1498  {
1499  if( _precision > 0 )
1500  outstr.precision( int( _precision ) );
1501 
1502  if( _getMethod && _container )
1503  {
1504  // Save the current _attribPtr
1505  T* tempAttribPtr = this->_attribPtr;
1506 
1507  // Get the value from the method.
1508  T temp( ( _container->*_getMethod )() );
1509 
1510  // Temporarily change the _attribPtr
1511  this->_attribPtr = &temp;
1512 
1513  // Call the base class to format the _attribPtr
1514  BaseClass::WriteValue( outstr );
1515 
1516  // Put the _attribPtr back to where it belongs
1517  this->_attribPtr = tempAttribPtr;
1518  }
1519  else if( this->_attribPtr )
1520  {
1521  BaseClass::WriteValue( outstr );
1522  }
1523 
1524  return outstr;
1525  }
1526 
1527  virtual std::istream& ReadValue( std::istream& instr ) DISTI_METHOD_OVERRIDE
1528  {
1529  if( _setMethod && _container )
1530  {
1531  // Save the current _attribPtr
1532  T* tempAttribPtr = this->_attribPtr;
1533  T temp;
1534 
1535  // Set _attribPtr to the temp variable;
1536  this->_attribPtr = &temp;
1537 
1538  // Call the base class to format the input
1539  BaseClass::ReadValue( instr );
1540 
1541  // Call the method
1542  ( _container->*_setMethod )( temp );
1543 
1544  this->_attribPtr = tempAttribPtr;
1545  }
1546  else if( this->_attribPtr )
1547  {
1548  BaseClass::ReadValue( instr );
1549  }
1550 
1551  return instr;
1552  }
1553 
1554  virtual T Value() DISTI_METHOD_OVERRIDE
1555  {
1556  if( _getMethod && _container )
1557  {
1558  // Get the value from the method
1559  return ( _container->*_getMethod )();
1560  }
1561  else if( this->_attribPtr )
1562  {
1563  return BaseClass::Value();
1564  }
1565  else
1566  {
1567  return T();
1568  }
1569  }
1570 
1571  virtual void Value( const T& val ) DISTI_METHOD_OVERRIDE // this has to match the base class's prototype so we override it, ie can't use SetArgT here
1572  {
1573  if( _setMethod && _container )
1574  {
1575  ( _container->*_setMethod )( val );
1576  }
1577  else if( this->_attribPtr )
1578  {
1579  BaseClass::Value( val );
1580  }
1581  }
1582 };
1583 
1584 /** Overloaded helper function to create a DistiAttributeProperty where the setter param is of type Type and the getter is non-const. (See other varians below.)
1585  * \tparam Type The type of the property (int, float, GlsColor, etc.)
1586  * \tparam Class The class of the object that owns this parameter (typically a subclass of DisplayObject)
1587  * \param attrName The attribute name for this property.
1588  * \param obj The display object instance associated with this property.
1589  * \param setMethod The setter method for the property (can be NULL)
1590  * \param getMethod The getter method for the property (can be NULL)
1591  * \return The DistiAttributeProperty instance, which is owned by the caller.
1592  * \code
1593  * Attributes().Add( CreateDistiAttributeProperty<int>( MetaTextureIndex, this, &DisplayObject::TextureIndex, &DisplayObject::TextureIndex ) );
1594  * \endcode
1595  */
1596 template<typename Type, class Class>
1598  const AttributeName& attrName,
1599  Class* const obj,
1601  const typename DistiAttributeProperty<Class, Type, Type>::GetMethodType getMethod = NULL )
1602 {
1603  return new DistiAttributeProperty<Class, Type, Type>( attrName, obj, NULL, setMethod, getMethod );
1604 }
1605 
1606 /** Overloaded helper function to create a DistiAttributeProperty where the getter is const. */
1607 template<typename Type, class Class>
1609  const AttributeName& attrName,
1610  Class* const obj,
1613 {
1614  return new DistiAttributeProperty<Class, Type, Type>( attrName, obj, NULL, setMethod,
1615  reinterpret_cast<typename DistiAttributeProperty<Class, Type>::GetMethodType>( getMethod ) );
1616 }
1617 
1618 /** Overloaded helper function to create a DistiAttributeProperty where there is no setter method and the getter is const. */
1619 template<typename Type, class Class>
1621  const AttributeName& attrName,
1622  Class* const obj,
1624 {
1625  return new DistiAttributeProperty<Class, Type>( attrName, obj, NULL, NULL,
1626  reinterpret_cast<typename DistiAttributeProperty<Class, Type>::GetMethodType>( getMethod ) );
1627 }
1628 
1629 /** Overloaded helper function to create a DistiAttributeProperty where there is no setter method and the getter is non-const. */
1630 template<typename Type, class Class>
1632  const AttributeName& attrName,
1633  Class* const obj,
1634  const typename DistiAttributeProperty<Class, Type>::GetMethodType getMethod )
1635 {
1636  return new DistiAttributeProperty<Class, Type>( attrName, obj, NULL, NULL, getMethod );
1637 }
1638 
1639 /** Overloaded helper function to create a DistiAttributeProperty where the setter param is of type const Type& and the getter is non-const. */
1640 template<typename Type, class Class>
1642  const AttributeName& attrName,
1643  Class* const obj,
1645  const typename DistiAttributeProperty<Class, Type, const Type&>::GetMethodType getMethod = NULL )
1646 {
1647  return new DistiAttributeProperty<Class, Type, const Type&>( attrName, obj, NULL, setMethod, getMethod );
1648 }
1649 
1650 /** Overloaded helper function to create a DistiAttributeProperty where the setter param is of type const Type& and the getter is const. */
1651 template<typename Type, class Class>
1653  const AttributeName& attrName,
1654  Class* const obj,
1657 {
1658  return new DistiAttributeProperty<Class, Type, const Type&>( attrName, obj, NULL, setMethod,
1659  reinterpret_cast<typename DistiAttributeProperty<Class, Type, const Type&>::GetMethodType>( getMethod ) );
1660 }
1661 
1662 /** Overloaded helper function to create a DistiAttributeProperty where the getter and setter are different base types (e.g. int vs bool) */
1663 template<typename GetReturnT, typename SetArgT, class Class>
1665  const AttributeName& attrName,
1666  Class* const obj,
1669 {
1670  return new DistiAttributeProperty<Class, GetReturnT, SetArgT>( attrName, obj, NULL, setMethod, getMethod );
1671 }
1672 
1673 /** Overloaded helper function for properties that formerly used DistiAttributeLocation, which wraps properties that are stored in c++ as a Vertex but used in the Resources as a Vector */
1674 template<class Class>
1676  const AttributeName& attrName,
1677  Class* const obj,
1680 {
1681  return new DistiAttributeProperty<Class, Vector, const Vertex&, const Vertex&>( attrName, obj, NULL, setMethod,
1683 }
1684 
1685 /** An empty attribute used where a reference to an attribute
1686  * must be returned, but needs to be blank
1687  */
1689 {
1690 public:
1692  : DistiAttributeBase( NULL, AttributeName( "EmptyAttribute" ), false )
1693  {
1694  }
1695 
1696  /** Write nothing */
1697  virtual std::ostream& WriteValue( std::ostream& outstr )
1698  {
1699  return outstr;
1700  }
1701  /** Read nothing */
1702  virtual std::istream& ReadValue( std::istream& instr )
1703  {
1704  return instr;
1705  }
1706 };
1707 
1708 /** \class DistiAttributeEnumDirect
1709  * A Disti Attribute which reads and writes enumerations directly, bypassing method calls.
1710  */
1711 template<class enumType>
1713 {
1714 protected:
1715  enumType* _attribPtr;
1716 
1717 public:
1718  DistiAttributeEnumDefList* _pairList;
1719 
1720  DistiAttributeEnumDirect( CallbackMethodCallerBase* callback, const AttributeName& name, enumType* attribPtr, DistiAttributeEnumDefList* pairList )
1721  : DistiAttributeBase( callback, name, false )
1722  , _attribPtr( attribPtr )
1723  , _pairList( pairList )
1724  {
1725  }
1726  DistiAttributeEnumDirect( CallbackMethodCallerBase* callback, const AttributeName& name, const enumType& value, DistiAttributeEnumDefList* pairList )
1727  : DistiAttributeBase( callback, name, true )
1728  , _attribPtr( new enumType( value ) )
1729  , _pairList( pairList )
1730  {
1731  }
1732 
1733  virtual ~DistiAttributeEnumDirect()
1734  {
1735  if( _localStorage && _attribPtr )
1736  delete _attribPtr;
1737  //delete _pairList; // This must point to persistant
1738  }
1739 
1740  virtual long ValueInt() { return (long)*_attribPtr; };
1741  virtual void ValueInt( long val ) { *_attribPtr = (enumType)val; };
1742 
1744  {
1745  DistiAttributeEnumDirect* ptr = dynamic_cast<DistiAttributeEnumDirect*>( const_cast<DistiAttributeBase*>( &oldClass ) );
1746  if( ptr )
1747  {
1748  *_attribPtr = ( enumType ) * ( ptr->_attribPtr );
1749  CallCallback();
1750  }
1751  else
1752  {
1753  return DistiAttributeBase::operator=( oldClass );
1754  }
1755  return *this;
1756  }
1757  virtual std::ostream& WriteValue( std::ostream& outstr )
1758  {
1759  bool foundIt = false;
1760 #ifndef __VXWORKS__
1761  typename DistiAttributeEnumDefList::iterator item = _pairList->begin();
1762  while( item != _pairList->end() )
1763  {
1764  if( ( *item )->_enum == *_attribPtr )
1765  {
1766  outstr << ( *item )->_string;
1767  foundIt = true;
1768  break;
1769  }
1770  ++item;
1771  }
1772  if( !foundIt )
1773  {
1774  //Didn't find it so just write the number
1775  outstr << (int)*_attribPtr;
1776  }
1777 #endif
1778 
1779  return outstr;
1780  }
1781  virtual std::istream& ReadValue( std::istream& instr )
1782  {
1783 #ifndef __VXWORKS__
1784  char value[ 64 ];
1785  instr >> value;
1786 
1787  bool foundIt = false;
1788  typename DistiAttributeEnumDefList::iterator item = _pairList->begin();
1789 
1790  // First look by enumeration
1791  while( item != _pairList->end() )
1792  {
1793  if( strcmp( ( *item )->_string, value ) == 0 )
1794  {
1795  *_attribPtr = ( enumType )( *item )->_enum;
1796  CallCallback();
1797 
1798  foundIt = true;
1799  break;
1800  }
1801  ++item;
1802  }
1803 
1804  // If not found, assume that the numerical value is specified.
1805  if( !foundIt )
1806  {
1807  *_attribPtr = (enumType)atoi( value );
1808  CallCallback();
1809  }
1810 #endif
1811 
1812  return instr;
1813  }
1814 };
1815 
1816 ////////////////////////////////////////////////////////////////////////////////
1817 /// A macro for boilerplate code to setup a DisplayObject callback.
1818 /// \param instance The DisplayObject instance.
1819 /// \param Class The current class name, derived from DisplayObject.
1820 /// \param Method The class's method name for the callback.
1821 /// \code{.cpp}
1822 /// // Given a class ScrollList that inherits from DisplayObject...
1823 /// ScrollList::ScrollList()
1824 /// {
1825 /// DISTI_REGISTER_METHOD_CALLBACK( this, &ScrollList::EventCallback );
1826 /// }
1827 ///
1828 /// int ScrollList::EventCallback( Group* self, DisplayEvent* ev )
1829 /// {
1830 /// // ... event handler code ...
1831 /// }
1832 /// \endcode
1833 ////////////////////////////////////////////////////////////////////////////////
1834 #define DISTI_REGISTER_METHOD_CALLBACK( instance, Class, Method ) \
1835  { \
1836  typedef CallbackMethodCallerTemplate<Class, Class> Caller; \
1837  typedef typename Caller::MethodType1 MethodType; \
1838  const MethodType callback = reinterpret_cast<MethodType>( Method ); \
1839  ThisClass::CallbackCaller( new Caller( callback, instance ) ); \
1840  }
1841 
1842 ////////////////////////////////////////////////////////////////////////////////
1843 /// A macro for boilerplate code to setup a DisplayObject method caller for
1844 /// MethodType 1.
1845 /// \param object The DisplayObject instance.
1846 /// \param method The method that should be called.
1847 /// \param parent The parent to the object
1848 ////////////////////////////////////////////////////////////////////////////////
1849 #define DISTI_SET_OBJECT_CALLBACK1( object, method, parent ) \
1850  ( object )->CallbackCaller( \
1851  new CallbackMethodCallerTemplate<DisplayObject, DisplayObject>( \
1852  ( disti::CallbackMethodCallerTemplate<DisplayObject, DisplayObject>::MethodType1 )( method ), ( parent ) ) );
1853 
1854 ////////////////////////////////////////////////////////////////////////////////
1855 /// A macro for boilerplate code to setup a DisplayObject attribute.
1856 /// \param Type The type of the attribute.
1857 /// \param name The unique string name identifying the attribute.
1858 /// \param memberVarAddr A pointer to the member variable of type \a Type.
1859 /// Can be NULL if no member variable is desired.
1860 /// \sa DISTI_ADD_ATTRIBUTE_CALLBACK
1861 /// \sa DISTI_ADD_ATTRIBUTE_SET_GET
1862 ////////////////////////////////////////////////////////////////////////////////
1863 #define DISTI_ADD_ATTRIBUTE( Type, name, memberVarAddr ) \
1864  { \
1865  static const AttributeName attr( name ); \
1866  CallbackAttributeNotifier<ThisClass> cb( this, attr ); \
1867  this->Attributes().Add( new DistiAttribute<Type>( &cb, ( attr ), ( memberVarAddr ) ) ); \
1868  }
1869 
1870 ////////////////////////////////////////////////////////////////////////////////
1871 /// A macro for boilerplate code to setup a DisplayObject attribute that has a
1872 /// callback function.
1873 /// \param Type The type of the attribute.
1874 /// \param name The unique string name identifying the attribute.
1875 /// \param memberVarAddr A pointer to the member variable of type \a Type.
1876 /// Can be NULL if no member variable is desired.
1877 /// \param callbackFunction A member function pointer to the function called when this
1878 /// attribute is changed.
1879 /// \sa DISTI_ADD_ATTRIBUTE
1880 /// \sa DISTI_ADD_ATTRIBUTE_SET_GET
1881 ////////////////////////////////////////////////////////////////////////////////
1882 #define DISTI_ADD_ATTRIBUTE_CALLBACK( Type, name, memberVarAddr, callbackFunction ) \
1883  { \
1884  typedef void ( ThisClass::*Method )(); /* Member function pointer */ \
1885  static const AttributeName attr( name ); \
1886  CallbackAttributeNotifier<ThisClass> cb( this, attr, reinterpret_cast<Method>( callbackFunction ) ); \
1887  this->Attributes().Add( new DistiAttribute<Type>( &cb, ( attr ), ( memberVarAddr ) ) ); \
1888  }
1889 
1890 ////////////////////////////////////////////////////////////////////////////////
1891 /// A macro for boilerplate code to setup a DisplayObject attribute that has a
1892 /// setter and a getter function.
1893 /// \param Type The type of the attribute.
1894 /// \param name The unique string name identifying the attribute.
1895 /// \param setter A member function pointer to the setter function (can be NULL)
1896 /// \param getter A member function pointer to the getter function (can be NULL)
1897 /// \sa DISTI_ADD_ATTRIBUTE
1898 /// \sa DISTI_ADD_ATTRIBUTE_CALLBACK
1899 ////////////////////////////////////////////////////////////////////////////////
1900 #define DISTI_ADD_ATTRIBUTE_SET_GET( Type, name, setter, getter ) \
1901  { \
1902  static const AttributeName attr( name ); \
1903  this->Attributes().Add( CreateDistiAttributeProperty<Type>( attr, this, setter, getter ) ); \
1904  }
1905 
1906 ////////////////////////////////////////////////////////////////////////////////
1907 /// A macro for boilerplate code to setup a string as a DisplayObject attribute.
1908 /// \param name The unique string name identifying the attribute.
1909 /// \param memberVarAddr A pointer to the member variable of type std::string.
1910 /// Can be NULL if no member variable is desired.
1911 /// \sa DISTI_ADD_ATTRIBUTE_STRING_CALLBACK
1912 ////////////////////////////////////////////////////////////////////////////////
1913 #define DISTI_ADD_ATTRIBUTE_STRING( name, memberVarAddr ) \
1914  { \
1915  static const AttributeName attr( name ); \
1916  CallbackAttributeNotifier<ThisClass> cb( this, attr ); \
1917  this->Attributes().Add( new DistiAttributeEncodedStdString( &cb, attr, memberVarAddr ) ); \
1918  }
1919 
1920 ////////////////////////////////////////////////////////////////////////////////
1921 /// A macro for boilerplate code to setup a string as a DisplayObject attribute
1922 /// with a callback
1923 /// \param name The unique string name identifying the attribute.
1924 /// \param memberVarAddr A pointer to the member variable of type std::string.
1925 /// Can be NULL if no member variable is desired.
1926 /// \param callbackFunction The function that gets called when the attribute changes.
1927 /// \sa DISTI_ADD_ATTRIBUTE_STRING
1928 ////////////////////////////////////////////////////////////////////////////////
1929 #define DISTI_ADD_ATTRIBUTE_STRING_CALLBACK( name, memberVarAddr, callbackFunction ) \
1930  { \
1931  typedef void ( ThisClass::*Method )(); /* Member function pointer */ \
1932  static const AttributeName attr( name ); \
1933  CallbackAttributeNotifier<ThisClass> cb( this, attr, reinterpret_cast<Method>( callbackFunction ) ); \
1934  this->Attributes().Add( new DistiAttributeEncodedStdString( &cb, attr, memberVarAddr ) ); \
1935  }
1936 
1937 ////////////////////////////////////////////////////////////////////////////////
1938 /// A macro for boilerplate code to setup an alias to an existing DisplayObject attribute.
1939 /// \param name The unique string name identifying the attribute.
1940 /// \param origName The unique string idenfifying the attribute to create the alias from.
1941 /// \param obj The object containing the origName attribute.
1942 /// \sa DISTI_ADD_ATTRIBUTE
1943 ////////////////////////////////////////////////////////////////////////////////
1944 #define DISTI_ADD_ATTRIBUTE_ALIAS( aliasName, origName, obj ) \
1945  { \
1946  static const AttributeName aliasAttr( aliasName ); \
1947  static const AttributeName origAttr( origName ); \
1948  DistiAttribDict& attributes = ( obj )->Attributes(); \
1949  this->Attributes().Add( new DistiAttributeAlias( NULL, aliasAttr, origAttr, &attributes ) ); \
1950  }
1951 
1952 #ifdef DISTI_HAS_CPP11
1953 
1955 {
1956 public:
1957  AttributeFnCallback( WeakReferenceable* object, std::function<void()> func )
1958  : _func( std::move( func ) )
1959  , _object( object )
1960  {
1961  GLS_VERIFY( NULL != object );
1962  }
1963 
1965  {
1966  if( IsValid() )
1967  {
1968  _func();
1969  }
1970  }
1971 
1972  virtual bool IsValid() const
1973  {
1974  return !_object.IsNull() && _func;
1975  }
1976 
1977 protected:
1978  std::function<void()> _func;
1980 };
1981 
1982 inline AttributeObserver* CreateAttributeFnCallback(
1983  WeakReferenceable* const obj,
1984  const std::function<void()>& func )
1985 {
1986  return new AttributeFnCallback( obj, func );
1987 }
1988 
1989 
1990 inline DistiAttributeBase::CallbackID Connect( DisplayObject* obj, const std::string& resource, WeakReferenceable* funcOwner, std::function<void()> func )
1991 {
1992  auto& res = obj->Resource( resource.c_str() );
1993  if( dynamic_cast<disti::DistiEmptyAttribute*>( &res ) )
1994  {
1995  std::cout << "Unknown attribute name: " << resource << std::endl;
1996  return DISTI_INVALID_CALLBACK_ID;
1997  }
1998 
1999  return res.RegisterObserver( CreateAttributeFnCallback( funcOwner, std::move( func ) ) );
2000 }
2001 #endif
2002 
2003 template<class Class>
2004 DistiAttributeBase::CallbackID Connect( DisplayObject* obj, const std::string& resource, Class* const methodInstance, const typename AttributeMethodCallback<Class>::Callback method )
2005 {
2006  DistiAttributeBase& res = obj->Resource( resource.c_str() );
2007  if( dynamic_cast<disti::DistiEmptyAttribute*>( &res ) )
2008  {
2009  std::cout << "Unknown attribute name: " << resource << std::endl;
2010  return DISTI_INVALID_CALLBACK_ID;
2011  }
2012  return res.RegisterObserver( CreateAttributeMethodCallback( methodInstance, method ) );
2013 }
2014 
2015 inline void Disconnect( DisplayObject* obj, const std::string& resource, DistiAttributeBase::CallbackID id )
2016 {
2017  DistiAttributeBase& res = obj->Resource( resource.c_str() );
2018  if( !dynamic_cast<disti::DistiEmptyAttribute*>( &res ) && id != DISTI_INVALID_CALLBACK_ID )
2019  {
2020  res.UnregisterObserver( id );
2021  }
2022 }
2023 
2024 } // namespace disti
2025 
2026 #endif
Definition: display_types.h:75
Definition: gls_metadata_attributes.h:249
Definition: gls_metadata_attributes.h:608
Definition: gls_metadata_attributes.h:266
Definition: display_types.h:100
virtual void ValueString(const std::string &s) override
Definition: gls_metadata_attributes.h:1489
virtual std::ostream & WriteValue(std::ostream &outstr)
Definition: gls_metadata_attributes.h:1393
Definition: display_types.h:73
Definition: gls_metadata_attributes.h:1688
std::ostream & WriteValue(std::ostream &outstr) override
Definition: gls_metadata_attributes.h:1231
virtual std::ostream & WriteValue(std::ostream &outstr)
Definition: gls_metadata_attributes.h:821
virtual std::ostream & WriteValue(std::ostream &outstr)
Definition: gls_metadata_attributes.h:1077
Definition: vertex.h:409
The disti metadata.
The disti::Material class.
#define DISTI_DEPRECATED(msg)
Defines whether this compiler supports the C++14 deprecated attribute.
Definition: gls_cpp_lang_support.h:436
Definition: gls_metadata_attributes.h:586
virtual std::istream & ReadValue(std::istream &instr)
Definition: gls_metadata_attributes.h:841
Definition: gls_metadata_attributes.h:291
virtual std::ostream & WriteValue(std::ostream &outstr)
Definition: gls_metadata_attributes.h:966
unsigned Count() const
Definition: dynamic_array.h:204
virtual std::istream & ReadValue(std::istream &instr)
Definition: gls_metadata_attributes.h:1089
Definition: gls_metadata_attributes.h:1954
The disti::DynamicArray class. A templated array of objects capable of dynamically growing...
Definition: gls_metadata_attributes.h:1282
Definition: gls_metadata_attributes.h:232
Definition: gls_metadata_attributes.h:486
Definition: gls_metadata_attributes.h:402
std::istream & ReadValue(std::istream &instr) override
Definition: disti_metadata.h:588
Definition: display_types.h:153
Definition: gls_metadata_attributes.h:533
Definition: gls_metadata_attributes.h:658
virtual long ValueInt()
Definition: gls_metadata_attributes.h:1740
Definition: display_types.h:151
Definition: display_types.h:91
virtual bool OkToWrite() const
Definition: gls_metadata_attributes.h:684
virtual double ValueFloat() override
Definition: gls_metadata_attributes.h:1494
Definition: display_types.h:103
virtual void ValueFloat(double val) override
Definition: gls_metadata_attributes.h:1495
Definition: gls_metadata_attributes.h:1712
Definition: display_types.h:92
virtual bool operator==(const DistiAttributeBase &rArg)
Definition: gls_metadata_attributes.h:1040
std::ostream & WriteValue(std::ostream &outstr) override
Definition: disti_metadata.h:574
Definition: gls_metadata_attributes.h:1068
virtual std::ostream & WriteValue(std::ostream &outstr)
Definition: gls_metadata_attributes.h:691
virtual std::istream & ReadValue(std::istream &instr)
Definition: gls_metadata_attributes.h:1342
Definition: display_types.h:102
Definition: display_types.h:110
A file for all GL Studio files to include.
virtual std::string ValueString() override
Definition: gls_metadata_attributes.h:1488
Definition: display_types.h:63
Definition: display_types.h:116
The disti::DisplayObject class and global enumerations.
Definition: gls_metadata_attributes.h:921
unsigned int CallbackID
Type for unique identifiers.
Definition: disti_metadata.h:345
Definition: display_types.h:90
Definition: gls_metadata_attributes.h:1201
Definition: gls_metadata_attributes.h:1372
virtual std::istream & ReadValue(std::istream &instr)
Definition: gls_metadata_attributes.h:1412
Definition: gls_metadata_attributes.h:321
virtual bool OkToWrite() const
Definition: gls_metadata_attributes.h:448
Definition: weak_reference.h:64
Definition: gls_metadata_attributes.h:1138
Definition: display_types.h:101
Definition: disti_metadata.h:894
bool OkToWrite() const override
Definition: gls_metadata_attributes.h:1226
Definition: display_types.h:123
virtual void ValueInt(long val)
Definition: gls_metadata_attributes.h:1741
The List_c class. Generic linked list.
virtual std::ostream & WriteValue(std::ostream &outstr)
Definition: gls_metadata_attributes.h:1697
bool operator==(const AttributeName &attr1, const AttributeName &attr2)
Definition: disti_metadata.h:144
virtual void Value(const T &val) override
Definition: gls_metadata_attributes.h:1571
Definition: display_types.h:152
Definition: display_types.h:64
Definition: display_types.h:62
Definition: gls_metadata_attributes.h:1119
Definition: disti_metadata.h:491
The disti::Vertex class. A class for manipulating 3D vertices.
Generally useful defines, macros, enumerations and function prototypes.
void Call(DistiAttributeBase &ev)
Definition: gls_metadata_attributes.h:1964
#define GLS_VERIFY(exp)
Definition: disti_assert.h:155
Definition: gls_metadata_attributes.h:1450
Definition: gls_metadata_attributes.h:453
virtual std::ostream & WriteValue(std::ostream &outstr)
Definition: gls_metadata_attributes.h:1757
Definition: disti_metadata.h:186
virtual std::istream & ReadValue(std::istream &instr)
Definition: gls_metadata_attributes.h:986
Definition: disti_metadata.h:169
Definition: display_types.h:61
Definition: gls_metadata_attributes.h:506
virtual long ValueInt() override
Definition: gls_metadata_attributes.h:1491
Definition: disti_metadata.h:668
DistiAttributeProperty< Class, GetReturnT, SetArgT > * CreateDistiAttributeProperty(const AttributeName &attrName, Class *const obj, const typename DistiAttributeProperty< Class, GetReturnT, SetArgT >::SetMethodType setMethod, const typename DistiAttributeProperty< Class, GetReturnT, SetArgT >::GetMethodType getMethod)
Definition: gls_metadata_attributes.h:1664
Definition: disti_metadata.h:882
Definition: callback_caller_base.h:55
DistiAttributeProperty< Class, Vector, const Vertex &, const Vertex & > * CreateDistiAttributePropertyVertexToVector(const AttributeName &attrName, Class *const obj, const typename DistiAttributeProperty< Class, Vector, const Vertex &, const Vertex & >::SetMethodType setMethod, const typename DistiAttributeProperty< Class, Vector, const Vertex &, const Vertex & >::GetMethodConstType getMethod)
Definition: gls_metadata_attributes.h:1675
Definition: weak_reference.h:91
std::istream & ReadValue(std::istream &instr) override
Definition: gls_metadata_attributes.h:1256
virtual bool OkToWrite() const
Definition: gls_metadata_attributes.h:1391
T & Back()
Definition: dynamic_array.h:342
virtual std::istream & ReadValue(std::istream &instr)
Definition: gls_metadata_attributes.h:1702
Definition: display_types.h:94
bool Equal(T1 x, T2 y, float precision=0.001f)
Definition: util.h:246
Definition: display_types.h:71
Definition: display_types.h:150
AttributeObserver * CreateAttributeMethodCallback(Class *const obj, const typename AttributeMethodCallback< Class >::Callback method)
Definition: disti_metadata.h:403
virtual std::ostream & WriteValue(std::ostream &outstr) override
Definition: gls_metadata_attributes.h:1497
Definition: gls_metadata_attributes.h:619
AttributeName _name
Definition: disti_metadata.h:193
void Add(DistiAttributeBase *attr)
virtual bool OkToWrite() const
Definition: gls_metadata_attributes.h:961
Definition: display_types.h:117
Definition: vertex.h:84
virtual void ValueInt(long val) override
Definition: gls_metadata_attributes.h:1492
virtual bool IsValid() const
Definition: gls_metadata_attributes.h:1972
virtual std::istream & ReadValue(std::istream &instr)
Definition: gls_metadata_attributes.h:717
virtual std::ostream & WriteValue(std::ostream &outstr)
Definition: gls_metadata_attributes.h:1317
Definition: display_types.h:93
Definition: gls_metadata_attributes.h:572
Definition: gls_metadata_attributes.h:776
Definition: display_types.h:74
virtual DistiAttributeBase & operator=(const DistiAttributeBase &oldClass)
Definition: gls_metadata_attributes.h:1743
Definition: display_types.h:70
unsigned PushBack(const T &object)
Definition: dynamic_array.h:325
Definition: display_types.h:72
virtual bool OkToWrite() const
Definition: gls_metadata_attributes.h:1131
virtual std::istream & ReadValue(std::istream &instr)
Definition: gls_metadata_attributes.h:1781
Definition: gls_metadata_attributes.h:635
Definition: gls_metadata_attributes.h:422
Definition: gls_metadata_attributes.h:553
Definition: display_types.h:154
Definition: gls_metadata_attributes.h:350
Definition: disti_metadata.h:85
Definition: display_types.h:125
Definition: display_types.h:124
Definition: gls_metadata_attributes.h:376
Definition: bmpimage.h:46
long ValueInt() override
Definition: disti_metadata.h:534
Definition: display_types.h:149
virtual bool OkToWrite() const override
Definition: gls_metadata_attributes.h:1481
virtual std::istream & ReadValue(std::istream &instr) override
Definition: gls_metadata_attributes.h:1527
virtual bool OkToWrite() const
Definition: gls_metadata_attributes.h:1312
virtual bool operator==(const DistiAttributeBase &rArg)
Definition: gls_metadata_attributes.h:894
Definition: display_types.h:109
virtual bool OkToWrite() const
Definition: gls_metadata_attributes.h:816
virtual T Value() override
Definition: gls_metadata_attributes.h:1554