From 69f2fb56b343a6cfe14fd4a22d1ce1d1e713d4a2 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 2 Oct 2013 13:59:00 +0000 Subject: [PATCH] From Colin McDonald and Robert Osfield, "When a serializer shared library is loaded it registers all of the wrappers it contains. The registration creates a prototype object for all of the wrapped classes. For some of the higher-level classes this can be a bit heavy. I noticed a problem with a model which required a single class from osgSim. When osgdb_serializers_osgsim.so was loaded it registered wrappers and created prototype objects for all of the osgSim classes, including osgSim::ScalarBar. The constructor for that class creates several drawables, and loads arial.ttf using the freetype plugin. I don't need that, and don't even ship the font or plugin with my application, resulting in an unexplained warning message loading the model. I've modified the ObjectWrapper class to defer the prototype object creation until if & when actually required." --- include/osgDB/ObjectWrapper | 33 +++++++++++++++++++-------------- src/osgDB/InputStream.cpp | 2 +- src/osgDB/ObjectWrapper.cpp | 16 ++++++++-------- 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/include/osgDB/ObjectWrapper b/include/osgDB/ObjectWrapper index 48438ee78..ee0f7f9ac 100644 --- a/include/osgDB/ObjectWrapper +++ b/include/osgDB/ObjectWrapper @@ -48,16 +48,17 @@ public: typedef std::vector< BaseSerializer::Type > TypeList; typedef std::vector< osg::ref_ptr > SerializerList; typedef std::vector< osg::ref_ptr > FinishedObjectReadCallbackList; + typedef osg::Object* CreateInstanceFunc(); - ObjectWrapper( osg::Object* proto, const std::string& name, + ObjectWrapper( CreateInstanceFunc* createInstanceFunc, const std::string& name, const std::string& associates ); - ObjectWrapper( osg::Object* proto, const std::string& domain, const std::string& name, + ObjectWrapper( CreateInstanceFunc* createInstanceFunc, const std::string& domain, const std::string& name, const std::string& associates ); void setUpdatedVersion( int ver ) { _version = ver; } int getUpdatedVersion() const { return _version; } - const osg::Object* getProto() const { return _proto.get(); } + osg::Object* createInstance() const { return _createInstanceFunc(); } const std::string& getDomain() const { return _domain; } const std::string& getName() const { return _name; } const StringList& getAssociates() const { return _associates; } @@ -87,7 +88,7 @@ protected: ObjectWrapper() : _version(0) {} virtual ~ObjectWrapper() {} - osg::ref_ptr _proto; + CreateInstanceFunc* _createInstanceFunc; std::string _domain; std::string _name; StringList _associates; @@ -172,7 +173,7 @@ class OSGDB_EXPORT RegisterWrapperProxy public: typedef void (*AddPropFunc)( ObjectWrapper* ); - RegisterWrapperProxy( osg::Object* proto, const std::string& name, + RegisterWrapperProxy( ObjectWrapper::CreateInstanceFunc *createInstanceFunc, const std::string& name, const std::string& associates, AddPropFunc func ); virtual ~RegisterWrapperProxy(); @@ -186,7 +187,7 @@ class OSGDB_EXPORT RegisterCustomWrapperProxy public: typedef void (*AddPropFunc)( const char*, ObjectWrapper* ); - RegisterCustomWrapperProxy( osg::Object* proto, const std::string& domain, const std::string& name, + RegisterCustomWrapperProxy( ObjectWrapper::CreateInstanceFunc *createInstanceFunc, const std::string& domain, const std::string& name, const std::string& associates, AddPropFunc func ); virtual ~RegisterCustomWrapperProxy(); @@ -195,35 +196,39 @@ protected: osg::ref_ptr _wrapper; }; -#define REGISTER_OBJECT_WRAPPER(NAME, PROTO, CLASS, ASSOCIATES) \ +#define REGISTER_OBJECT_WRAPPER(NAME, CREATEINSTANCE, CLASS, ASSOCIATES) \ extern "C" void wrapper_serializer_##NAME(void) {} \ extern void wrapper_propfunc_##NAME(osgDB::ObjectWrapper*); \ + static osg::Object* wrapper_createinstancefunc##NAME() { return CREATEINSTANCE; } \ static osgDB::RegisterWrapperProxy wrapper_proxy_##NAME( \ - PROTO, #CLASS, ASSOCIATES, &wrapper_propfunc_##NAME); \ + wrapper_createinstancefunc##NAME, #CLASS, ASSOCIATES, &wrapper_propfunc_##NAME); \ typedef CLASS MyClass; \ void wrapper_propfunc_##NAME(osgDB::ObjectWrapper* wrapper) -#define REGISTER_OBJECT_WRAPPER2(NAME, PROTO, CLASS, CLASSNAME, ASSOCIATES) \ +#define REGISTER_OBJECT_WRAPPER2(NAME, CREATEINSTANCE, CLASS, CLASSNAME, ASSOCIATES) \ extern "C" void wrapper_serializer_##NAME(void) {} \ extern void wrapper_propfunc_##NAME(osgDB::ObjectWrapper*); \ + static osg::Object* wrapper_createinstancefunc##NAME() { return CREATEINSTANCE; } \ static osgDB::RegisterWrapperProxy wrapper_proxy_##NAME( \ - PROTO, CLASSNAME, ASSOCIATES, &wrapper_propfunc_##NAME); \ + wrapper_createinstancefunc##NAME, CLASSNAME, ASSOCIATES, &wrapper_propfunc_##NAME); \ typedef CLASS MyClass; \ void wrapper_propfunc_##NAME(osgDB::ObjectWrapper* wrapper) -#define REGISTER_CUSTOM_OBJECT_WRAPPER(DOMAIN, NAME, PROTO, CLASS, ASSOCIATES) \ +#define REGISTER_CUSTOM_OBJECT_WRAPPER(DOMAIN, NAME, CREATEINSTANCE, CLASS, ASSOCIATES) \ extern "C" void wrapper_serializer_##NAME(void) {} \ extern void wrapper_propfunc_##NAME(const char*, osgDB::ObjectWrapper*); \ + static osg::Object* wrapper_createinstancefunc##NAME() { return CREATEINSTANCE; } \ static osgDB::RegisterCustomWrapperProxy wrapper_proxy_##NAME( \ - PROTO, #DOMAIN, #CLASS, ASSOCIATES, &wrapper_propfunc_##NAME); \ + wrapper_createinstancefunc##NAME, #DOMAIN, #CLASS, ASSOCIATES, &wrapper_propfunc_##NAME); \ typedef CLASS MyClass; \ void wrapper_propfunc_##NAME(const char* domain, osgDB::ObjectWrapper* wrapper) -#define REGISTER_CUSTOM_OBJECT_WRAPPER2(DOMAIN, NAME, PROTO, CLASS, CLASSNAME, ASSOCIATES) \ +#define REGISTER_CUSTOM_OBJECT_WRAPPER2(DOMAIN, NAME, CREATEINSTANCE, CLASS, CLASSNAME, ASSOCIATES) \ extern "C" void wrapper_serializer_##NAME(void) {} \ extern void wrapper_propfunc_##NAME(const char*, osgDB::ObjectWrapper*); \ + static osg::Object* wrapper_createinstancefunc##NAME() { return CREATEINSTANCE; } \ static osgDB::RegisterCustomWrapperProxy wrapper_proxy_##NAME( \ - PROTO, #DOMAIN, CLASSNAME, ASSOCIATES, &wrapper_propfunc_##NAME); \ + wrapper_createinstancefunc##NAME, #DOMAIN, CLASSNAME, ASSOCIATES, &wrapper_propfunc_##NAME); \ typedef CLASS MyClass; \ void wrapper_propfunc_##NAME(const char* domain, osgDB::ObjectWrapper* wrapper) diff --git a/src/osgDB/InputStream.cpp b/src/osgDB/InputStream.cpp index efed38ec1..3d4a77a06 100644 --- a/src/osgDB/InputStream.cpp +++ b/src/osgDB/InputStream.cpp @@ -792,7 +792,7 @@ osg::Object* InputStream::readObjectFields( const std::string& className, unsign return NULL; } - osg::ref_ptr obj = existingObj ? existingObj : wrapper->getProto()->cloneType(); + osg::ref_ptr obj = existingObj ? existingObj : wrapper->createInstance(); _identifierMap[id] = obj; if ( obj.valid() ) { diff --git a/src/osgDB/ObjectWrapper.cpp b/src/osgDB/ObjectWrapper.cpp index 70639b614..68ede4055 100644 --- a/src/osgDB/ObjectWrapper.cpp +++ b/src/osgDB/ObjectWrapper.cpp @@ -84,18 +84,18 @@ void osgDB::split( const std::string& src, StringList& list, char separator ) // // ObjectWrapper // -ObjectWrapper::ObjectWrapper( osg::Object* proto, const std::string& name, +ObjectWrapper::ObjectWrapper( CreateInstanceFunc* createInstanceFunc, const std::string& name, const std::string& associates ) : osg::Referenced(), - _proto(proto), _name(name), _version(0) + _createInstanceFunc(createInstanceFunc), _name(name), _version(0) { split( associates, _associates ); } -ObjectWrapper::ObjectWrapper( osg::Object* proto, const std::string& domain, const std::string& name, +ObjectWrapper::ObjectWrapper( CreateInstanceFunc* createInstanceFunc, const std::string& domain, const std::string& name, const std::string& associates ) : osg::Referenced(), - _proto(proto), _domain(domain), _name(name), _version(0) + _createInstanceFunc(createInstanceFunc), _domain(domain), _name(name), _version(0) { split( associates, _associates ); } @@ -312,10 +312,10 @@ void ObjectWrapper::writeSchema( StringList& properties, TypeList& types ) // // RegisterWrapperProxy // -RegisterWrapperProxy::RegisterWrapperProxy( osg::Object* proto, const std::string& name, +RegisterWrapperProxy::RegisterWrapperProxy( ObjectWrapper::CreateInstanceFunc *createInstanceFunc, const std::string& name, const std::string& associates, AddPropFunc func ) { - _wrapper = new ObjectWrapper( proto, name, associates ); + _wrapper = new ObjectWrapper( createInstanceFunc, name, associates ); if ( func ) (*func)( _wrapper.get() ); if (Registry::instance()) @@ -337,10 +337,10 @@ RegisterWrapperProxy::~RegisterWrapperProxy() // RegisterCustomWrapperProxy // RegisterCustomWrapperProxy::RegisterCustomWrapperProxy( - osg::Object* proto, const std::string& domain, const std::string& name, + ObjectWrapper::CreateInstanceFunc *createInstanceFunc, const std::string& domain, const std::string& name, const std::string& associates, AddPropFunc func ) { - _wrapper = new ObjectWrapper( proto, domain, name, associates ); + _wrapper = new ObjectWrapper( createInstanceFunc, domain, name, associates ); if ( func ) (*func)( domain.c_str(), _wrapper.get() ); if (Registry::instance())