PropertyManager 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2018 Robert Osfield
  2. *
  3. * This library is open source and may be redistributed and/or modified under
  4. * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
  5. * (at your option) any later version. The full license is in LICENSE file
  6. * included with this distribution, and on the openscenegraph.org website.
  7. *
  8. * This library is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * OpenSceneGraph Public License for more details.
  12. */
  13. #ifndef PROPERTYMANAGER
  14. #define PROPERTYMANAGER 1
  15. #include <osg/UserDataContainer>
  16. #include <osg/ValueObject>
  17. #include <osg/ImageSequence>
  18. #include <osgGA/GUIEventHandler>
  19. #include <osgPresentation/Export>
  20. #include <sstream>
  21. namespace osgPresentation
  22. {
  23. class PropertyManager : protected osg::Object
  24. {
  25. public:
  26. PropertyManager() {}
  27. PropertyManager(const PropertyManager& pm, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
  28. osg::Object(pm,copyop) {}
  29. META_Object(osgPresentation, PropertyManager)
  30. /** Convenience method that casts the named UserObject to osg::TemplateValueObject<T> and gets the value.
  31. * To use this template method you need to include the osg/ValueObject header.*/
  32. template<typename T>
  33. bool getProperty(const std::string& name, T& value) const
  34. {
  35. OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
  36. return getUserValue(name, value);
  37. }
  38. /** Convenience method that creates the osg::TemplateValueObject<T> to store the
  39. * specified value and adds it as a named UserObject.
  40. * To use this template method you need to include the osg/ValueObject header. */
  41. template<typename T>
  42. void setProperty(const std::string& name, const T& value)
  43. {
  44. OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
  45. return setUserValue(name, value);
  46. }
  47. int ref() const { return osg::Referenced::ref(); }
  48. int unref() const { return osg::Referenced::unref(); }
  49. protected:
  50. mutable OpenThreads::Mutex _mutex;
  51. };
  52. extern OSGPRESENTATION_EXPORT const osg::Object* getUserObject(const osg::NodePath& nodepath, const std::string& name);
  53. template<typename T>
  54. bool getUserValue(const osg::NodePath& nodepath, const std::string& name, T& value)
  55. {
  56. typedef osg::TemplateValueObject<T> UserValueObject;
  57. const osg::Object* object = getUserObject(nodepath, name);
  58. const UserValueObject* uvo = dynamic_cast<const UserValueObject*>(object);
  59. if (uvo)
  60. {
  61. value = uvo->getValue();
  62. return true;
  63. }
  64. else
  65. {
  66. return false;
  67. }
  68. }
  69. extern OSGPRESENTATION_EXPORT bool containsPropertyReference(const std::string& str);
  70. struct PropertyReader
  71. {
  72. PropertyReader(const osg::NodePath& nodePath, const std::string& str):
  73. _errorGenerated(false),
  74. _nodePath(nodePath),
  75. _sstream(str) {}
  76. template<typename T>
  77. bool read(T& value)
  78. {
  79. // skip white space.
  80. while(!_sstream.fail() && _sstream.peek()==' ') _sstream.ignore();
  81. // check to see if a &propertyName is used.
  82. if (_sstream.peek()=='$')
  83. {
  84. std::string propertyName;
  85. _sstream.ignore(1);
  86. _sstream >> propertyName;
  87. OSG_NOTICE<<"Reading propertyName="<<propertyName<<std::endl;
  88. if (!_sstream.fail() && !propertyName.empty()) return getUserValue(_nodePath, propertyName, value);
  89. else return false;
  90. }
  91. else
  92. {
  93. _sstream >> value;
  94. OSG_NOTICE<<"Reading value="<<value<<std::endl;
  95. return !_sstream.fail();
  96. }
  97. }
  98. template<typename T>
  99. PropertyReader& operator>>( T& value ) { if (!read(value)) _errorGenerated=true; return *this; }
  100. bool ok() { return !_sstream.fail() && !_errorGenerated; }
  101. bool fail() { return _sstream.fail() || _errorGenerated; }
  102. bool _errorGenerated;
  103. osg::NodePath _nodePath;
  104. std::istringstream _sstream;
  105. };
  106. class OSGPRESENTATION_EXPORT PropertyAnimation : public osg::NodeCallback
  107. {
  108. public:
  109. PropertyAnimation():
  110. _firstTime(DBL_MAX),
  111. _latestTime(0.0),
  112. _pause(false),
  113. _pauseTime(0.0) {}
  114. void setPropertyManager(PropertyManager* pm) { _pm = pm; }
  115. PropertyManager* getPropertyManager() const { return _pm.get(); }
  116. typedef std::map<double, osg::ref_ptr<osg::UserDataContainer> > KeyFrameMap;
  117. KeyFrameMap& getKeyFrameMap() { return _keyFrameMap; }
  118. const KeyFrameMap& getKeyFrameMap() const { return _keyFrameMap; }
  119. void addKeyFrame(double time, osg::UserDataContainer* udc)
  120. {
  121. _keyFrameMap[time] = udc;
  122. }
  123. virtual void reset();
  124. void setPause(bool pause);
  125. bool getPause() const { return _pause; }
  126. double getAnimationTime() const;
  127. virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
  128. virtual void update(osg::Node& node);
  129. protected:
  130. osg::ref_ptr<PropertyManager> _pm;
  131. void assign(osg::UserDataContainer* destination, osg::UserDataContainer* source);
  132. void assign(osg::UserDataContainer* udc, osg::Object* obj);
  133. KeyFrameMap _keyFrameMap;
  134. double _firstTime;
  135. double _latestTime;
  136. bool _pause;
  137. double _pauseTime;
  138. };
  139. struct OSGPRESENTATION_EXPORT ImageSequenceUpdateCallback : public osg::NodeCallback
  140. {
  141. ImageSequenceUpdateCallback(osg::ImageSequence* is, PropertyManager* pm, const std::string& propertyName):
  142. _imageSequence(is),
  143. _propertyManager(pm),
  144. _propertyName(propertyName) {}
  145. virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
  146. osg::ref_ptr<osg::ImageSequence> _imageSequence;
  147. osg::ref_ptr<PropertyManager> _propertyManager;
  148. std::string _propertyName;
  149. };
  150. struct OSGPRESENTATION_EXPORT PropertyEventCallback : public osgGA::GUIEventHandler
  151. {
  152. PropertyEventCallback(PropertyManager* pm):
  153. _propertyManager(pm) {}
  154. virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&);
  155. osg::ref_ptr<PropertyManager> _propertyManager;
  156. };
  157. }
  158. #endif