| 1 | /* -*-c++-*- OpenSceneGraph - Copyright (C) 2011 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 OSG_VALUEOBJECT |
|---|
| 15 | #define OSG_VALUEOBJECT 1 |
|---|
| 16 | |
|---|
| 17 | #include <osg/Object> |
|---|
| 18 | #include <osg/UserDataContainer> |
|---|
| 19 | |
|---|
| 20 | namespace osg { |
|---|
| 21 | |
|---|
| 22 | // foward declare core OSG math classes |
|---|
| 23 | class Vec2f; |
|---|
| 24 | class Vec3f; |
|---|
| 25 | class Vec4f; |
|---|
| 26 | class Vec2d; |
|---|
| 27 | class Vec3d; |
|---|
| 28 | class Vec4d; |
|---|
| 29 | class Quat; |
|---|
| 30 | class Plane; |
|---|
| 31 | class Matrixf; |
|---|
| 32 | class Matrixd; |
|---|
| 33 | |
|---|
| 34 | class ValueObject : public Object |
|---|
| 35 | { |
|---|
| 36 | public: |
|---|
| 37 | |
|---|
| 38 | ValueObject() : Object(true) {} |
|---|
| 39 | ValueObject(const std::string& name) : Object(true) { setName(name); } |
|---|
| 40 | ValueObject(const ValueObject& rhs, const osg::CopyOp copyop=osg::CopyOp::SHALLOW_COPY): Object(rhs,copyop) {} |
|---|
| 41 | |
|---|
| 42 | META_Object(osg, ValueObject) |
|---|
| 43 | |
|---|
| 44 | class GetValueVisitor |
|---|
| 45 | { |
|---|
| 46 | public: |
|---|
| 47 | virtual void apply(bool value) {} |
|---|
| 48 | virtual void apply(char value) {} |
|---|
| 49 | virtual void apply(unsigned char value) {} |
|---|
| 50 | virtual void apply(short value) {} |
|---|
| 51 | virtual void apply(unsigned short value) {} |
|---|
| 52 | virtual void apply(int value) {} |
|---|
| 53 | virtual void apply(unsigned int value) {} |
|---|
| 54 | virtual void apply(float value) {} |
|---|
| 55 | virtual void apply(double value) {} |
|---|
| 56 | virtual void apply(const std::string& value) {} |
|---|
| 57 | virtual void apply(const osg::Vec2f& value) {} |
|---|
| 58 | virtual void apply(const osg::Vec3f& value) {} |
|---|
| 59 | virtual void apply(const osg::Vec4f& value) {} |
|---|
| 60 | virtual void apply(const osg::Vec2d& value) {} |
|---|
| 61 | virtual void apply(const osg::Vec3d& value) {} |
|---|
| 62 | virtual void apply(const osg::Vec4d& value) {} |
|---|
| 63 | virtual void apply(const osg::Quat& value) {} |
|---|
| 64 | virtual void apply(const osg::Plane& value) {} |
|---|
| 65 | virtual void apply(const osg::Matrixf& value) {} |
|---|
| 66 | virtual void apply(const osg::Matrixd& value) {} |
|---|
| 67 | }; |
|---|
| 68 | |
|---|
| 69 | class SetValueVisitor |
|---|
| 70 | { |
|---|
| 71 | public: |
|---|
| 72 | virtual void apply(bool& value) {} |
|---|
| 73 | virtual void apply(char& value) {} |
|---|
| 74 | virtual void apply(unsigned char& value) {} |
|---|
| 75 | virtual void apply(short& value) {} |
|---|
| 76 | virtual void apply(unsigned short& value) {} |
|---|
| 77 | virtual void apply(int& value) {} |
|---|
| 78 | virtual void apply(unsigned int& value) {} |
|---|
| 79 | virtual void apply(float& value) {} |
|---|
| 80 | virtual void apply(double& value) {} |
|---|
| 81 | virtual void apply(std::string& value) {} |
|---|
| 82 | virtual void apply(osg::Vec2f& value) {} |
|---|
| 83 | virtual void apply(osg::Vec3f& value) {} |
|---|
| 84 | virtual void apply(osg::Vec4f& value) {} |
|---|
| 85 | virtual void apply(osg::Vec2d& value) {} |
|---|
| 86 | virtual void apply(osg::Vec3d& value) {} |
|---|
| 87 | virtual void apply(osg::Vec4d& value) {} |
|---|
| 88 | virtual void apply(osg::Quat& value) {} |
|---|
| 89 | virtual void apply(osg::Plane& value) {} |
|---|
| 90 | virtual void apply(osg::Matrixf& value) {} |
|---|
| 91 | virtual void apply(osg::Matrixd& value) {} |
|---|
| 92 | }; |
|---|
| 93 | |
|---|
| 94 | virtual bool get(GetValueVisitor& gvv) const { return false; } |
|---|
| 95 | virtual bool set(SetValueVisitor& gvv) { return false; } |
|---|
| 96 | protected: |
|---|
| 97 | virtual ~ValueObject() {} |
|---|
| 98 | }; |
|---|
| 99 | |
|---|
| 100 | template< typename T > |
|---|
| 101 | struct ValueObjectClassNameTrait |
|---|
| 102 | { |
|---|
| 103 | static const char* className() { return "TemplateValueObject"; } |
|---|
| 104 | }; |
|---|
| 105 | |
|---|
| 106 | |
|---|
| 107 | template< typename T > |
|---|
| 108 | class TemplateValueObject : public ValueObject |
|---|
| 109 | { |
|---|
| 110 | public: |
|---|
| 111 | |
|---|
| 112 | TemplateValueObject(): |
|---|
| 113 | ValueObject(), |
|---|
| 114 | _value() {} |
|---|
| 115 | |
|---|
| 116 | TemplateValueObject(const std::string& name, const T& value) : |
|---|
| 117 | ValueObject(name), |
|---|
| 118 | _value(value) {} |
|---|
| 119 | |
|---|
| 120 | TemplateValueObject(const TemplateValueObject& rhs, const osg::CopyOp copyop=osg::CopyOp::SHALLOW_COPY) : |
|---|
| 121 | ValueObject(rhs,copyop), |
|---|
| 122 | _value(rhs._value) {} |
|---|
| 123 | |
|---|
| 124 | virtual Object* cloneType() const { return new TemplateValueObject(); } |
|---|
| 125 | virtual Object* clone(const CopyOp& copyop) const { return new TemplateValueObject(*this, copyop); } |
|---|
| 126 | virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const TemplateValueObject*>(obj)!=NULL; } |
|---|
| 127 | virtual const char* libraryName() const { return "osg"; } |
|---|
| 128 | virtual const char* className() const { return ValueObjectClassNameTrait<T>::className(); } |
|---|
| 129 | |
|---|
| 130 | void setValue(const T& value) { _value = value; } |
|---|
| 131 | const T& getValue() const { return _value; } |
|---|
| 132 | |
|---|
| 133 | virtual bool get(GetValueVisitor& gvv) const { gvv.apply(_value); return true; } |
|---|
| 134 | virtual bool set(SetValueVisitor& svv) { svv.apply(_value); return true; } |
|---|
| 135 | |
|---|
| 136 | protected: |
|---|
| 137 | |
|---|
| 138 | virtual ~TemplateValueObject() {} |
|---|
| 139 | static const char* s_TemplateValueObject_className; |
|---|
| 140 | |
|---|
| 141 | T _value; |
|---|
| 142 | }; |
|---|
| 143 | |
|---|
| 144 | #define META_ValueObject(TYPE,NAME) \ |
|---|
| 145 | template<> struct ValueObjectClassNameTrait<TYPE> { static const char* className() { return #NAME; } }; \ |
|---|
| 146 | typedef TemplateValueObject<TYPE> NAME; |
|---|
| 147 | |
|---|
| 148 | META_ValueObject(std::string, StringValueObject) |
|---|
| 149 | META_ValueObject(bool, BoolValueObject) |
|---|
| 150 | META_ValueObject(char, CharValueObject) |
|---|
| 151 | META_ValueObject(unsigned char, UCharValueObject) |
|---|
| 152 | META_ValueObject(short, ShortValueObject) |
|---|
| 153 | META_ValueObject(unsigned short, UShortValueObject) |
|---|
| 154 | META_ValueObject(int, IntValueObject) |
|---|
| 155 | META_ValueObject(unsigned int, UIntValueObject) |
|---|
| 156 | META_ValueObject(float, FloatValueObject) |
|---|
| 157 | META_ValueObject(double, DoubleValueObject) |
|---|
| 158 | META_ValueObject(Vec2f, Vec2fValueObject) |
|---|
| 159 | META_ValueObject(Vec3f, Vec3fValueObject) |
|---|
| 160 | META_ValueObject(Vec4f, Vec4fValueObject) |
|---|
| 161 | META_ValueObject(Vec2d, Vec2dValueObject) |
|---|
| 162 | META_ValueObject(Vec3d, Vec3dValueObject) |
|---|
| 163 | META_ValueObject(Vec4d, Vec4dValueObject) |
|---|
| 164 | META_ValueObject(Quat, QuatValueObject) |
|---|
| 165 | META_ValueObject(Plane, PlaneValueObject) |
|---|
| 166 | META_ValueObject(Matrixf, MatrixfValueObject) |
|---|
| 167 | META_ValueObject(Matrixd, MatrixdValueObject) |
|---|
| 168 | |
|---|
| 169 | /** provide implementation of osg::Object::getUserValue(..) template*/ |
|---|
| 170 | template<typename T> |
|---|
| 171 | bool osg::Object::getUserValue(const std::string& name, T& value) const |
|---|
| 172 | { |
|---|
| 173 | typedef TemplateValueObject<T> UserValueObject; |
|---|
| 174 | |
|---|
| 175 | const osg::UserDataContainer* udc = dynamic_cast<const osg::UserDataContainer*>(this); |
|---|
| 176 | if (!udc) udc = _userDataContainer; |
|---|
| 177 | |
|---|
| 178 | const UserValueObject* uvo = udc ? dynamic_cast<const UserValueObject*>(udc->getUserObject(name)) : 0; |
|---|
| 179 | if (uvo) |
|---|
| 180 | { |
|---|
| 181 | value = uvo->getValue(); |
|---|
| 182 | return true; |
|---|
| 183 | } |
|---|
| 184 | else |
|---|
| 185 | { |
|---|
| 186 | return false; |
|---|
| 187 | } |
|---|
| 188 | } |
|---|
| 189 | |
|---|
| 190 | /** provide implementation of osg::Object::setUserValue(..) template.*/ |
|---|
| 191 | template<typename T> |
|---|
| 192 | void osg::Object::setUserValue(const std::string& name, const T& value) |
|---|
| 193 | { |
|---|
| 194 | typedef TemplateValueObject<T> UserValueObject; |
|---|
| 195 | |
|---|
| 196 | osg::UserDataContainer* udc = dynamic_cast<osg::UserDataContainer*>(this); |
|---|
| 197 | if (!udc) |
|---|
| 198 | { |
|---|
| 199 | getOrCreateUserDataContainer(); |
|---|
| 200 | udc = _userDataContainer; |
|---|
| 201 | } |
|---|
| 202 | |
|---|
| 203 | unsigned int i = udc->getUserObjectIndex(name); |
|---|
| 204 | if (i<udc->getNumUserObjects()) udc->setUserObject(i, new UserValueObject(name,value)); |
|---|
| 205 | else udc->addUserObject(new UserValueObject(name,value)); |
|---|
| 206 | } |
|---|
| 207 | |
|---|
| 208 | } |
|---|
| 209 | #endif |
|---|
| 210 | |
|---|