openscenegraph
PropertyManager
Go to the documentation of this file.
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
14#ifndef PROPERTYMANAGER
15#define PROPERTYMANAGER 1
16
17#include <osg/UserDataContainer>
18#include <osg/ValueObject>
19#include <osg/ImageSequence>
20#include <osgGA/GUIEventHandler>
21
22#include <osgPresentation/Export>
23
24#include <sstream>
25
26namespace osgPresentation
27{
28
29class PropertyManager : protected osg::Object
30{
31public:
32
33 PropertyManager() {}
34 PropertyManager(const PropertyManager& pm, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
35 osg::Object(pm,copyop) {}
36
37 META_Object(osgPresentation, PropertyManager)
38
39 /** Convenience method that casts the named UserObject to osg::TemplateValueObject<T> and gets the value.
40 * To use this template method you need to include the osg/ValueObject header.*/
41 template<typename T>
42 bool getProperty(const std::string& name, T& value) const
43 {
44 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
45 return getUserValue(name, value);
46 }
47
48 /** Convenience method that creates the osg::TemplateValueObject<T> to store the
49 * specified value and adds it as a named UserObject.
50 * To use this template method you need to include the osg/ValueObject header. */
51 template<typename T>
52 void setProperty(const std::string& name, const T& value)
53 {
54 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
55 return setUserValue(name, value);
56 }
57
58 int ref() const { return osg::Referenced::ref(); }
59 int unref() const { return osg::Referenced::unref(); }
60
61protected:
62
63 mutable OpenThreads::Mutex _mutex;
64
65};
66
67extern OSGPRESENTATION_EXPORT const osg::Object* getUserObject(const osg::NodePath& nodepath, const std::string& name);
68
69template<typename T>
70bool getUserValue(const osg::NodePath& nodepath, const std::string& name, T& value)
71{
72 typedef osg::TemplateValueObject<T> UserValueObject;
73 const osg::Object* object = getUserObject(nodepath, name);
74 const UserValueObject* uvo = dynamic_cast<const UserValueObject*>(object);
75
76 if (uvo)
77 {
78 value = uvo->getValue();
79 return true;
80 }
81 else
82 {
83 return false;
84 }
85}
86
87extern OSGPRESENTATION_EXPORT bool containsPropertyReference(const std::string& str);
88
89struct PropertyReader
90{
91 PropertyReader(const osg::NodePath& nodePath, const std::string& str):
92 _errorGenerated(false),
93 _nodePath(nodePath),
94 _sstream(str) {}
95
96 template<typename T>
97 bool read(T& value)
98 {
99 // skip white space.
100 while(!_sstream.fail() && _sstream.peek()==' ') _sstream.ignore();
101
102 // check to see if a &propertyName is used.
103 if (_sstream.peek()=='$')
104 {
105 std::string propertyName;
106 _sstream.ignore(1);
107 _sstream >> propertyName;
108 OSG_NOTICE<<"Reading propertyName="<<propertyName<<std::endl;
109 if (!_sstream.fail() && !propertyName.empty()) return getUserValue(_nodePath, propertyName, value);
110 else return false;
111 }
112 else
113 {
114 _sstream >> value;
115 OSG_NOTICE<<"Reading value="<<value<<std::endl;
116 return !_sstream.fail();
117 }
118 }
119
120 template<typename T>
121 PropertyReader& operator>>( T& value ) { if (!read(value)) _errorGenerated=true; return *this; }
122
123 bool ok() { return !_sstream.fail() && !_errorGenerated; }
124 bool fail() { return _sstream.fail() || _errorGenerated; }
125
126 bool _errorGenerated;
127 osg::NodePath _nodePath;
128 std::istringstream _sstream;
129};
130
131
132class OSGPRESENTATION_EXPORT PropertyAnimation : public osg::NodeCallback
133{
134public:
135 PropertyAnimation():
136 _firstTime(DBL_MAX),
137 _latestTime(0.0),
138 _pause(false),
139 _pauseTime(0.0) {}
140
141 void setPropertyManager(PropertyManager* pm) { _pm = pm; }
142 PropertyManager* getPropertyManager() const { return _pm.get(); }
143
144 typedef std::map<double, osg::ref_ptr<osg::UserDataContainer> > KeyFrameMap;
145
146 KeyFrameMap& getKeyFrameMap() { return _keyFrameMap; }
147 const KeyFrameMap& getKeyFrameMap() const { return _keyFrameMap; }
148
149 void addKeyFrame(double time, osg::UserDataContainer* udc)
150 {
151 _keyFrameMap[time] = udc;
152 }
153
154 virtual void reset();
155
156 void setPause(bool pause);
157 bool getPause() const { return _pause; }
158
159 double getAnimationTime() const;
160
161 virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
162
163 virtual void update(osg::Node& node);
164
165
166protected:
167
168 osg::ref_ptr<PropertyManager> _pm;
169
170 void assign(osg::UserDataContainer* destination, osg::UserDataContainer* source);
171 void assign(osg::UserDataContainer* udc, osg::Object* obj);
172
173 KeyFrameMap _keyFrameMap;
174
175 double _firstTime;
176 double _latestTime;
177 bool _pause;
178 double _pauseTime;
179
180};
181
182
183
184struct OSGPRESENTATION_EXPORT ImageSequenceUpdateCallback : public osg::NodeCallback
185{
186 ImageSequenceUpdateCallback(osg::ImageSequence* is, PropertyManager* pm, const std::string& propertyName):
187 _imageSequence(is),
188 _propertyManager(pm),
189 _propertyName(propertyName) {}
190
191 virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
192
193 osg::ref_ptr<osg::ImageSequence> _imageSequence;
194 osg::ref_ptr<PropertyManager> _propertyManager;
195 std::string _propertyName;
196};
197
198struct OSGPRESENTATION_EXPORT PropertyEventCallback : public osgGA::GUIEventHandler
199{
200 PropertyEventCallback(PropertyManager* pm):
201 _propertyManager(pm) {}
202
203 virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&);
204
205 osg::ref_ptr<PropertyManager> _propertyManager;
206};
207
208}
209
210#endif