GL Studio API
disti_metadata.h
Go to the documentation of this file.
1 
2 /*! \file
3  \brief The disti metadata.
4 
5  \par Copyright Information
6 
7  Copyright (c) 2015 by The DiSTI Corporation.<br>
8  11301 Corporate Blvd; Suite 100<br>
9  Orlando, Florida 32817<br>
10  USA<br>
11  <br>
12  All rights reserved.<br>
13 
14  This Software contains proprietary trade secrets of DiSTI and may not be
15 reproduced, in whole or part, in any form, or by any means of electronic,
16 mechanical, or otherwise, without the written permission of DiSTI. Said
17 permission may be derived through the purchase of applicable DiSTI product
18 licenses which detail the distribution rights of this content and any
19 Derivative Works based on this or other copyrighted DiSTI Software.
20 
21  NO WARRANTY. THE SOFTWARE IS PROVIDED "AS-IS," WITHOUT WARRANTY OF ANY KIND,
22 AND ANY USE OF THIS SOFTWARE PRODUCT IS AT YOUR OWN RISK. TO THE MAXIMUM EXTENT
23 PERMITTED BY APPLICABLE LAW, DISTI AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES
24 AND CONDITIONS, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
25 IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY AND/OR FITNESS FOR A
26 PARTICULAR PURPOSE, TITLE, AND NON-INFRINGEMENT, WITH REGARD TO THE SOFTWARE.
27 
28  LIMITATION OF LIABILITY. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW,
29 IN NO EVENT SHALL DISTI OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
30 INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION,
31 DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
32 INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR
33 INABILITY TO USE THE SOFTWARE, EVEN IF DISTI HAS BEEN ADVISED OF THE POSSIBILITY
34 OF SUCH DAMAGES. DISTI'S ENTIRE LIABILITY AND YOUR EXCLUSIVE REMEDY SHALL NOT
35 EXCEED FIVE DOLLARS (US$5.00).
36 
37  The aforementioned terms and restrictions are governed by the laws of the
38 State of Florida and the United States of America.
39 
40 */
41 
42 #ifndef DISTI_METADATA_H
43 #define DISTI_METADATA_H
44 
45 #if defined(WIN32)
46 #pragma warning( push )
47 #pragma warning (disable:4786)
48 #pragma warning (disable:4251) // This may hide non-exported code.
49 #endif
50 
51 #include <iostream>
52 #include <list>
53 #include <map>
54 #include <sstream>
55 #include <vector>
56 
57 #include <stdarg.h>
58 
59 #include "disti_include.h"
60 #include "dynamic_array.h"
61 #include "scoped_ptr.h"
62 #include "tlist.h"
63 #include "unhide_globals.h"
64 #include "weak_reference.h"
66 
67 #if defined(LINUX)
68 #include <typeinfo>
69 #include <stdlib.h>
70 #endif
71 
72 
73 namespace disti
74 {
75 class CallbackMethodCallerBase;
76 class Mutex;
77 const int MAX_ATTRIBUTE_NAME_LENGTH = 128;
78 /** AttributeName class can be treated like a std::string in some instances
79  * It creates static storage for any referenced name.
80  * This results in only one copy for each name which saves memory
81  * Very fast comparison between references to names
82  */
84 {
85 private:
86  /** Defines the Singleton static storage class */
87  class StaticNameStorage
88  {
89  public:
90  /** Returns or creates and returns the instance of the class */
91  static DISTI_EXPORT StaticNameStorage* Instance();
92 
93  /** Returns the access mutex used for accessing the StaticNameStorage::Instance */
94  static DISTI_EXPORT disti::Mutex* AccessMutex();
95 
96  /** Allows the index to be looked up from the name */
97  std::map<std::string,int> _nameMap;
98 
99  /** Allows the name to be looked up directly from the index */
100  std::vector<std::string> _nameVector;
101  };
102  long _stringIndex;
103 
104  /** Attempts to find the specified name.
105  * If found _stringIndex is set to its index
106  * otherwise a new one is created and its index is saved */
107  DISTI_EXPORT void Initialize(const char *name);
108 
109 public:
110 
111  /** Constructor
112  * Explicit because construction of an AttributeName is an
113  * expensive operation. If possible you should use a static
114  * AttrbuteName object rather than constructing a new
115  * one each time it is needed.
116  * \param name the desired Name */
117  explicit DISTI_EXPORT AttributeName(const std::string &name);
118 
119  /** Constructor
120  * See comments on AttributeName(const std::string &name)
121  * \param name the desired Name */
122  explicit DISTI_EXPORT AttributeName(const char *name);
123 
124  /** Constructor
125  * \param stringIndex The index into the string map.
126  */
127  explicit DISTI_EXPORT AttributeName(long stringIndex);
128 
129  /** Returns the index to the string associate with this instance */
130  DISTI_EXPORT long StringIndex() const;
131 
132  /** Compares this string to the specified AttributeName.
133  * This compare is very fast compared to doing string compares, and is
134  * one of the primary reasons for creating this class */
135  bool DISTI_EXPORT operator == (const AttributeName & other) const;
136 
137  /** Compares this string for inequality to the specified AttributeName.
138  * This compare is very fast compared to doing string compares, and is
139  * one of the primary reasons for creating this class */
140  bool DISTI_EXPORT operator != (const AttributeName & other) const;
141 
142  /** Defines the cast operator to make this look like a std::string for reading */
143  DISTI_EXPORT operator std::string() const;
144 
145  /** More pretending to be a std::string.
146  * Returns a C string pointer to the actual name*/
147 //REMOVED because not thread safe const DISTI_EXPORT char* c_str() const;
148 
149  /** Defines the stream out operator */
150  friend DISTI_EXPORT std::ostream & operator<<(std::ostream & outstr, const AttributeName & name);
151 
152  /** Defines various == operators which makes the users syntax easier */
153  friend DISTI_EXPORT bool operator==(const AttributeName & lName, const char* rName);
154  friend DISTI_EXPORT bool operator==(const char* lName, const AttributeName & rName);
155  friend DISTI_EXPORT bool operator==(const std::string& lName, const AttributeName & rName);
156  friend DISTI_EXPORT bool operator==(const AttributeName & lName, const std::string& rName);
157 };
158 
159 class DistiAttributeBase;
160 
161 /** Class used to call a callback method that takes a DistiAttributeBase */
163 {
164 public:
165  /** call the callback with the provided display event */
166  virtual void Call( DistiAttributeBase& attr ) = 0;
167 
168  /** When IsValid is false, then this AttributeObserver can be deleted. */
169  virtual bool IsValid() const = 0;
170 
171  virtual ~AttributeObserver() {}
172 };
173 
174 class DistiAttributeObserverList;
175 
176 /** \class DistiAttributeBase
177  * This is the base class for all Disti Attributes.
178  */
180 {
181 private:
182  DistiAttributeBase( const DistiAttributeBase& other );
183 public:
184  /** The name of this attribute */
186  /** The callback which is called when the value of this object changes */
188 
190 
191  /** _localStorage is true if this attributes data should be copied.
192  * It would typically be set false if the data is stored externally,
193  * and there is no need to copy the data through metadata.
194  * It is also used to determine if storage should be deleted.*/
196 public:
197 
198  /** Constructor
199  * \param callback The method to call when the value changes. A duplicate of the
200  CallbackMethodCallerBase is created and stored internally.
201  * \param name The name of the attribute
202  * \param localStorage True if this DistiAttribute contains actual storage,
203  rather than just a pointer to somebody elses storage*/
204  DISTI_EXPORT DistiAttributeBase(CallbackMethodCallerBase* callback, const AttributeName &name, bool localStorage);
205 
206  /** This will perform the copy using ReadValue() and WriteValue()
207  * It can be overridden by any dervied classes to do a smarter more efficent copy. */
208  virtual DISTI_EXPORT DistiAttributeBase& operator = (const DistiAttributeBase & oldClass);
209 
210  virtual DISTI_EXPORT ~DistiAttributeBase();
211 
212  /** Returns the name of this object */
213  DISTI_EXPORT const AttributeName& Name() const;
214 
215  /** Returns the name of this object */
216  DISTI_EXPORT AttributeName& Name();
217 
218  /** Returns true if this object has local storage */
219  DISTI_EXPORT bool LocalStorage() const;
220 
221  /** Its not a word, but it means able to be copied
222  * This should return true if it makes sense for the data to be copied.
223  * By default, will only copy if it contains local storage */
224  virtual DISTI_EXPORT bool Copyable() const;
225 
226  /** Returns true if this object is ready to have its WriteValue() called
227  * This SHOULD be overriden by any derived objects that may not be ready
228  * to write at any point.
229  * The reason for this is the data is often written "NAME: VALUE". If
230  * Value is not available, we don't want to write "NAME: " first, so before
231  * writting "NAME: ", OkToWrite() can be called to see if it will have a valid value */
232  virtual DISTI_EXPORT bool OkToWrite() const;
233 
234  /** Returns true if the object's value has changed since
235  * calling ResetValueChanged()
236  * However, it is not implmented in the base class and will
237  * always return true if not overridden */
238  virtual DISTI_EXPORT bool ValueChanged();
239 
240  /** Saves the current value for later comparison by ValueChanged()
241  * This does nothing in the base class */
242  virtual DISTI_EXPORT void ResetValueChanged();
243 
244  /** Returns the std::string version of the attribute data.
245  * Here in the base class it uses WriteValue()
246  */
247  virtual DISTI_EXPORT std::string ValueString();
248 
249  /** Sets the value from a std::string argument.
250  * Here in the base class it uses ReadValue()
251  */
252  virtual DISTI_EXPORT void ValueString(const std::string& s);
253 
254  /** Allows for faster access to integer types than the more generic
255  * stream operators. However, it is only faster if it is overridden. */
256  virtual DISTI_EXPORT long ValueInt();
257 
258  /** Allows for faster access to integer types than the more generic
259  * stream operator. However, it is only faster if it is overridden. */
260  virtual DISTI_EXPORT void ValueInt(long val);
261 
262  /** Allows for faster access to floating-point types than the more generic
263  * stream operators. However, it is only faster if it is overridden. */
264  virtual DISTI_EXPORT double ValueFloat();
265 
266  /** Allows for faster access to floating-point types than the more generic
267  * stream operator. However, it is only faster if it is overridden. */
268  virtual DISTI_EXPORT void ValueFloat(double val);
269 
270  /** Calls callback CallType3 if it has been set */
271  virtual DISTI_EXPORT void CallCallback();
272 
273  /** Pure virtual because this is specific to the data type to be contained.
274  * This should be overridden to write the data to the stream */
275  virtual std::ostream & WriteValue(std::ostream &outstr) = 0;
276  /** Pure virtual because this is specific to the data type to be contained.
277  * This should be overridden to read the data from the stream */
278  virtual std::istream & ReadValue(std::istream &instr) = 0;
279 
280  /** Compares name and value
281  * This can be overriden to improve speed. */
282  virtual DISTI_EXPORT bool operator==(const DistiAttributeBase& r);
283 
284  /** Allow for generic access to some data types.
285  * This will NOT work for types which:
286  * s << val does not work.
287  * In general if the WriteValue is overridden, then it probably will not work.
288  */
289  template<class valType>
290  DistiAttributeBase & operator<<( const valType& val )
291  {
292  std::stringstream s;
293  s << val;
294  ReadValue(s);
295  return *this;
296  }
297  /** Allows for generic access to some data types.
298  * This will NOT work for types which:
299  * s >> val does not work.
300  * In general if the ReadValue is overridden, then it probably will not work.
301  */
302  template<class valType>
303  DistiAttributeBase & operator>>( valType& val )
304  {
305  std::stringstream s;
306  WriteValue(s);
307  s >> val;
308  return *this;
309  }
310 
311  /** Allows this class to send to a stream.
312  * Internally it uses WriteValue() */
313  friend DISTI_EXPORT std::ostream & operator<<(std::ostream & outstr, const DistiAttributeBase & attribute);
314  /** Allows this class to receive from a stream.
315  * Internally it uses ReadValue() */
316  friend DISTI_EXPORT std::istream & operator>>(std::istream & instr, DistiAttributeBase & attribute);
317 
318  /// Type for unique identifiers
319  typedef unsigned int CallbackID;
320 
321  /** Register a callback that is called when the value of the attribute changes. If multiple oservers are registered, they will be notified in the order they registered.
322  * DistiAttributeBase takes ownership of the observer and will delete it.
323  * \param observer the observer to notify. It is automatically unregistered and destroyed when it becomes invalid.
324  * \return an id that can be used to unregister the observer
325  */
326  virtual DISTI_EXPORT CallbackID RegisterObserver( AttributeObserver* observer );
327 
328  /** Unregister an observer
329  * \param id the id returned when the observer was registered
330  */
331  virtual DISTI_EXPORT void UnregisterObserver( CallbackID id );
332 
333  /** Triggers all observers to have their callbacks called. Typically called by the class that owns the DistiAttributeBase */
334  virtual DISTI_EXPORT void NotifyObservers();
335 };
336 
337 /** Template for an AttributeCallbackBase that will call a class method whenever the attribute changes. The class must implement WeakReferenceable.
338  * Don't use this directly, use CreateAttributeMethodCallback instead.
339  */
340 template <class T>
342 {
343 public:
344  typedef void ( T::*Callback )( DistiAttributeBase& attr );
345 
346  AttributeMethodCallback( T* object, Callback method )
347  : _method( method )
348  , _object( object )
349  {
350  GLS_VERIFY( NULL != method );
351  GLS_VERIFY( NULL != object );
352  }
353 
355  {
356  if( IsValid() )
357  {
358  ( _object.Get()->*( _method ) )( ev );
359  }
360  }
361 
362  virtual bool IsValid() const
363  {
364  return !_object.IsNull();
365  }
366 
367 protected:
368  Callback _method;
369  WeakRef<T> _object;
370 };
371 
372 /** Create an AttributeCallbackBase that will call a class method whenever the attribute changes.
373  * \param obj the object to call the method on
374  * \param method a class method pointer
375  */
376 template <class Class>
378  Class* const obj,
379  const typename AttributeMethodCallback<Class>::Callback method )
380 {
381  return new AttributeMethodCallback<Class>( obj, method );
382 }
383 
384 /** Template for an AttributeCallbackBase that will set another object's attribute whenever the attribute changes. The class must implement WeakReferenceable.
385  * Don't use this directly, use CreateAttributeResourceCallback instead.
386  */
387 template <class T>
389 {
390 public:
391  AttributeResourceCallback( T* object, const AttributeName& attributeName )
392  : _attributeName( attributeName )
393  , _object( object )
394  {
395  GLS_VERIFY( NULL != object );
396  }
397 
398  void Call( DistiAttributeBase& attr )
399  {
400  if( IsValid() )
401  {
402  if( DistiAttributeBase* objAttr = _object.Get()->Attributes().Get( _attributeName ) )
403  {
404  ( *objAttr ) << attr.ValueString();
405  }
406  }
407  }
408 
409  virtual bool IsValid() const
410  {
411  return !_object.IsNull();
412  }
413 
414 protected:
415  AttributeName _attributeName;
416  WeakRef<T> _object;
417 };
418 
419 /** Create an AttributeCallbackBase that will set another object's attribute whenever the attribute changes.
420  * \param obj the object to set the resource on
421  * \param attributeName the name of the property
422  */
423 template <class Class>
425  Class* const obj,
426  const char* attributeName )
427 {
428  return new AttributeResourceCallback<Class>( obj, AttributeName( attributeName ) );
429 }
430 
431 /** Interface for notifying when attributes have changed */
433 {
434 public:
435  /** Notify the class that the attribute has changed. Observers of the attribute will have their callbacks called
436  * \param name the name of the attribute
437  */
438  virtual DISTI_EXPORT void NotifyAttributeChanged( const AttributeName& name ) = 0;
439 
440  /** destructor */
442 };
443 
444 /** helper method to notify if an attribute has changed through a setter method
445  * \param object the object to notify
446  * \param property the storage for the data that is going to be set
447  * \param newValue the new value to set
448  * \param name the attribute name
449  */
450 template< class T >
451 void SetAndNotifyIfChanged( AttributeChangedNotifier* object, T& property, const T& newValue, const AttributeName& name )
452 {
453  if( newValue != property )
454  {
455  property = newValue;
456  object->NotifyAttributeChanged( name );
457  }
458 }
459 
460 
461 /** \class DistiAttribute
462  * A templated class for creating attributes.
463  */
464 class DistiAttribDict;
465 template <class T>
467 {
468 protected:
469  /** Points to the actual storage */
471  /** Allows for setting of precision for floating point numbers */
473 public:
474  /** Constructor
475  * Keeps a pointer to the specified type
476  * \param callback The method to call when the value changes. A duplicate of the
477  * CallbackMethodCallerBase is created and stored internally.
478  * \param name The name of the attribute
479  * \param attribPtr The address of the storage.
480  */
481  DistiAttribute(CallbackMethodCallerBase* callback, const AttributeName &name, T *attribPtr):
482  DistiAttributeBase(callback, name, false),
483  _attribPtr(attribPtr),
484  _precision(0)
485  {
486  // Automatically use some precision for floats
487  if ( typeid( T ) == typeid( float ) ||
488  typeid( T ) == typeid( double )||
489  typeid( T ) == typeid( long double ))
490  {
491  _precision = 10;
492  }
493  }
494 
495  /** Constructor
496  * Actually creates storage of the specified type
497  * \param callback The method to call when the value changes. A duplicate of the
498  * CallbackMethodCallerBase is created and stored internally.
499  * \param name The name of the attribute
500  * \param initialValue The initial value of the intenally stored variable.
501  */
502  DistiAttribute(CallbackMethodCallerBase* callback, const AttributeName &name, const T& initialValue):
503  DistiAttributeBase(callback, name, true /*Because we actually have storage*/),
504  _attribPtr(new T(initialValue)),
505  _precision(0)
506  {
507  // Automatically use some precision for floats
508  if ( typeid( T ) == typeid( float ) ||
509  typeid( T ) == typeid( double )||
510  typeid( T ) == typeid( long double ))
511  {
512  _precision = 10;
513  }
514  }
515  /** Its not a word, but it means able to be copied
516  * This should return true if it makes sense for the data to be copied.
517  * By default, will return true for this template.
518  * It is overridden here to allow for template specialization */
519  virtual bool Copyable() const { return true; }
520 
521  /** Allows for faster access to integer types than the more generic
522  * GetValueSimple. However, it is only faster if it is overridden.
523  * It is overridden here to allow for template specialization */
524  virtual long ValueInt()
525  {
527  }
528  /** Allows for faster access to integer types than the more generic
529  * SetValueSimple. However, it is only faster if it is overridden.
530  * It is overridden here to allow for template specialization */
531  virtual void ValueInt(long val)
532  {
534  }
535 
536  /** Allows for faster access to integer types than the more generic
537  * GetValueSimple. However, it is only faster if it is overridden.
538  * It is overridden here to allow for template specialization */
539  virtual double ValueFloat()
540  {
542  }
543  /** Allows for faster access to integer types than the more generic
544  * SetValueSimple. However, it is only faster if it is overridden.
545  * It is overridden here to allow for template specialization */
546  virtual void ValueFloat(double val)
547  {
549  }
550 
551  /** This will perform the copy using Value() and Value(val) */
553  {
554  DistiAttribute* ptr;
555 
556  ptr = dynamic_cast<DistiAttribute*>(const_cast<DistiAttributeBase*>(&oldClass));
557  if (ptr)
558  {
559  Value(ptr->Value());
560  }
561  else
562  {
563  return DistiAttributeBase::operator = (oldClass);
564  }
565  return *this;
566  }
567 
568  /** Writes the data to the stream */
569  virtual std::ostream & WriteValue(std::ostream &outstr)
570  {
571  if (_precision > 0)
572  outstr.precision(_precision);
573 
574  //operator<<(outstr, *_attribPtr);
575  outstr << *_attribPtr;
576  return outstr;
577  };
578 
579  /** Reads the data from the stream
580  * The ReadValue call shall consume only what it needs. It is the responsibility of
581  * the calling function to read to the end of line, or to clean up from a bad read.
582  * The calling function will also ensure that the data starts as the next byte in the stream. */
583  virtual std::istream& ReadValue( std::istream& instr )
584  {
585  return ReadValueImpl( instr );
586  };
587 
588  /** Allows for type specific access to the data */
589  virtual T Value()
590  {
591  return *_attribPtr;
592  }
593  /** Allows for type specific access to the data */
594  virtual void Value(const T &val)
595  {
596  *_attribPtr = val;
597  CallCallback();
598  }
599  /** Performs type specific comparison.
600  * This results in faster comparisons than the base class */
601  virtual bool operator==(const DistiAttributeBase& rArg)
602  {
603  DistiAttribute< T >* r = dynamic_cast< DistiAttribute< T >* >( const_cast<DistiAttributeBase*>(&rArg) );
604  if (!r)
605  return false;
606 
607  if (!(_name == r->_name))
608  return false;
609 
610  return Value() == r->Value();
611  }
612 
613  /** Destructor
614  * deletes local storage if we created it */
615  virtual ~DistiAttribute()
616  {
617  // Only delete it if we created it.
618  if (_localStorage && _attribPtr)
619  delete _attribPtr;
620  _attribPtr = NULL;
621  }
622 
623 private:
624  inline std::istream& ReadValueImpl( std::istream& instr )
625  {
626  instr >> *_attribPtr;
627  CallCallback();
628 
629  return instr;
630  }
631 };
632 
633 /** Optimized ReadValueImpl for floating point types.
634  * Visual Studio 2012 (vc110) runtime performs much slower when using
635  * std::istream::operator>>( float& val )
636  */
637 template<>
638 inline std::istream& DistiAttribute< float >::ReadValueImpl( std::istream& instr )
639 {
640  char instrBuf[64];
641  instr >> instrBuf;
642  *_attribPtr = static_cast< float >( atof( instrBuf ) );
643  CallCallback();
644 
645  return instr;
646 }
647 
648 template<>
649 inline std::istream& DistiAttribute< double >::ReadValueImpl( std::istream& instr )
650 {
651  char instrBuf[64];
652  instr >> instrBuf;
653  *_attribPtr = atof( instrBuf );
654  CallCallback();
655 
656  return instr;
657 }
658 
659 
660 /** The Attribute Dictionary is a container for DistiAttributeBase derived objects */
662 {
663 public:
664  /** Allows for easy access to the contained class type */
666 
667  typedef std::list<Attr_t> List_t;
668  typedef std::multimap<long, Attr_t> Map_t;
669 
670  typedef List_t::const_iterator const_iterator;
671  typedef List_t::iterator iterator;
672 
673  /** Constructor */
674  DISTI_EXPORT DistiAttribDict();
675 
676  /** Destructor */
677  virtual DISTI_EXPORT ~DistiAttribDict();
678 
679  /** Used as needed for version specific parsing
680  * Whenever a version is parsed, the results should be stored here.
681  * This does add order dependency.
682  *
683  * Note: These are not set or used by the DistiAttribDict class
684  * they are here to be set and accessed by the derived Attributes.
685  * Since they are shared by all instances of DistiAttribDict, they
686  * are only valid while the dictionary is parsing a file.
687  */
688  static DISTI_EXPORT double _currentFileVersionPrimary;
689  static DISTI_EXPORT long _currentFileVersionSecondary;
690 
691  /** Assignment operator
692  * Copies the values for all items which have matching names.
693  * All others are ignored */
694  DISTI_EXPORT DistiAttribDict& operator = (const DistiAttribDict &old_class);
695 
696  /** Equality operator
697  * Compares length, names and values.
698  * order does not matter */
699  DISTI_EXPORT bool operator == (const DistiAttribDict &old_class);
700 
701  /** Adds the specified Attribute to the list.
702  * The object passed in becomes the responsibility
703  * of this class, and should NOT be deleted by the
704  * caller. It will be deleted by this class as needed */
705  virtual DISTI_EXPORT void Add(DistiAttributeBase* attr);
706 
707  const_iterator Begin() const { return _list.begin(); }
708  const_iterator End() const { return _list.end(); }
709  iterator Begin() { return _list.begin(); }
710  iterator End() { return _list.end(); }
711 
712  /** Returns the current number of elements in the dictionary */
713  int DISTI_EXPORT Count() const;
714 
715  /** Returns the number of elements with the same name in the dictionary */
716  int DISTI_EXPORT Count(const AttributeName& name) const;
717 
718  /** Removes all elements in the list, deleting the data as it goes */
719  void DISTI_EXPORT Clear();
720 
721  /** Removes the attribute specified by name from the dictionary and
722  * deletes the data. This does actually delete the attribute.
723  */
724  virtual DISTI_EXPORT void Delete(const AttributeName& name);
725 
726  /** Reads a stream, expecting each line to be of the form
727  * NAME: SomeStringValue
728  * For each line a new DistiAttribute<std::string> is created,
729  * and the remaining line is placed as it's value.
730  * This is intended for special uses and is not considered
731  * the 'normal' mode of operation */
732  virtual DISTI_EXPORT void ReadStrings(std::istream &instr);
733 
734  /** Writes all items in the dictionary to the stream in the form:
735  * "NAME: VALUE"
736  * If changedDataOnly is true, only items which return ValueChanged() == true
737  * will be written.
738  */
739  virtual DISTI_EXPORT void Write(std::ostream &outstr, bool changedDataOnly = false);
740 
741  /** Reads multiple attributes from the stream expecting the form:
742  * "NAME: VALUE"
743  * Returns true if something was found and set. */
744  virtual DISTI_EXPORT bool Read(std::istream &instr);
745 
746  /** Returns the std::string value of the attribute specified by name
747  * Returns "" if not found
748  * Internally it uses ValueString() from the attribute */
749  virtual DISTI_EXPORT std::string ValueString(const AttributeName& name) const;
750 
751  /** Sets the attribute of named 'name' to the value of 'val'
752  * If name is not found, there is no indication */
753  virtual DISTI_EXPORT void ValueString(const AttributeName& name, const std::string& val);
754 
755  /** Gets the ValueInt() of the named attribute */
756  DISTI_EXPORT long ValueInt(const AttributeName& name) const;
757 
758  /** Sets the ValueInt() of the named attribute */
759  DISTI_EXPORT void ValueInt(const AttributeName& name, long val);
760 
761 #if 0
762  /** Allows for generic access to some data types.
763  * This will NOT work for types which:
764  * s << val does not work.
765  * In general if the attribute's WriteValue is overridden, then it probably will not work.
766  * Returns false if not found. */
767  template<class valType>
768  bool SetValueSimple(const AttributeName& name, const valType& val)
769  {
770  Map_t::iterator attr(_map.find(name.StringIndex()));
771 
772  if (attr != _map.end())
773  {
774  attr->second->SetValueSimple(val);
775  }
776 
777  return attr != _map.end();
778  }
779  /** Allows for generic access to some data types.
780  * This will NOT work for types which:
781  * s >> val does not work.
782  * In general if the attribute's ReadValue is overwridden, then it probably will not work.
783  * Will both set the argument, and return the value.
784  * The argument is required to determine the template type.
785  * Returns false if not found. */
786  template<class valType>
787  bool GetValueSimple(const AttributeName& name, valType& val)
788  {
789  Map_t::iterator attr(_map.find(name.StringIndex()));
790 
791  if (attr != _map.end())
792  {
793  attr->second->GetValueSimple(val);
794  }
795 
796  return attr != _map.end();
797  }
798 #endif
799 
800  /** Calls WriteValue() for the attribute specified by name */
801  virtual DISTI_EXPORT std::ostream & WriteValue(const AttributeName& name, std::ostream &outstr);
802 
803  /** Calls ReadValue() for the attribute specified by name */
804  virtual DISTI_EXPORT std::istream & ReadValue(const AttributeName& name, std::istream &instr);
805 
806  /** Returns the DistiAttributeBase* for the specified name
807  * If not found it returns NULL */
808  virtual DISTI_EXPORT DistiAttributeBase* Get(const AttributeName& name) const;
809 
810  /** Retuns a comparison of val with ValueInt() of the attribute
811  * looked up by name
812  * Returns false if not found */
813  virtual DISTI_EXPORT bool IsEqual(const AttributeName& name, const long val) const;
814 
815  /** Static, data for formating output */
816  static DISTI_EXPORT int currentOutputSpacing; // Should be private
817 
818  /** Static, Increments the current spacing */
819  static DISTI_EXPORT void SpacingInc();
820 
821  /** Static, Decrements the current spacing */
822  static DISTI_EXPORT void SpacingDec();
823 
824  /** Static, Sets the spacing to zero */
825  static DISTI_EXPORT void SpacingZero();
826 
827  /** Static, Returns a string containing the current spacing */
828  static DISTI_EXPORT std::string SpacingString();
829 
830  /** Static method used for parsing a stream
831  * Used internally and Exposed here so others can use it.
832  */
833  static DISTI_EXPORT bool ScanToken(std::istream &instr, std::string &result);
834 
835  /** Removes the attribute specified by name
836  * This does NOT actually delete the attribute, just removes it from the
837  * dictionary.
838  */
839  virtual DISTI_EXPORT void Remove(const AttributeName& name);
840 
841 protected:
842 
843  List_t _list;
844  Map_t _map;
845 
846 private:
847  /** Copy constructor
848  * Don't copy anything
849  * Almost everything is a pointer, so it wouldn't make sense */
850  DistiAttribDict(const DistiAttribDict &old_class);
851 };
852 
853 
854 ////////////////////////////////////////////////////////////
855 // Some useful derivations
856 ////////////////////////////////////////////////////////////
857 
858 /** \class DistiAttributeEnumStringPair
859  * A string to enumeration mapping
860  */
861 typedef struct
862 {
863  char _string[64];
864  int _enum;
866 
867 
868 /** A list of enumeration definitions */
869 class DistiAttributeEnumDefList : public std::list<DistiAttributeEnumStringPair*>
870 {
871 public:
872  DISTI_EXPORT DistiAttributeEnumDefList(char *stringVal, ...);
873  virtual DISTI_EXPORT int EnumToInt(const std::string& string);
874  virtual DISTI_EXPORT ~DistiAttributeEnumDefList();
875 };
876 
877 /** \class DistiAttributeEnum
878  * A Disti Attribute which reads and writes enumerations.
879  */
880 template<class containerClass,class setType,class getType>
882 {
883 public:
884 
885  DistiAttributeEnumDefList *_pairList;
886 
887  typedef void (containerClass::*SetMethodType)(setType);
888  typedef getType (containerClass::*GetMethodType)();
889 
890  containerClass* _object; /* Object that contains the attribute */
891  SetMethodType _setMethod; /* Set method member pointer */
892  GetMethodType _getMethod; /* Get method member pointer */
893 
894  DistiAttributeEnum(containerClass *object,SetMethodType setMethod, GetMethodType getMethod,const AttributeName &name) :
895  DistiAttributeBase(NULL,name,false),
896  _object(object),
897  _setMethod(setMethod),
898  _getMethod(getMethod)
899  {
900  DistiAssert(setMethod);
901  DistiAssert(getMethod);
902 
903  }
904 
905  virtual ~DistiAttributeEnum()
906  {
907  }
908 
909  virtual long ValueInt()
910  {
911  return (long)(_object->*_getMethod)();
912  }
913 
914  virtual void ValueInt(long val)
915  {
916  (_object->*_setMethod)((setType)val);
917  };
918 
920  {
922  if (ptr)
923  {
924  ValueInt(ptr->ValueInt());
925  }
926  else
927  {
928  return DistiAttributeBase::operator = (oldClass);
929  }
930  return *this;
931  }
932 
933  virtual std::ostream & WriteValue(std::ostream &outstr)
934  {
935  bool foundIt = false;
936  getType value = (_object->*_getMethod)();
937  DistiAttributeEnumDefList::iterator item = _pairList->begin();
938  while (item != _pairList->end() && *item)
939  {
940  if ((*item)->_enum == value)
941  {
942  outstr << (*item)->_string;
943  foundIt = true;
944  break;
945  }
946  ++item;
947  }
948  if (!foundIt)
949  {
950  //Didn't find it so just write the number
951  outstr << value;
952  }
953  return outstr;
954  }
955 
956  int EnumToInt(std::string &string)
957  {
958  bool foundIt = false;
959  int returnVal = 0;
960  DistiAttributeEnumDefList::iterator item = _pairList->begin();
961 
962  while (item != _pairList->end() && *item)
963  {
964  if (strcmp((*item)->_string, string.c_str()) == 0)
965  {
966  foundIt = true;
967  returnVal = (*item)->_enum;
968  break;
969  }
970  ++item;
971  }
972  return returnVal;
973  }
974 
975  virtual std::istream & ReadValue(std::istream &instr)
976  {
977  char value[64];
978  instr >> value;
979 
980  bool foundIt = false;
981  DistiAttributeEnumDefList::iterator item = _pairList->begin();
982 
983  // First look by enumeration
984  while (item != _pairList->end() && *item)
985  {
986  if (strcmp((*item)->_string, value) == 0)
987  {
988  (_object->*_setMethod)((setType)(*item)->_enum);
989 
990  foundIt = true;
991  break;
992  }
993  ++item;
994  }
995 
996  // If not found, assume that the numerical value is specified.
997  if (!foundIt)
998  {
999  (_object->*_setMethod)((setType)atoi(value));
1000  }
1001  return instr;
1002  }
1003 };
1004 
1005 
1006 } // namespace disti
1007 
1008 #if defined(WIN32)
1009 #pragma warning( pop )
1010 #endif
1011 
1012 #endif
The DistiUnhideGlobalsDummyClass class.
virtual DistiAttributeBase & operator=(const DistiAttributeBase &oldClass)
Definition: disti_metadata.h:919
virtual ~AttributeChangedNotifier()
Definition: disti_metadata.h:441
virtual void Call(DistiAttributeBase &attr)=0
virtual bool Copyable() const
bool operator==(const AttributeName &other) const
virtual bool operator==(const DistiAttributeBase &r)
static int currentOutputSpacing
Definition: disti_metadata.h:816
bool LocalStorage() const
virtual long ValueInt()
Definition: disti_metadata.h:909
virtual void ValueFloat(double val)
Definition: disti_metadata.h:546
The disti::DynamicArray class. A templated array of objects capable of dynamically growing...
virtual DistiAttributeBase & operator=(const DistiAttributeBase &oldClass)
Definition: disti_metadata.h:552
virtual void NotifyObservers()
virtual DistiAttributeBase & operator=(const DistiAttributeBase &oldClass)
AttributeObserver * CreateAttributeResourceCallback(Class *const obj, const char *attributeName)
Definition: disti_metadata.h:424
DistiAttributeBase & operator>>(valType &val)
Definition: disti_metadata.h:303
static double _currentFileVersionPrimary
Definition: disti_metadata.h:688
DistiAttributeBase & operator<<(const valType &val)
Definition: disti_metadata.h:290
virtual std::istream & ReadValue(const AttributeName &name, std::istream &instr)
virtual std::ostream & WriteValue(std::ostream &outstr)
Definition: disti_metadata.h:933
virtual std::ostream & WriteValue(std::ostream &outstr)
Definition: disti_metadata.h:569
Definition: disti_metadata.h:388
virtual double ValueFloat()
A templated list, disti::TList.
virtual std::istream & ReadValue(std::istream &instr)
Definition: disti_metadata.h:583
weak reference and related classes
virtual bool IsEqual(const AttributeName &name, const long val) const
AttributeName(const std::string &name)
virtual ~DistiAttribute()
Definition: disti_metadata.h:615
static void SpacingDec()
A file for all GL Studio files to include.
virtual bool ValueChanged()
virtual bool IsValid() const
Definition: disti_metadata.h:362
void Call(DistiAttributeBase &attr)
Definition: disti_metadata.h:398
static std::string SpacingString()
DistiAttributeBase * Attr_t
Definition: disti_metadata.h:665
virtual std::string ValueString()
unsigned int CallbackID
Type for unique identifiers.
Definition: disti_metadata.h:319
virtual bool Copyable() const
Definition: disti_metadata.h:519
virtual double ValueFloat()
Definition: disti_metadata.h:539
friend std::ostream & operator<<(std::ostream &outstr, const AttributeName &name)
virtual bool IsValid() const =0
virtual void Write(std::ostream &outstr, bool changedDataOnly=false)
Definition: disti_metadata.h:881
DistiAttribute(CallbackMethodCallerBase *callback, const AttributeName &name, T *attribPtr)
Definition: disti_metadata.h:481
virtual void CallCallback()
virtual bool operator==(const DistiAttributeBase &rArg)
Definition: disti_metadata.h:601
virtual bool OkToWrite() const
int _precision
Definition: disti_metadata.h:472
virtual std::ostream & WriteValue(const AttributeName &name, std::ostream &outstr)
Definition: disti_metadata.h:341
DistiAttribDict & operator=(const DistiAttribDict &old_class)
virtual void Add(DistiAttributeBase *attr)
T * _attribPtr
Definition: disti_metadata.h:470
Definition: gls_mutex.h:53
Definition: disti_metadata.h:466
virtual bool IsValid() const
Definition: disti_metadata.h:409
#define GLS_VERIFY(exp)
Definition: disti_assert.h:148
virtual std::istream & ReadValue(std::istream &instr)
Definition: disti_metadata.h:975
virtual void ValueInt(long val)
Definition: disti_metadata.h:914
static void SpacingInc()
virtual void Remove(const AttributeName &name)
virtual T Value()
Definition: disti_metadata.h:589
Definition: disti_metadata.h:179
virtual std::string ValueString(const AttributeName &name) const
virtual long ValueInt()
Definition: disti_metadata.h:524
virtual void ValueInt(long val)
Definition: disti_metadata.h:531
virtual bool Read(std::istream &instr)
Definition: disti_metadata.h:162
static bool ScanToken(std::istream &instr, std::string &result)
void Call(DistiAttributeBase &ev)
Definition: disti_metadata.h:354
Definition: disti_metadata.h:661
Definition: weak_referenceable_mixin.h:52
Definition: disti_metadata.h:869
Definition: callback_caller_base.h:56
bool _localStorage
Definition: disti_metadata.h:195
void SetAndNotifyIfChanged(AttributeChangedNotifier *object, T &property, const T &newValue, const AttributeName &name)
Definition: disti_metadata.h:451
Definition: weak_reference.h:91
long ValueInt(const AttributeName &name) const
CallbackMethodCallerBase * _callback
Definition: disti_metadata.h:187
AttributeObserver * CreateAttributeMethodCallback(Class *const obj, const typename AttributeMethodCallback< Class >::Callback method)
Definition: disti_metadata.h:377
virtual void ResetValueChanged()
virtual void Delete(const AttributeName &name)
virtual CallbackID RegisterObserver(AttributeObserver *observer)
Definition: disti_metadata.h:432
AttributeName _name
Definition: disti_metadata.h:185
long StringIndex() const
static void SpacingZero()
scoped ptr
DistiAttribute(CallbackMethodCallerBase *callback, const AttributeName &name, const T &initialValue)
Definition: disti_metadata.h:502
virtual void Value(const T &val)
Definition: disti_metadata.h:594
Definition: disti_metadata.h:861
virtual void ReadStrings(std::istream &instr)
virtual void NotifyAttributeChanged(const AttributeName &name)=0
Definition: disti_metadata.h:83
const AttributeName & Name() const
Definition: bmpimage.h:46
virtual std::istream & ReadValue(std::istream &instr)=0
bool operator==(const DistiAttribDict &old_class)
virtual void UnregisterObserver(CallbackID id)
weak reference and related classes
bool operator!=(const AttributeName &other) const
virtual std::ostream & WriteValue(std::ostream &outstr)=0
virtual DistiAttributeBase * Get(const AttributeName &name) const