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