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