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  * If this particular attribute's underlying type is a string, this returns the unencoded value, suitable for users.
247  * If a file encoded value is required, call WriteValue instead.
248  */
249  virtual DISTI_EXPORT std::string ValueString();
250 
251  /** Sets the value from a std::string argument.
252  * Here in the base class it uses ReadValue()
253  * If this particular attribute's underlying type is a string, this should not be set to an encoded value.
254  * If needing to set from an encoded value, call ReadValue instead.
255  */
256  virtual DISTI_EXPORT void ValueString(const std::string& s);
257 
258  /** Allows for faster access to integer types than the more generic
259  * stream operators. However, it is only faster if it is overridden. */
260  virtual DISTI_EXPORT long ValueInt();
261 
262  /** Allows for faster access to integer types than the more generic
263  * stream operator. However, it is only faster if it is overridden. */
264  virtual DISTI_EXPORT void ValueInt(long val);
265 
266  /** Allows for faster access to floating-point types than the more generic
267  * stream operators. However, it is only faster if it is overridden. */
268  virtual DISTI_EXPORT double ValueFloat();
269 
270  /** Allows for faster access to floating-point types than the more generic
271  * stream operator. However, it is only faster if it is overridden. */
272  virtual DISTI_EXPORT void ValueFloat(double val);
273 
274  /** Calls callback CallType3 if it has been set */
275  virtual DISTI_EXPORT void CallCallback();
276 
277  /** Pure virtual because this is specific to the data type to be contained.
278  * This should be overridden to write the data to the stream.
279  * The value written could be encoded for writing to a file as a single string,
280  * or have its own special encoding specific to its underlying type.
281  * In the case of attribute strings, this will be the GLS file encoded value.
282  * The user is responsible for decoding the value themselves, or using ReadValue
283  * which should perform decoding to maintain symmetry. */
284  virtual std::ostream & WriteValue(std::ostream &outstr) = 0;
285  /** Pure virtual because this is specific to the data type to be contained.
286  * This should be overridden to read the data from the stream.
287  * The value read could be encoded for being read from a file as a single string,
288  * or have its own special encoding specific to its underlying type.
289  * In the case of attribute strings, this will be the GLS file encoded value.
290  * The user is responsible for encoding the value themselves, or using WriteValue
291  * which should perform encoding to maintain symmetry.
292  */
293  virtual std::istream & ReadValue(std::istream &instr) = 0;
294 
295  /** Compares name and value
296  * This can be overriden to improve speed. */
297  virtual DISTI_EXPORT bool operator==(const DistiAttributeBase& r);
298 
299  /** Allow for generic access to some data types.
300  * This will NOT work for types which:
301  * s << val does not work.
302  * In general if the WriteValue is overridden, then it probably will not work.
303  */
304  template<class valType>
305  DistiAttributeBase & operator<<( const valType& val )
306  {
307  std::stringstream s;
308  s << val;
309  ReadValue(s);
310  return *this;
311  }
312  /** Allows for generic access to some data types.
313  * This will NOT work for types which:
314  * s >> val does not work.
315  * In general if the ReadValue is overridden, then it probably will not work.
316  */
317  template<class valType>
318  DistiAttributeBase & operator>>( valType& val )
319  {
320  std::stringstream s;
321  WriteValue(s);
322  s >> val;
323  return *this;
324  }
325 
326  /** Allows this class to send to a stream.
327  * Internally it uses WriteValue() */
328  friend DISTI_EXPORT std::ostream & operator<<(std::ostream & outstr, const DistiAttributeBase & attribute);
329  /** Allows this class to receive from a stream.
330  * Internally it uses ReadValue() */
331  friend DISTI_EXPORT std::istream & operator>>(std::istream & instr, DistiAttributeBase & attribute);
332 
333  /// Type for unique identifiers
334  typedef unsigned int CallbackID;
335 
336  /** 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.
337  * DistiAttributeBase takes ownership of the observer and will delete it.
338  * \param observer the observer to notify. It is automatically unregistered and destroyed when it becomes invalid.
339  * \return an id that can be used to unregister the observer
340  */
341  virtual DISTI_EXPORT CallbackID RegisterObserver( AttributeObserver* observer );
342 
343  /** Unregister an observer
344  * \param id the id returned when the observer was registered
345  */
346  virtual DISTI_EXPORT void UnregisterObserver( CallbackID id );
347 
348  /** Triggers all observers to have their callbacks called. Typically called by the class that owns the DistiAttributeBase */
349  virtual DISTI_EXPORT void NotifyObservers();
350 };
351 
352 /** Template for an AttributeCallbackBase that will call a class method whenever the attribute changes. The class must implement WeakReferenceable.
353  * Don't use this directly, use CreateAttributeMethodCallback instead.
354  */
355 template <class T>
357 {
358 public:
359  typedef void ( T::*Callback )( DistiAttributeBase& attr );
360 
361  AttributeMethodCallback( T* object, Callback method )
362  : _method( method )
363  , _object( object )
364  {
365  GLS_VERIFY( NULL != method );
366  GLS_VERIFY( NULL != object );
367  }
368 
370  {
371  if( IsValid() )
372  {
373  ( _object.Get()->*( _method ) )( ev );
374  }
375  }
376 
377  virtual bool IsValid() const
378  {
379  return !_object.IsNull();
380  }
381 
382 protected:
383  Callback _method;
384  WeakRef<T> _object;
385 };
386 
387 /** Create an AttributeCallbackBase that will call a class method whenever the attribute changes.
388  * \param obj the object to call the method on
389  * \param method a class method pointer
390  */
391 template <class Class>
393  Class* const obj,
394  const typename AttributeMethodCallback<Class>::Callback method )
395 {
396  return new AttributeMethodCallback<Class>( obj, method );
397 }
398 
399 /** Template for an AttributeCallbackBase that will set another object's attribute whenever the attribute changes. The class must implement WeakReferenceable.
400  * Don't use this directly, use CreateAttributeResourceCallback instead.
401  */
402 template <class T>
404 {
405 public:
406  AttributeResourceCallback( T* object, const AttributeName& attributeName )
407  : _attributeName( attributeName )
408  , _object( object )
409  {
410  GLS_VERIFY( NULL != object );
411  }
412 
413  void Call( DistiAttributeBase& attr )
414  {
415  if( IsValid() )
416  {
417  if( DistiAttributeBase* objAttr = _object.Get()->Attributes().Get( _attributeName ) )
418  {
419  ( *objAttr ) << attr.ValueString();
420  }
421  }
422  }
423 
424  virtual bool IsValid() const
425  {
426  return !_object.IsNull();
427  }
428 
429 protected:
430  AttributeName _attributeName;
431  WeakRef<T> _object;
432 };
433 
434 /** Create an AttributeCallbackBase that will set another object's attribute whenever the attribute changes.
435  * \param obj the object to set the resource on
436  * \param attributeName the name of the property
437  */
438 template <class Class>
440  Class* const obj,
441  const char* attributeName )
442 {
443  return new AttributeResourceCallback<Class>( obj, AttributeName( attributeName ) );
444 }
445 
446 /** Interface for notifying when attributes have changed */
448 {
449 public:
450  /** Notify the class that the attribute has changed. Observers of the attribute will have their callbacks called
451  * \param name the name of the attribute
452  */
453  virtual DISTI_EXPORT void NotifyAttributeChanged( const AttributeName& name ) = 0;
454 
455  /** destructor */
457 };
458 
459 /** helper method to notify if an attribute has changed through a setter method
460  * \param object the object to notify
461  * \param property the storage for the data that is going to be set
462  * \param newValue the new value to set
463  * \param name the attribute name
464  */
465 template< class T >
466 void SetAndNotifyIfChanged( AttributeChangedNotifier* object, T& property, const T& newValue, const AttributeName& name )
467 {
468  if( newValue != property )
469  {
470  property = newValue;
471  object->NotifyAttributeChanged( name );
472  }
473 }
474 
475 
476 /** \class DistiAttribute
477  * A templated class for creating attributes.
478  */
479 class DistiAttribDict;
480 template <class T>
482 {
483 protected:
484  /** Points to the actual storage */
486  /** Allows for setting of precision for floating point numbers */
488 public:
489  /** Constructor
490  * Keeps a pointer to the specified type
491  * \param callback The method to call when the value changes. A duplicate of the
492  * CallbackMethodCallerBase is created and stored internally.
493  * \param name The name of the attribute
494  * \param attribPtr The address of the storage.
495  */
496  DistiAttribute(CallbackMethodCallerBase* callback, const AttributeName &name, T *attribPtr):
497  DistiAttributeBase(callback, name, false),
498  _attribPtr(attribPtr),
499  _precision(0)
500  {
501  // Automatically use some precision for floats
502  if ( typeid( T ) == typeid( float ) ||
503  typeid( T ) == typeid( double )||
504  typeid( T ) == typeid( long double ))
505  {
506  _precision = 10;
507  }
508  }
509 
510  /** Constructor
511  * Actually creates storage of the specified type
512  * \param callback The method to call when the value changes. A duplicate of the
513  * CallbackMethodCallerBase is created and stored internally.
514  * \param name The name of the attribute
515  * \param initialValue The initial value of the intenally stored variable.
516  */
517  DistiAttribute(CallbackMethodCallerBase* callback, const AttributeName &name, const T& initialValue):
518  DistiAttributeBase(callback, name, true /*Because we actually have storage*/),
519  _attribPtr(new T(initialValue)),
520  _precision(0)
521  {
522  // Automatically use some precision for floats
523  if ( typeid( T ) == typeid( float ) ||
524  typeid( T ) == typeid( double )||
525  typeid( T ) == typeid( long double ))
526  {
527  _precision = 10;
528  }
529  }
530  /** Its not a word, but it means able to be copied
531  * This should return true if it makes sense for the data to be copied.
532  * By default, will return true for this template.
533  * It is overridden here to allow for template specialization */
534  virtual bool Copyable() const { return true; }
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 long ValueInt()
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 ValueInt(long val)
547  {
549  }
550 
551  /** Allows for faster access to integer types than the more generic
552  * GetValueSimple. However, it is only faster if it is overridden.
553  * It is overridden here to allow for template specialization */
554  virtual double ValueFloat()
555  {
557  }
558  /** Allows for faster access to integer types than the more generic
559  * SetValueSimple. However, it is only faster if it is overridden.
560  * It is overridden here to allow for template specialization */
561  virtual void ValueFloat(double val)
562  {
564  }
565 
566  /** This will perform the copy using Value() and Value(val) */
568  {
569  DistiAttribute* ptr;
570 
571  ptr = dynamic_cast<DistiAttribute*>(const_cast<DistiAttributeBase*>(&oldClass));
572  if (ptr)
573  {
574  Value(ptr->Value());
575  }
576  else
577  {
578  return DistiAttributeBase::operator = (oldClass);
579  }
580  return *this;
581  }
582 
583  /** Writes the data to the stream */
584  virtual std::ostream & WriteValue(std::ostream &outstr)
585  {
586  if (_precision > 0)
587  outstr.precision(_precision);
588 
589  //operator<<(outstr, *_attribPtr);
590  outstr << *_attribPtr;
591  return outstr;
592  };
593 
594  /** Reads the data from the stream
595  * The ReadValue call shall consume only what it needs. It is the responsibility of
596  * the calling function to read to the end of line, or to clean up from a bad read.
597  * The calling function will also ensure that the data starts as the next byte in the stream. */
598  virtual std::istream& ReadValue( std::istream& instr )
599  {
600  return ReadValueImpl( instr );
601  };
602 
603  /** Allows for type specific access to the data */
604  virtual T Value()
605  {
606  return *_attribPtr;
607  }
608  /** Allows for type specific access to the data */
609  virtual void Value(const T &val)
610  {
611  *_attribPtr = val;
612  CallCallback();
613  }
614  /** Performs type specific comparison.
615  * This results in faster comparisons than the base class */
616  virtual bool operator==(const DistiAttributeBase& rArg)
617  {
618  DistiAttribute< T >* r = dynamic_cast< DistiAttribute< T >* >( const_cast<DistiAttributeBase*>(&rArg) );
619  if (!r)
620  return false;
621 
622  if (!(_name == r->_name))
623  return false;
624 
625  return Value() == r->Value();
626  }
627 
628  /** Destructor
629  * deletes local storage if we created it */
630  virtual ~DistiAttribute()
631  {
632  // Only delete it if we created it.
633  if (_localStorage && _attribPtr)
634  delete _attribPtr;
635  _attribPtr = NULL;
636  }
637 
638 private:
639  inline std::istream& ReadValueImpl( std::istream& instr )
640  {
641  instr >> *_attribPtr;
642  CallCallback();
643 
644  return instr;
645  }
646 };
647 
648 /** Optimized ReadValueImpl for floating point types.
649  * Visual Studio 2012 (vc110) runtime performs much slower when using
650  * std::istream::operator>>( float& val )
651  */
652 template<>
653 inline std::istream& DistiAttribute< float >::ReadValueImpl( std::istream& instr )
654 {
655  char instrBuf[64];
656  instr >> instrBuf;
657  *_attribPtr = static_cast< float >( atof( instrBuf ) );
658  CallCallback();
659 
660  return instr;
661 }
662 
663 template<>
664 inline std::istream& DistiAttribute< double >::ReadValueImpl( std::istream& instr )
665 {
666  char instrBuf[64];
667  instr >> instrBuf;
668  *_attribPtr = atof( instrBuf );
669  CallCallback();
670 
671  return instr;
672 }
673 
674 
675 /** The Attribute Dictionary is a container for DistiAttributeBase derived objects */
677 {
678 public:
679  /** Allows for easy access to the contained class type */
681 
682  typedef std::list<Attr_t> List_t;
683  typedef std::multimap<long, Attr_t> Map_t;
684 
685  typedef List_t::const_iterator const_iterator;
686  typedef List_t::iterator iterator;
687 
688  /** Constructor */
689  DISTI_EXPORT DistiAttribDict();
690 
691  /** Destructor */
692  virtual DISTI_EXPORT ~DistiAttribDict();
693 
694  /** Used as needed for version specific parsing
695  * Whenever a version is parsed, the results should be stored here.
696  * This does add order dependency.
697  *
698  * Note: These are not set or used by the DistiAttribDict class
699  * they are here to be set and accessed by the derived Attributes.
700  * Since they are shared by all instances of DistiAttribDict, they
701  * are only valid while the dictionary is parsing a file.
702  */
703  static DISTI_EXPORT double _currentFileVersionPrimary;
704  static DISTI_EXPORT long _currentFileVersionSecondary;
705 
706  /** Assignment operator
707  * Copies the values for all items which have matching names.
708  * All others are ignored */
709  DISTI_EXPORT DistiAttribDict& operator = (const DistiAttribDict &old_class);
710 
711  /** Equality operator
712  * Compares length, names and values.
713  * order does not matter */
714  DISTI_EXPORT bool operator == (const DistiAttribDict &old_class);
715 
716  /** Adds the specified Attribute to the list.
717  * The object passed in becomes the responsibility
718  * of this class, and should NOT be deleted by the
719  * caller. It will be deleted by this class as needed */
720  virtual DISTI_EXPORT void Add(DistiAttributeBase* attr);
721 
722  const_iterator Begin() const { return _list.begin(); }
723  const_iterator End() const { return _list.end(); }
724  iterator Begin() { return _list.begin(); }
725  iterator End() { return _list.end(); }
726 
727  /** Returns the current number of elements in the dictionary */
728  int DISTI_EXPORT Count() const;
729 
730  /** Returns the number of elements with the same name in the dictionary */
731  int DISTI_EXPORT Count(const AttributeName& name) const;
732 
733  /** Removes all elements in the list, deleting the data as it goes */
734  void DISTI_EXPORT Clear();
735 
736  /** Removes the attribute specified by name from the dictionary and
737  * deletes the data. This does actually delete the attribute.
738  */
739  virtual DISTI_EXPORT void Delete(const AttributeName& name);
740 
741  /** Reads a stream, expecting each line to be of the form
742  * NAME: SomeStringValue
743  * For each line a new DistiAttribute<std::string> is created,
744  * and the remaining line is placed as it's value.
745  * This is intended for special uses and is not considered
746  * the 'normal' mode of operation */
747  virtual DISTI_EXPORT void ReadStrings(std::istream &instr);
748 
749  /** Writes all items in the dictionary to the stream in the form:
750  * "NAME: VALUE"
751  * If changedDataOnly is true, only items which return ValueChanged() == true
752  * will be written.
753  */
754  virtual DISTI_EXPORT void Write(std::ostream &outstr, bool changedDataOnly = false);
755 
756  /** Reads multiple attributes from the stream expecting the form:
757  * "NAME: VALUE"
758  * Returns true if something was found and set. */
759  virtual DISTI_EXPORT bool Read(std::istream &instr);
760 
761  /** Reads multiple attributes from the stream expecting the form:
762  * "NAME: VALUE"
763  * missing stream is filled with attributes that were not in the dictionary
764  * Returns true if something was found and set. */
765  DISTI_EXPORT bool ReadAndCaptureMissing(std::istream &instr, std::stringstream* missingStream);
766 
767  /** Returns the std::string value of the attribute specified by name
768  * Returns "" if not found
769  * Internally it uses ValueString() from the attribute */
770  virtual DISTI_EXPORT std::string ValueString(const AttributeName& name) const;
771 
772  /** Sets the attribute of named 'name' to the value of 'val'
773  * If name is not found, there is no indication */
774  virtual DISTI_EXPORT void ValueString(const AttributeName& name, const std::string& val);
775 
776  /** Gets the ValueInt() of the named attribute */
777  DISTI_EXPORT long ValueInt(const AttributeName& name) const;
778 
779  /** Sets the ValueInt() of the named attribute */
780  DISTI_EXPORT void ValueInt(const AttributeName& name, long val);
781 
782 #if 0
783  /** Allows for generic access to some data types.
784  * This will NOT work for types which:
785  * s << val does not work.
786  * In general if the attribute's WriteValue is overridden, then it probably will not work.
787  * Returns false if not found. */
788  template<class valType>
789  bool SetValueSimple(const AttributeName& name, const valType& val)
790  {
791  Map_t::iterator attr(_map.find(name.StringIndex()));
792 
793  if (attr != _map.end())
794  {
795  attr->second->SetValueSimple(val);
796  }
797 
798  return attr != _map.end();
799  }
800  /** Allows for generic access to some data types.
801  * This will NOT work for types which:
802  * s >> val does not work.
803  * In general if the attribute's ReadValue is overwridden, then it probably will not work.
804  * Will both set the argument, and return the value.
805  * The argument is required to determine the template type.
806  * Returns false if not found. */
807  template<class valType>
808  bool GetValueSimple(const AttributeName& name, valType& val)
809  {
810  Map_t::iterator attr(_map.find(name.StringIndex()));
811 
812  if (attr != _map.end())
813  {
814  attr->second->GetValueSimple(val);
815  }
816 
817  return attr != _map.end();
818  }
819 #endif
820 
821  /** Calls WriteValue() for the attribute specified by name */
822  virtual DISTI_EXPORT std::ostream & WriteValue(const AttributeName& name, std::ostream &outstr);
823 
824  /** Calls ReadValue() for the attribute specified by name */
825  virtual DISTI_EXPORT std::istream & ReadValue(const AttributeName& name, std::istream &instr);
826 
827  /** Returns the DistiAttributeBase* for the specified name
828  * If not found it returns NULL */
829  virtual DISTI_EXPORT DistiAttributeBase* Get(const AttributeName& name) const;
830 
831  /** Retuns a comparison of val with ValueInt() of the attribute
832  * looked up by name
833  * Returns false if not found */
834  virtual DISTI_EXPORT bool IsEqual(const AttributeName& name, const long val) const;
835 
836  /** Static, data for formating output */
837  static DISTI_EXPORT int currentOutputSpacing; // Should be private
838 
839  /** Static, Increments the current spacing */
840  static DISTI_EXPORT void SpacingInc();
841 
842  /** Static, Decrements the current spacing */
843  static DISTI_EXPORT void SpacingDec();
844 
845  /** Static, Sets the spacing to zero */
846  static DISTI_EXPORT void SpacingZero();
847 
848  /** Static, Returns a string containing the current spacing */
849  static DISTI_EXPORT std::string SpacingString();
850 
851  /** Static method used for parsing a stream
852  * Used internally and Exposed here so others can use it.
853  */
854  static DISTI_EXPORT bool ScanToken(std::istream &instr, std::string &result);
855 
856  /** Removes the attribute specified by name
857  * This does NOT actually delete the attribute, just removes it from the
858  * dictionary.
859  */
860  virtual DISTI_EXPORT void Remove(const AttributeName& name);
861 
862 protected:
863 
864  List_t _list;
865  Map_t _map;
866 
867 private:
868  /** Copy constructor
869  * Don't copy anything
870  * Almost everything is a pointer, so it wouldn't make sense */
871  DistiAttribDict(const DistiAttribDict &old_class);
872 };
873 
874 
875 ////////////////////////////////////////////////////////////
876 // Some useful derivations
877 ////////////////////////////////////////////////////////////
878 
879 /** \class DistiAttributeEnumStringPair
880  * A string to enumeration mapping
881  */
882 typedef struct
883 {
884  char _string[64];
885  int _enum;
887 
888 
889 /** A list of enumeration definitions */
890 class DistiAttributeEnumDefList : public std::list<DistiAttributeEnumStringPair*>
891 {
892 public:
893  DISTI_EXPORT DistiAttributeEnumDefList(char *stringVal, ...);
894  virtual DISTI_EXPORT int EnumToInt(const std::string& string);
895  virtual DISTI_EXPORT ~DistiAttributeEnumDefList();
896 };
897 
898 /** \class DistiAttributeEnum
899  * A Disti Attribute which reads and writes enumerations.
900  */
901 template<class containerClass,class setType,class getType>
903 {
904 public:
905 
906  DistiAttributeEnumDefList *_pairList;
907 
908  typedef void (containerClass::*SetMethodType)(setType);
909  typedef getType (containerClass::*GetMethodType)();
910 
911  containerClass* _object; /* Object that contains the attribute */
912  SetMethodType _setMethod; /* Set method member pointer */
913  GetMethodType _getMethod; /* Get method member pointer */
914 
915  DistiAttributeEnum(containerClass *object,SetMethodType setMethod, GetMethodType getMethod,const AttributeName &name) :
916  DistiAttributeBase(NULL,name,false),
917  _object(object),
918  _setMethod(setMethod),
919  _getMethod(getMethod)
920  {
921  DistiAssert(setMethod);
922  DistiAssert(getMethod);
923 
924  }
925 
926  virtual ~DistiAttributeEnum()
927  {
928  }
929 
930  virtual long ValueInt()
931  {
932  return (long)(_object->*_getMethod)();
933  }
934 
935  virtual void ValueInt(long val)
936  {
937  (_object->*_setMethod)((setType)val);
938  };
939 
941  {
943  if (ptr)
944  {
945  ValueInt(ptr->ValueInt());
946  }
947  else
948  {
949  return DistiAttributeBase::operator = (oldClass);
950  }
951  return *this;
952  }
953 
954  virtual std::ostream & WriteValue(std::ostream &outstr)
955  {
956  bool foundIt = false;
957  getType value = (_object->*_getMethod)();
958  DistiAttributeEnumDefList::iterator item = _pairList->begin();
959  while (item != _pairList->end() && *item)
960  {
961  if ((*item)->_enum == value)
962  {
963  outstr << (*item)->_string;
964  foundIt = true;
965  break;
966  }
967  ++item;
968  }
969  if (!foundIt)
970  {
971  //Didn't find it so just write the number
972  outstr << value;
973  }
974  return outstr;
975  }
976 
977  int EnumToInt(std::string &string)
978  {
979  bool foundIt = false;
980  int returnVal = 0;
981  DistiAttributeEnumDefList::iterator item = _pairList->begin();
982 
983  while (item != _pairList->end() && *item)
984  {
985  if (strcmp((*item)->_string, string.c_str()) == 0)
986  {
987  foundIt = true;
988  returnVal = (*item)->_enum;
989  break;
990  }
991  ++item;
992  }
993  return returnVal;
994  }
995 
996  virtual std::istream & ReadValue(std::istream &instr)
997  {
998  char value[64];
999  instr >> value;
1000 
1001  bool foundIt = false;
1002  DistiAttributeEnumDefList::iterator item = _pairList->begin();
1003 
1004  // First look by enumeration
1005  while (item != _pairList->end() && *item)
1006  {
1007  if (strcmp((*item)->_string, value) == 0)
1008  {
1009  (_object->*_setMethod)((setType)(*item)->_enum);
1010 
1011  foundIt = true;
1012  break;
1013  }
1014  ++item;
1015  }
1016 
1017  // If not found, assume that the numerical value is specified.
1018  if (!foundIt)
1019  {
1020  (_object->*_setMethod)((setType)atoi(value));
1021  }
1022  return instr;
1023  }
1024 };
1025 
1026 
1027 } // namespace disti
1028 
1029 #if defined(WIN32)
1030 #pragma warning( pop )
1031 #endif
1032 
1033 #endif
The DistiUnhideGlobalsDummyClass class.
virtual DistiAttributeBase & operator=(const DistiAttributeBase &oldClass)
Definition: disti_metadata.h:940
virtual ~AttributeChangedNotifier()
Definition: disti_metadata.h:456
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:837
bool LocalStorage() const
virtual long ValueInt()
Definition: disti_metadata.h:930
virtual void ValueFloat(double val)
Definition: disti_metadata.h:561
The disti::DynamicArray class. A templated array of objects capable of dynamically growing...
virtual DistiAttributeBase & operator=(const DistiAttributeBase &oldClass)
Definition: disti_metadata.h:567
virtual void NotifyObservers()
virtual DistiAttributeBase & operator=(const DistiAttributeBase &oldClass)
AttributeObserver * CreateAttributeResourceCallback(Class *const obj, const char *attributeName)
Definition: disti_metadata.h:439
DistiAttributeBase & operator>>(valType &val)
Definition: disti_metadata.h:318
static double _currentFileVersionPrimary
Definition: disti_metadata.h:703
DistiAttributeBase & operator<<(const valType &val)
Definition: disti_metadata.h:305
virtual std::istream & ReadValue(const AttributeName &name, std::istream &instr)
virtual std::ostream & WriteValue(std::ostream &outstr)
Definition: disti_metadata.h:954
virtual std::ostream & WriteValue(std::ostream &outstr)
Definition: disti_metadata.h:584
Definition: disti_metadata.h:403
virtual double ValueFloat()
A templated list, disti::TList.
virtual std::istream & ReadValue(std::istream &instr)
Definition: disti_metadata.h:598
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:630
static void SpacingDec()
A file for all GL Studio files to include.
virtual bool ValueChanged()
virtual bool IsValid() const
Definition: disti_metadata.h:377
void Call(DistiAttributeBase &attr)
Definition: disti_metadata.h:413
static std::string SpacingString()
DistiAttributeBase * Attr_t
Definition: disti_metadata.h:680
virtual std::string ValueString()
unsigned int CallbackID
Type for unique identifiers.
Definition: disti_metadata.h:334
virtual bool Copyable() const
Definition: disti_metadata.h:534
virtual double ValueFloat()
Definition: disti_metadata.h:554
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:902
DistiAttribute(CallbackMethodCallerBase *callback, const AttributeName &name, T *attribPtr)
Definition: disti_metadata.h:496
virtual void CallCallback()
virtual bool operator==(const DistiAttributeBase &rArg)
Definition: disti_metadata.h:616
virtual bool OkToWrite() const
int _precision
Definition: disti_metadata.h:487
virtual std::ostream & WriteValue(const AttributeName &name, std::ostream &outstr)
Definition: disti_metadata.h:356
DistiAttribDict & operator=(const DistiAttribDict &old_class)
virtual void Add(DistiAttributeBase *attr)
T * _attribPtr
Definition: disti_metadata.h:485
Definition: gls_mutex.h:53
Definition: disti_metadata.h:481
virtual bool IsValid() const
Definition: disti_metadata.h:424
#define GLS_VERIFY(exp)
Definition: disti_assert.h:148
virtual std::istream & ReadValue(std::istream &instr)
Definition: disti_metadata.h:996
virtual void ValueInt(long val)
Definition: disti_metadata.h:935
static void SpacingInc()
virtual void Remove(const AttributeName &name)
virtual T Value()
Definition: disti_metadata.h:604
Definition: disti_metadata.h:179
virtual std::string ValueString(const AttributeName &name) const
virtual long ValueInt()
Definition: disti_metadata.h:539
virtual void ValueInt(long val)
Definition: disti_metadata.h:546
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:369
Definition: disti_metadata.h:676
Definition: weak_referenceable_mixin.h:52
Definition: disti_metadata.h:890
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:466
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:392
virtual void ResetValueChanged()
virtual void Delete(const AttributeName &name)
virtual CallbackID RegisterObserver(AttributeObserver *observer)
Definition: disti_metadata.h:447
AttributeName _name
Definition: disti_metadata.h:185
bool ReadAndCaptureMissing(std::istream &instr, std::stringstream *missingStream)
long StringIndex() const
static void SpacingZero()
A smart pointer with unique ownership – poor man's std::unique_ptr.
DistiAttribute(CallbackMethodCallerBase *callback, const AttributeName &name, const T &initialValue)
Definition: disti_metadata.h:517
virtual void Value(const T &val)
Definition: disti_metadata.h:609
Definition: disti_metadata.h:882
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