ObjectWrapper 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 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. // Written by Wang Rui, (C) 2010
  14. #ifndef OSGDB_OBJECTWRAPPER
  15. #define OSGDB_OBJECTWRAPPER
  16. #include <OpenThreads/ReentrantMutex>
  17. #include <osgDB/Serializer>
  18. #include <osg/ScriptEngine>
  19. namespace osgDB
  20. {
  21. struct MethodObject : public osg::Referenced
  22. {
  23. typedef std::vector< osg::ref_ptr<osg::Object> > Parameters;
  24. virtual bool run(void* objectPtr, osg::Parameters& inputParameters, osg::Parameters& outputParameters) const = 0;
  25. virtual ~MethodObject() {}
  26. };
  27. class OSGDB_EXPORT BaseCompressor : public osg::Referenced
  28. {
  29. public:
  30. BaseCompressor() {}
  31. void setName( const std::string& name ) { _name = name; }
  32. const std::string& getName() const { return _name; }
  33. virtual bool compress( std::ostream&, const std::string& ) = 0;
  34. virtual bool decompress( std::istream&, std::string& ) = 0;
  35. protected:
  36. std::string _name;
  37. };
  38. struct FinishedObjectReadCallback : public osg::Referenced
  39. {
  40. virtual void objectRead(osgDB::InputStream& is, osg::Object& obj) = 0;
  41. };
  42. struct OSGDB_EXPORT ObjectWrapperAssociate
  43. {
  44. ObjectWrapperAssociate(std::string name):_firstVersion(0),_lastVersion(INT_MAX),_name(name){}
  45. int _firstVersion;
  46. int _lastVersion;
  47. std::string _name;
  48. };
  49. class OSGDB_EXPORT ObjectWrapper : public osg::Referenced
  50. {
  51. public:
  52. typedef std::vector< BaseSerializer::Type > TypeList;
  53. typedef std::vector< osg::ref_ptr<BaseSerializer> > SerializerList;
  54. typedef std::vector< osg::ref_ptr<FinishedObjectReadCallback> > FinishedObjectReadCallbackList;
  55. typedef std::list<ObjectWrapperAssociate> RevisionAssociateList;
  56. typedef osg::Object* CreateInstanceFunc();
  57. ObjectWrapper( CreateInstanceFunc* createInstanceFunc, const std::string& name,
  58. const std::string& associates );
  59. ObjectWrapper( CreateInstanceFunc* createInstanceFunc, const std::string& domain, const std::string& name,
  60. const std::string& associates );
  61. void setUpdatedVersion( int ver ) { _version = ver; }
  62. int getUpdatedVersion() const { return _version; }
  63. osg::Object* createInstance() const { return _createInstanceFunc(); }
  64. const std::string& getDomain() const { return _domain; }
  65. const std::string& getName() const { return _name; }
  66. const RevisionAssociateList& getAssociates() const { return _associates; }
  67. SerializerList& getSerializerList() { return _serializers; }
  68. const SerializerList& getSerializerList() const { return _serializers; }
  69. TypeList& getTypeList() { return _typeList; }
  70. const TypeList& getTypeList() const { return _typeList; }
  71. void addSerializer( BaseSerializer* s, BaseSerializer::Type t=BaseSerializer::RW_UNDEFINED );
  72. void markSerializerAsRemoved( const std::string& name );
  73. void markAssociateAsRemoved(const std::string& name);
  74. void markAssociateAsAdded(const std::string& name);
  75. BaseSerializer* getLastSerializer() { return _serializers.empty() ? 0 : _serializers.back().get(); }
  76. BaseSerializer* getSerializer( const std::string& name );
  77. BaseSerializer* getSerializer( const std::string& name, BaseSerializer::Type& type);
  78. void addFinishedObjectReadCallback ( FinishedObjectReadCallback* forc) { _finishedObjectReadCallbacks.push_back(forc); }
  79. bool read( InputStream&, osg::Object& );
  80. bool write( OutputStream&, const osg::Object& );
  81. bool readSchema( const StringList& properties, const TypeList& types );
  82. void writeSchema( StringList& properties, TypeList& types );
  83. void resetSchema() { if ( _backupSerializers.size()>0 ) _serializers = _backupSerializers; }
  84. void addMethodObject(const std::string& methodName, MethodObject* mo);
  85. typedef std::multimap< std::string, osg::ref_ptr<MethodObject> > MethodObjectMap;
  86. MethodObjectMap& getMethodObjectMap() { return _methodObjectMap; }
  87. const MethodObjectMap& getMethodObjectMap() const { return _methodObjectMap; }
  88. void setupAssociatesRevisionsInheritanceIfRequired();
  89. protected:
  90. ObjectWrapper() : _version(0) {}
  91. virtual ~ObjectWrapper() {}
  92. CreateInstanceFunc* _createInstanceFunc;
  93. std::string _domain;
  94. std::string _name;
  95. RevisionAssociateList _associates;
  96. SerializerList _serializers;
  97. SerializerList _backupSerializers;
  98. TypeList _typeList;
  99. FinishedObjectReadCallbackList _finishedObjectReadCallbacks;
  100. MethodObjectMap _methodObjectMap;
  101. int _version; // Last updated version of the wrapper
  102. //simulate associate revisions inheritance
  103. bool _isAssociatesRevisionsInheritanceDone;
  104. static void splitAssociates( const std::string& src, ObjectWrapper::RevisionAssociateList& list, char separator=' ' );
  105. };
  106. struct UpdateWrapperVersionProxy
  107. {
  108. UpdateWrapperVersionProxy( ObjectWrapper* w, int v ): _wrapper(w)
  109. {
  110. _lastVersion = w->getUpdatedVersion();
  111. w->setUpdatedVersion(v);
  112. }
  113. ~UpdateWrapperVersionProxy()
  114. {
  115. _wrapper->setUpdatedVersion(_lastVersion);
  116. }
  117. ObjectWrapper* _wrapper;
  118. int _lastVersion;
  119. };
  120. class Registry;
  121. class OSGDB_EXPORT ObjectWrapperManager : public osg::Referenced
  122. {
  123. public:
  124. // Wrapper handlers
  125. void addWrapper( ObjectWrapper* wrapper );
  126. void removeWrapper( ObjectWrapper* wrapper );
  127. ObjectWrapper* findWrapper( const std::string& name );
  128. typedef std::map< std::string, osg::ref_ptr<ObjectWrapper> > WrapperMap;
  129. WrapperMap& getWrapperMap() { return _wrappers; }
  130. const WrapperMap& getWrapperMap() const { return _wrappers; }
  131. // Compressor handlers
  132. void addCompressor( BaseCompressor* compressor );
  133. void removeCompressor( BaseCompressor* compressor );
  134. BaseCompressor* findCompressor( const std::string& name );
  135. typedef std::map< std::string, osg::ref_ptr<BaseCompressor> > CompressorMap;
  136. CompressorMap& getCompressorMap() { return _compressors; }
  137. const CompressorMap& getCompressorMap() const { return _compressors; }
  138. typedef std::map<std::string, IntLookup> IntLookupMap;
  139. IntLookup::Value getValue( const std::string& group, const std::string& str ) { return findLookup(group).getValue(str.c_str()); }
  140. const std::string& getString( const std::string& group, IntLookup::Value value ) { return findLookup(group).getString(value); }
  141. IntLookupMap& getLookupMap() { return _globalMap; }
  142. const IntLookupMap& getLookupMap() const { return _globalMap; }
  143. protected:
  144. friend class osgDB::Registry;
  145. ObjectWrapperManager();
  146. virtual ~ObjectWrapperManager();
  147. OpenThreads::ReentrantMutex _wrapperMutex;
  148. WrapperMap _wrappers;
  149. CompressorMap _compressors;
  150. IntLookup& findLookup( const std::string& group )
  151. {
  152. IntLookupMap::iterator itr = _globalMap.find(group);
  153. if ( itr!=_globalMap.end() ) return itr->second;
  154. else return _globalMap["GL"];
  155. }
  156. IntLookupMap _globalMap;
  157. };
  158. class OSGDB_EXPORT RegisterWrapperProxy
  159. {
  160. public:
  161. typedef void (*AddPropFunc)( ObjectWrapper* );
  162. RegisterWrapperProxy( ObjectWrapper::CreateInstanceFunc *createInstanceFunc, const std::string& name,
  163. const std::string& associates, AddPropFunc func );
  164. virtual ~RegisterWrapperProxy();
  165. protected:
  166. osg::ref_ptr<ObjectWrapper> _wrapper;
  167. };
  168. class OSGDB_EXPORT RegisterCustomWrapperProxy
  169. {
  170. public:
  171. typedef void (*AddPropFunc)( const char*, ObjectWrapper* );
  172. RegisterCustomWrapperProxy( ObjectWrapper::CreateInstanceFunc *createInstanceFunc, const std::string& domain, const std::string& name,
  173. const std::string& associates, AddPropFunc func );
  174. virtual ~RegisterCustomWrapperProxy();
  175. protected:
  176. osg::ref_ptr<ObjectWrapper> _wrapper;
  177. };
  178. #define REGISTER_OBJECT_WRAPPER(NAME, CREATEINSTANCE, CLASS, ASSOCIATES) \
  179. extern "C" void wrapper_serializer_##NAME(void) {} \
  180. extern void wrapper_propfunc_##NAME(osgDB::ObjectWrapper*); \
  181. static osg::Object* wrapper_createinstancefunc##NAME() { return CREATEINSTANCE; } \
  182. static osgDB::RegisterWrapperProxy wrapper_proxy_##NAME( \
  183. wrapper_createinstancefunc##NAME, #CLASS, ASSOCIATES, &wrapper_propfunc_##NAME); \
  184. typedef CLASS MyClass; \
  185. void wrapper_propfunc_##NAME(osgDB::ObjectWrapper* wrapper)
  186. #define REGISTER_OBJECT_WRAPPER2(NAME, CREATEINSTANCE, CLASS, CLASSNAME, ASSOCIATES) \
  187. extern "C" void wrapper_serializer_##NAME(void) {} \
  188. extern void wrapper_propfunc_##NAME(osgDB::ObjectWrapper*); \
  189. static osg::Object* wrapper_createinstancefunc##NAME() { return CREATEINSTANCE; } \
  190. static osgDB::RegisterWrapperProxy wrapper_proxy_##NAME( \
  191. wrapper_createinstancefunc##NAME, CLASSNAME, ASSOCIATES, &wrapper_propfunc_##NAME); \
  192. typedef CLASS MyClass; \
  193. void wrapper_propfunc_##NAME(osgDB::ObjectWrapper* wrapper)
  194. #define REGISTER_CUSTOM_OBJECT_WRAPPER(DOMAIN, NAME, CREATEINSTANCE, CLASS, ASSOCIATES) \
  195. extern "C" void wrapper_serializer_##NAME(void) {} \
  196. extern void wrapper_propfunc_##NAME(const char*, osgDB::ObjectWrapper*); \
  197. static osg::Object* wrapper_createinstancefunc##NAME() { return CREATEINSTANCE; } \
  198. static osgDB::RegisterCustomWrapperProxy wrapper_proxy_##NAME( \
  199. wrapper_createinstancefunc##NAME, #DOMAIN, #CLASS, ASSOCIATES, &wrapper_propfunc_##NAME); \
  200. typedef CLASS MyClass; \
  201. void wrapper_propfunc_##NAME(const char* domain, osgDB::ObjectWrapper* wrapper)
  202. #define REGISTER_CUSTOM_OBJECT_WRAPPER2(DOMAIN, NAME, CREATEINSTANCE, CLASS, CLASSNAME, ASSOCIATES) \
  203. extern "C" void wrapper_serializer_##NAME(void) {} \
  204. extern void wrapper_propfunc_##NAME(const char*, osgDB::ObjectWrapper*); \
  205. static osg::Object* wrapper_createinstancefunc##NAME() { return CREATEINSTANCE; } \
  206. static osgDB::RegisterCustomWrapperProxy wrapper_proxy_##NAME( \
  207. wrapper_createinstancefunc##NAME, #DOMAIN, CLASSNAME, ASSOCIATES, &wrapper_propfunc_##NAME); \
  208. typedef CLASS MyClass; \
  209. void wrapper_propfunc_##NAME(const char* domain, osgDB::ObjectWrapper* wrapper)
  210. class OSGDB_EXPORT RegisterCompressorProxy
  211. {
  212. public:
  213. RegisterCompressorProxy( const std::string& name, BaseCompressor* compressor );
  214. ~RegisterCompressorProxy();
  215. protected:
  216. osg::ref_ptr<BaseCompressor> _compressor;
  217. };
  218. #define REGISTER_COMPRESSOR(NAME, CLASS) \
  219. extern "C" void wrapper_compressor_##CLASS(void) {} \
  220. static osgDB::RegisterCompressorProxy compressor_proxy_##CLASS(NAME, new CLASS);
  221. }
  222. #endif