1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 Robert Osfield
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.
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.
13// Written by Wang Rui, (C) 2010
15#ifndef OSGDB_OBJECTWRAPPER
16#define OSGDB_OBJECTWRAPPER
18#include <OpenThreads/ReentrantMutex>
19#include <osgDB/Serializer>
20#include <osg/ScriptEngine>
25struct MethodObject : public osg::Referenced
27 typedef std::vector< osg::ref_ptr<osg::Object> > Parameters;
29 virtual bool run(void* objectPtr, osg::Parameters& inputParameters, osg::Parameters& outputParameters) const = 0;
31 virtual ~MethodObject() {}
34class OSGDB_EXPORT BaseCompressor : public osg::Referenced
38 void setName( const std::string& name ) { _name = name; }
39 const std::string& getName() const { return _name; }
41 virtual bool compress( std::ostream&, const std::string& ) = 0;
42 virtual bool decompress( std::istream&, std::string& ) = 0;
48struct FinishedObjectReadCallback : public osg::Referenced
50 virtual void objectRead(osgDB::InputStream& is, osg::Object& obj) = 0;
53struct OSGDB_EXPORT ObjectWrapperAssociate
55 ObjectWrapperAssociate(std::string name):_firstVersion(0),_lastVersion(INT_MAX),_name(name){}
61class OSGDB_EXPORT ObjectWrapper : public osg::Referenced
64 typedef std::vector< BaseSerializer::Type > TypeList;
65 typedef std::vector< osg::ref_ptr<BaseSerializer> > SerializerList;
66 typedef std::vector< osg::ref_ptr<FinishedObjectReadCallback> > FinishedObjectReadCallbackList;
67 typedef std::list<ObjectWrapperAssociate> RevisionAssociateList;
68 typedef osg::Object* CreateInstanceFunc();
70 ObjectWrapper( CreateInstanceFunc* createInstanceFunc, const std::string& name,
71 const std::string& associates );
72 ObjectWrapper( CreateInstanceFunc* createInstanceFunc, const std::string& domain, const std::string& name,
73 const std::string& associates );
75 void setUpdatedVersion( int ver ) { _version = ver; }
76 int getUpdatedVersion() const { return _version; }
78 osg::Object* createInstance() const { return _createInstanceFunc(); }
79 const std::string& getDomain() const { return _domain; }
80 const std::string& getName() const { return _name; }
82 const RevisionAssociateList& getAssociates() const { return _associates; }
84 SerializerList& getSerializerList() { return _serializers; }
85 const SerializerList& getSerializerList() const { return _serializers; }
87 TypeList& getTypeList() { return _typeList; }
88 const TypeList& getTypeList() const { return _typeList; }
90 void addSerializer( BaseSerializer* s, BaseSerializer::Type t=BaseSerializer::RW_UNDEFINED );
91 void markSerializerAsRemoved( const std::string& name );
93 void markAssociateAsRemoved(const std::string& name);
94 void markAssociateAsAdded(const std::string& name);
96 BaseSerializer* getLastSerializer() { return _serializers.empty() ? 0 : _serializers.back().get(); }
97 BaseSerializer* getSerializer( const std::string& name );
98 BaseSerializer* getSerializer( const std::string& name, BaseSerializer::Type& type);
100 void addFinishedObjectReadCallback ( FinishedObjectReadCallback* forc) { _finishedObjectReadCallbacks.push_back(forc); }
102 bool read( InputStream&, osg::Object& );
103 bool write( OutputStream&, const osg::Object& );
105 bool readSchema( const StringList& properties, const TypeList& types );
106 void writeSchema( StringList& properties, TypeList& types );
107 void resetSchema() { if ( _backupSerializers.size()>0 ) _serializers = _backupSerializers; }
109 void addMethodObject(const std::string& methodName, MethodObject* mo);
111 typedef std::multimap< std::string, osg::ref_ptr<MethodObject> > MethodObjectMap;
113 MethodObjectMap& getMethodObjectMap() { return _methodObjectMap; }
114 const MethodObjectMap& getMethodObjectMap() const { return _methodObjectMap; }
116 void setupAssociatesRevisionsInheritanceIfRequired();
119 ObjectWrapper() : _version(0) {}
120 virtual ~ObjectWrapper() {}
122 CreateInstanceFunc* _createInstanceFunc;
125 RevisionAssociateList _associates;
126 SerializerList _serializers;
127 SerializerList _backupSerializers;
129 FinishedObjectReadCallbackList _finishedObjectReadCallbacks;
130 MethodObjectMap _methodObjectMap;
131 int _version; // Last updated version of the wrapper
132 //simulate associate revisions inheritance
133 bool _isAssociatesRevisionsInheritanceDone;
134 static void splitAssociates( const std::string& src, ObjectWrapper::RevisionAssociateList& list, char separator=' ' );
137struct UpdateWrapperVersionProxy
139 UpdateWrapperVersionProxy( ObjectWrapper* w, int v ): _wrapper(w)
141 _lastVersion = w->getUpdatedVersion();
142 w->setUpdatedVersion(v);
145 ~UpdateWrapperVersionProxy()
147 _wrapper->setUpdatedVersion(_lastVersion);
150 ObjectWrapper* _wrapper;
156class OSGDB_EXPORT ObjectWrapperManager : public osg::Referenced
161 void addWrapper( ObjectWrapper* wrapper );
162 void removeWrapper( ObjectWrapper* wrapper );
163 ObjectWrapper* findWrapper( const std::string& name );
165 typedef std::map< std::string, osg::ref_ptr<ObjectWrapper> > WrapperMap;
166 WrapperMap& getWrapperMap() { return _wrappers; }
167 const WrapperMap& getWrapperMap() const { return _wrappers; }
169 // Compressor handlers
170 void addCompressor( BaseCompressor* compressor );
171 void removeCompressor( BaseCompressor* compressor );
172 BaseCompressor* findCompressor( const std::string& name );
174 typedef std::map< std::string, osg::ref_ptr<BaseCompressor> > CompressorMap;
175 CompressorMap& getCompressorMap() { return _compressors; }
176 const CompressorMap& getCompressorMap() const { return _compressors; }
178 typedef std::map<std::string, IntLookup> IntLookupMap;
179 IntLookup::Value getValue( const std::string& group, const std::string& str ) { return findLookup(group).getValue(str.c_str()); }
180 const std::string& getString( const std::string& group, IntLookup::Value value ) { return findLookup(group).getString(value); }
182 IntLookupMap& getLookupMap() { return _globalMap; }
183 const IntLookupMap& getLookupMap() const { return _globalMap; }
187 friend class osgDB::Registry;
189 ObjectWrapperManager();
190 virtual ~ObjectWrapperManager();
192 OpenThreads::ReentrantMutex _wrapperMutex;
194 WrapperMap _wrappers;
195 CompressorMap _compressors;
197 IntLookup& findLookup( const std::string& group )
199 IntLookupMap::iterator itr = _globalMap.find(group);
200 if ( itr!=_globalMap.end() ) return itr->second;
201 else return _globalMap["GL"];
204 IntLookupMap _globalMap;
208class OSGDB_EXPORT RegisterWrapperProxy
211 typedef void (*AddPropFunc)( ObjectWrapper* );
213 RegisterWrapperProxy( ObjectWrapper::CreateInstanceFunc *createInstanceFunc, const std::string& name,
214 const std::string& associates, AddPropFunc func );
216 virtual ~RegisterWrapperProxy();
219 osg::ref_ptr<ObjectWrapper> _wrapper;
222class OSGDB_EXPORT RegisterCustomWrapperProxy
225 typedef void (*AddPropFunc)( const char*, ObjectWrapper* );
227 RegisterCustomWrapperProxy( ObjectWrapper::CreateInstanceFunc *createInstanceFunc, const std::string& domain, const std::string& name,
228 const std::string& associates, AddPropFunc func );
230 virtual ~RegisterCustomWrapperProxy();
233 osg::ref_ptr<ObjectWrapper> _wrapper;
236#define REGISTER_OBJECT_WRAPPER(NAME, CREATEINSTANCE, CLASS, ASSOCIATES) \
237 extern "C" void wrapper_serializer_##NAME(void) {} \
238 extern void wrapper_propfunc_##NAME(osgDB::ObjectWrapper*); \
239 static osg::Object* wrapper_createinstancefunc##NAME() { return CREATEINSTANCE; } \
240 static osgDB::RegisterWrapperProxy wrapper_proxy_##NAME( \
241 wrapper_createinstancefunc##NAME, #CLASS, ASSOCIATES, &wrapper_propfunc_##NAME); \
242 typedef CLASS MyClass; \
243 void wrapper_propfunc_##NAME(osgDB::ObjectWrapper* wrapper)
245#define REGISTER_OBJECT_WRAPPER2(NAME, CREATEINSTANCE, CLASS, CLASSNAME, ASSOCIATES) \
246 extern "C" void wrapper_serializer_##NAME(void) {} \
247 extern void wrapper_propfunc_##NAME(osgDB::ObjectWrapper*); \
248 static osg::Object* wrapper_createinstancefunc##NAME() { return CREATEINSTANCE; } \
249 static osgDB::RegisterWrapperProxy wrapper_proxy_##NAME( \
250 wrapper_createinstancefunc##NAME, CLASSNAME, ASSOCIATES, &wrapper_propfunc_##NAME); \
251 typedef CLASS MyClass; \
252 void wrapper_propfunc_##NAME(osgDB::ObjectWrapper* wrapper)
254#define REGISTER_CUSTOM_OBJECT_WRAPPER(DOMAIN, NAME, CREATEINSTANCE, CLASS, ASSOCIATES) \
255 extern "C" void wrapper_serializer_##NAME(void) {} \
256 extern void wrapper_propfunc_##NAME(const char*, osgDB::ObjectWrapper*); \
257 static osg::Object* wrapper_createinstancefunc##NAME() { return CREATEINSTANCE; } \
258 static osgDB::RegisterCustomWrapperProxy wrapper_proxy_##NAME( \
259 wrapper_createinstancefunc##NAME, #DOMAIN, #CLASS, ASSOCIATES, &wrapper_propfunc_##NAME); \
260 typedef CLASS MyClass; \
261 void wrapper_propfunc_##NAME(const char* domain, osgDB::ObjectWrapper* wrapper)
263#define REGISTER_CUSTOM_OBJECT_WRAPPER2(DOMAIN, NAME, CREATEINSTANCE, CLASS, CLASSNAME, ASSOCIATES) \
264 extern "C" void wrapper_serializer_##NAME(void) {} \
265 extern void wrapper_propfunc_##NAME(const char*, osgDB::ObjectWrapper*); \
266 static osg::Object* wrapper_createinstancefunc##NAME() { return CREATEINSTANCE; } \
267 static osgDB::RegisterCustomWrapperProxy wrapper_proxy_##NAME( \
268 wrapper_createinstancefunc##NAME, #DOMAIN, CLASSNAME, ASSOCIATES, &wrapper_propfunc_##NAME); \
269 typedef CLASS MyClass; \
270 void wrapper_propfunc_##NAME(const char* domain, osgDB::ObjectWrapper* wrapper)
272class OSGDB_EXPORT RegisterCompressorProxy
275 RegisterCompressorProxy( const std::string& name, BaseCompressor* compressor );
276 ~RegisterCompressorProxy();
279 osg::ref_ptr<BaseCompressor> _compressor;
282#define REGISTER_COMPRESSOR(NAME, CLASS) \
283 extern "C" void wrapper_compressor_##CLASS(void) {} \
284 static osgDB::RegisterCompressorProxy compressor_proxy_##CLASS(NAME, new CLASS);