From 6490f1b6a5fd30521a0a14a30c0b131748982417 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 6 Jan 2014 15:45:46 +0000 Subject: [PATCH] Moved osgDB::MethodObject from lua plugin into osgDB, added support for running methods via the osgDB::PropertyInterface class. Updated lua plugin to use new osgDB::PropertyInterface to run methods. Added addChild/removeChild() etc to Group.cpp, and addDrawable/removeDrawable() etc. to Geode.cpp serializers. --- include/osgDB/ObjectWrapper | 23 ++++++- include/osgDB/PropertyInterface | 13 ++++ src/osgDB/ObjectWrapper.cpp | 7 +++ src/osgDB/PropertyInterface.cpp | 74 ++++++++++++++++++++++- src/osgPlugins/lua/CMakeLists.txt | 4 -- src/osgPlugins/lua/LuaScriptEngine.cpp | 6 +- src/osgPlugins/lua/LuaScriptEngine.h | 2 + src/osgPlugins/lua/MethodObject.h | 3 + src/osgWrappers/serializers/osg/Geode.cpp | 68 ++++++++++++++++++++- src/osgWrappers/serializers/osg/Group.cpp | 73 ++++++++++++++++++++++ 10 files changed, 262 insertions(+), 11 deletions(-) diff --git a/include/osgDB/ObjectWrapper b/include/osgDB/ObjectWrapper index ee0f7f9ac..86d459134 100644 --- a/include/osgDB/ObjectWrapper +++ b/include/osgDB/ObjectWrapper @@ -16,6 +16,7 @@ #define OSGDB_OBJECTWRAPPER #include +#include namespace osgDB { @@ -23,6 +24,15 @@ namespace osgDB typedef std::vector StringList; extern OSGDB_EXPORT void split( const std::string& src, StringList& list, char separator=' ' ); +struct MethodObject : public osg::Referenced +{ + typedef std::vector< osg::ref_ptr > Parameters; + + virtual bool run(void* objectPtr, osg::Parameters& inputParameters, osg::Parameters& outputParameters) const = 0; + + virtual ~MethodObject() {} +}; + class OSGDB_EXPORT BaseCompressor : public osg::Referenced { public: @@ -81,8 +91,14 @@ public: bool readSchema( const StringList& properties, const TypeList& types ); void writeSchema( StringList& properties, TypeList& types ); - void resetSchema() - { if ( _backupSerializers.size()>0 ) _serializers = _backupSerializers; } + void resetSchema() { if ( _backupSerializers.size()>0 ) _serializers = _backupSerializers; } + + void addMethodObject(const std::string& methodName, MethodObject* mo); + + typedef std::multimap< std::string, osg::ref_ptr > MethodObjectMap; + + MethodObjectMap& getMethodObjectMap() { return _methodObjectMap; } + const MethodObjectMap& getMethodObjectMap() const { return _methodObjectMap; } protected: ObjectWrapper() : _version(0) {} @@ -96,6 +112,7 @@ protected: SerializerList _backupSerializers; TypeList _typeList; FinishedObjectReadCallbackList _finishedObjectReadCallbacks; + MethodObjectMap _methodObjectMap; int _version; // Last updated version of the wrapper }; @@ -232,6 +249,8 @@ protected: typedef CLASS MyClass; \ void wrapper_propfunc_##NAME(const char* domain, osgDB::ObjectWrapper* wrapper) +#define ADD_METHOD_OBJECT( METHODNAME, METHODOBJECTCLASS ) wrapper->addMethodObject(METHODNAME, new METHODOBJECTCLASS()); + class OSGDB_EXPORT RegisterCompressorProxy { public: diff --git a/include/osgDB/PropertyInterface b/include/osgDB/PropertyInterface index 37a6cd074..d34b7407d 100644 --- a/include/osgDB/PropertyInterface +++ b/include/osgDB/PropertyInterface @@ -153,6 +153,19 @@ public: bool getSupportedProperties(const osg::Object* object, PropertyMap& properties, bool searchAssociates=true) const; + /// run method of object + bool run(void* objectPtr, const std::string& compoundClassName, const std::string& methodName, osg::Parameters& inputParameters, osg::Parameters& outputParameters) const; + + /// run method of object + bool run(osg::Object* object, const std::string& methodName, osg::Parameters& inputParameters, osg::Parameters& outputParameters) const; + + /// checked for support of specificed method + bool hasMethod(const std::string& compoundClassName, const std::string& methodName) const; + + /// checked for support of specificed method + bool hasMethod(const osg::Object* object, const std::string& methodName) const; + + /// Properties supported for a range of classes, used for white and black lists typedef std::map ObjectPropertyMap; diff --git a/src/osgDB/ObjectWrapper.cpp b/src/osgDB/ObjectWrapper.cpp index 7f41b08cc..d3262db8e 100644 --- a/src/osgDB/ObjectWrapper.cpp +++ b/src/osgDB/ObjectWrapper.cpp @@ -308,6 +308,13 @@ void ObjectWrapper::writeSchema( StringList& properties, TypeList& types ) } } +void ObjectWrapper::addMethodObject(const std::string& methodName, MethodObject* mo) +{ + OSG_NOTICE<<"Inserting MethodObject "<getSerializer(propertyName, type) : 0; + return (ow!=0) ? ow->getSerializer(propertyName, type) : 0; } osg::Object* PropertyInterface::createObject(const std::string& compoundClassName) const @@ -521,6 +521,78 @@ bool PropertyInterface::getSupportedProperties(const osg::Object* object, Proper } +bool PropertyInterface::run(void* objectPtr, const std::string& compoundClassName, const std::string& methodName, osg::Parameters& inputParameters, osg::Parameters& outputParameters) const +{ + ObjectWrapper* ow = osgDB::Registry::instance()->getObjectWrapperManager()->findWrapper(compoundClassName); + if (!ow) return false; + + const ObjectWrapper::MethodObjectMap& methodObjectMap = ow->getMethodObjectMap(); + ObjectWrapper::MethodObjectMap::const_iterator itr = methodObjectMap.find(methodName); + while ((itr!=methodObjectMap.end()) && (itr->first==methodName)) + { + MethodObject* mo = itr->second.get(); + if (mo->run(objectPtr, inputParameters, outputParameters)) return true; + ++itr; + } + + const osgDB::StringList& associates = ow->getAssociates(); + for(osgDB::StringList::const_iterator aitr = associates.begin(); + aitr != associates.end(); + ++aitr) + { + osgDB::ObjectWrapper* aow = osgDB::Registry::instance()->getObjectWrapperManager()->findWrapper(*aitr); + if (aow) + { + const ObjectWrapper::MethodObjectMap& methodObjectMap = aow->getMethodObjectMap(); + ObjectWrapper::MethodObjectMap::const_iterator itr = methodObjectMap.find(methodName); + while ((itr!=methodObjectMap.end()) && (itr->first==methodName)) + { + MethodObject* mo = itr->second.get(); + if (mo->run(objectPtr, inputParameters, outputParameters)) return true; + ++itr; + } + } + } + + return false; +} + +bool PropertyInterface::run(osg::Object* object, const std::string& methodName, osg::Parameters& inputParameters, osg::Parameters& outputParameters) const +{ + return run(object, object->getCompoundClassName(), methodName, inputParameters, outputParameters); +} + +bool PropertyInterface::hasMethod(const std::string& compoundClassName, const std::string& methodName) const +{ + ObjectWrapper* ow = osgDB::Registry::instance()->getObjectWrapperManager()->findWrapper(compoundClassName); + if (!ow) return false; + + const ObjectWrapper::MethodObjectMap& methodObjectMap = ow->getMethodObjectMap(); + ObjectWrapper::MethodObjectMap::const_iterator itr = methodObjectMap.find(methodName); + if (itr!=methodObjectMap.end()) return true; + + const osgDB::StringList& associates = ow->getAssociates(); + for(osgDB::StringList::const_iterator aitr = associates.begin(); + aitr != associates.end(); + ++aitr) + { + osgDB::ObjectWrapper* aow = osgDB::Registry::instance()->getObjectWrapperManager()->findWrapper(*aitr); + if (aow) + { + const ObjectWrapper::MethodObjectMap& methodObjectMap = aow->getMethodObjectMap(); + ObjectWrapper::MethodObjectMap::const_iterator itr = methodObjectMap.find(methodName); + if (itr!=methodObjectMap.end()) return true; + } + } + + return false; +} + +bool PropertyInterface::hasMethod(const osg::Object* object, const std::string& methodName) const +{ + return hasMethod(object->getCompoundClassName(), methodName); +} + } // end of osgDB namespace diff --git a/src/osgPlugins/lua/CMakeLists.txt b/src/osgPlugins/lua/CMakeLists.txt index 3ec9e5816..da94edf0a 100644 --- a/src/osgPlugins/lua/CMakeLists.txt +++ b/src/osgPlugins/lua/CMakeLists.txt @@ -1,11 +1,7 @@ SET(TARGET_H - MethodObject.h LuaScriptEngine.h ) SET(TARGET_SRC - MethodObject.cpp - GeodeMethods.cpp - GroupMethods.cpp LuaScriptEngine.cpp ReaderWriterLua.cpp ) diff --git a/src/osgPlugins/lua/LuaScriptEngine.cpp b/src/osgPlugins/lua/LuaScriptEngine.cpp index 1b073c080..a524b9169 100644 --- a/src/osgPlugins/lua/LuaScriptEngine.cpp +++ b/src/osgPlugins/lua/LuaScriptEngine.cpp @@ -12,7 +12,6 @@ */ #include "LuaScriptEngine.h" -#include "MethodObject.h" #include #include @@ -101,7 +100,8 @@ static int callClassMethod(lua_State* _lua) inputParameters.push_back(lse->popParameterObject()); } - if (osgDB::MethodsObjectManager::instance()->run(object, object->getCompoundClassName(), methodName, inputParameters, outputParameters)) +// if (osgDB::MethodsObjectManager::instance()->run(object, object->getCompoundClassName(), methodName, inputParameters, outputParameters)) + if (lse->getPropertyInterface().run(object, object->getCompoundClassName(), methodName, inputParameters, outputParameters)) { for(osg::Parameters::iterator itr = outputParameters.begin(); itr != outputParameters.end(); @@ -556,7 +556,7 @@ int LuaScriptEngine::pushPropertyToStack(osg::Object* object, const std::string& osgDB::BaseSerializer::Type type; if (!_pi.getPropertyType(object, propertyName, type)) { - if (osgDB::MethodsObjectManager::instance()->hasMethod(object->getCompoundClassName(), propertyName)) + if (_pi.hasMethod(object, propertyName)) { OSG_NOTICE<<"LuaScriptEngine::pushPropertyToStack("<(this)); diff --git a/src/osgPlugins/lua/LuaScriptEngine.h b/src/osgPlugins/lua/LuaScriptEngine.h index 661b08e8d..1543af239 100644 --- a/src/osgPlugins/lua/LuaScriptEngine.h +++ b/src/osgPlugins/lua/LuaScriptEngine.h @@ -45,6 +45,8 @@ class LuaScriptEngine : public osg::ScriptEngine /** get the lua_State object.*/ lua_State* getLuaState() const { return _lua; } + osgDB::PropertyInterface& getPropertyInterface() const { return _pi; } + int pushPropertyToStack(osg::Object* object, const std::string& propertyName) const; int setPropertyFromStack(osg::Object* object, const std::string& propertyName) const; diff --git a/src/osgPlugins/lua/MethodObject.h b/src/osgPlugins/lua/MethodObject.h index e2b5ca482..c3265bab6 100644 --- a/src/osgPlugins/lua/MethodObject.h +++ b/src/osgPlugins/lua/MethodObject.h @@ -15,10 +15,12 @@ #define METHODSOBJECT_H #include +#include namespace osgDB { +#if 0 struct MethodObject : public osg::Referenced { typedef std::vector< osg::ref_ptr > Parameters; @@ -26,6 +28,7 @@ struct MethodObject : public osg::Referenced virtual bool run(void* objectPtr, osg::Parameters& inputParameters, osg::Parameters& outputParameters) const = 0; virtual ~MethodObject() {} }; +#endif struct MethodsObject : public osg::Referenced { diff --git a/src/osgWrappers/serializers/osg/Geode.cpp b/src/osgWrappers/serializers/osg/Geode.cpp index 10f1a5762..0c7614083 100644 --- a/src/osgWrappers/serializers/osg/Geode.cpp +++ b/src/osgWrappers/serializers/osg/Geode.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -15,7 +16,7 @@ static bool readDrawables( osgDB::InputStream& is, osg::Geode& node ) for ( unsigned int i=0; i( is.readObject() ); - if ( drawable ) + if ( drawable ) { node.addDrawable( drawable ); } @@ -35,6 +36,66 @@ static bool writeDrawables( osgDB::OutputStream& os, const osg::Geode& node ) os << os.END_BRACKET << std::endl; return true; } +struct GeodeGetNumDrawables : public osgDB::MethodObject +{ + virtual bool run(void* objectPtr, osg::Parameters& inputParameters, osg::Parameters& outputParameters) const + { + osg::Geode* geode = reinterpret_cast(objectPtr); + outputParameters.push_back(new osg::UIntValueObject("return", geode->getNumDrawables())); + return true; + } +}; + + +struct GeodeGetDrawable : public osgDB::MethodObject +{ + virtual bool run(void* objectPtr, osg::Parameters& inputParameters, osg::Parameters& outputParameters) const + { + if (inputParameters.empty()) return false; + + osg::Object* indexObject = inputParameters[0].get(); + osg::UIntValueObject* uivo = dynamic_cast(indexObject); + if (!uivo) return false; + + osg::Geode* geode = reinterpret_cast(objectPtr); + outputParameters.push_back(geode->getDrawable(uivo->getValue())); + + return true; + } +}; + +struct GeodeAddDrawable : public osgDB::MethodObject +{ + virtual bool run(void* objectPtr, osg::Parameters& inputParameters, osg::Parameters& outputParameters) const + { + if (inputParameters.empty()) return false; + + osg::Drawable* child = dynamic_cast(inputParameters[0].get()); + if (!child) return false; + + osg::Geode* geode = reinterpret_cast(objectPtr); + geode->addDrawable(child); + + return true; + } +}; + + +struct GeodeRemoveDrawable : public osgDB::MethodObject +{ + virtual bool run(void* objectPtr, osg::Parameters& inputParameters, osg::Parameters& outputParameters) const + { + if (inputParameters.empty()) return false; + + osg::Drawable* child = dynamic_cast(inputParameters[0].get()); + if (!child) return false; + + osg::Geode* geode = reinterpret_cast(objectPtr); + geode->removeDrawable(child); + + return true; + } +}; REGISTER_OBJECT_WRAPPER( Geode, new osg::Geode, @@ -42,4 +103,9 @@ REGISTER_OBJECT_WRAPPER( Geode, "osg::Object osg::Node osg::Geode" ) { ADD_USER_SERIALIZER( Drawables ); // _drawables + + ADD_METHOD_OBJECT( "getNumDrawables", GeodeGetNumDrawables ); + ADD_METHOD_OBJECT( "getDrawable", GeodeGetDrawable ); + ADD_METHOD_OBJECT( "addDrawable", GeodeAddDrawable ); + ADD_METHOD_OBJECT( "removeDrawable", GeodeRemoveDrawable ); } diff --git a/src/osgWrappers/serializers/osg/Group.cpp b/src/osgWrappers/serializers/osg/Group.cpp index 9e8a40057..237db2ed6 100644 --- a/src/osgWrappers/serializers/osg/Group.cpp +++ b/src/osgWrappers/serializers/osg/Group.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -33,10 +34,82 @@ static bool writeChildren( osgDB::OutputStream& os, const osg::Group& node ) return true; } +struct GroupGetNumChildren : public osgDB::MethodObject +{ + virtual bool run(void* objectPtr, osg::Parameters& inputParameters, osg::Parameters& outputParameters) const + { + osg::Group* group = reinterpret_cast(objectPtr); + outputParameters.push_back(new osg::UIntValueObject("return", group->getNumChildren())); + return true; + } +}; + +struct GroupGetChild : public osgDB::MethodObject +{ + virtual bool run(void* objectPtr, osg::Parameters& inputParameters, osg::Parameters& outputParameters) const + { + if (inputParameters.empty()) return false; + + osg::Object* indexObject = inputParameters[0].get(); + OSG_NOTICE<<"GroupGetChild "<className()<(indexObject); + if (dvo) index = static_cast(dvo->getValue()); + else + { + osg::UIntValueObject* uivo = dynamic_cast(indexObject); + if (uivo) index = uivo->getValue(); + } + osg::Group* group = reinterpret_cast(objectPtr); + outputParameters.push_back(group->getChild(index)); + + return true; + } +}; + +struct GroupAddChild : public osgDB::MethodObject +{ + virtual bool run(void* objectPtr, osg::Parameters& inputParameters, osg::Parameters& outputParameters) const + { + if (inputParameters.empty()) return false; + + osg::Node* child = dynamic_cast(inputParameters[0].get()); + if (!child) return false; + + osg::Group* group = reinterpret_cast(objectPtr); + group->addChild(child); + + return true; + } +}; + + +struct GroupRemoveChild : public osgDB::MethodObject +{ + virtual bool run(void* objectPtr, osg::Parameters& inputParameters, osg::Parameters& outputParameters) const + { + if (inputParameters.empty()) return false; + + osg::Node* child = dynamic_cast(inputParameters[0].get()); + if (!child) return false; + + osg::Group* group = reinterpret_cast(objectPtr); + group->removeChild(child); + + return true; + } +}; + REGISTER_OBJECT_WRAPPER( Group, new osg::Group, osg::Group, "osg::Object osg::Node osg::Group" ) { ADD_USER_SERIALIZER( Children ); // _children + + ADD_METHOD_OBJECT( "getNumChildren", GroupGetNumChildren ); + ADD_METHOD_OBJECT( "getChild", GroupGetChild ); + ADD_METHOD_OBJECT( "addChild", GroupAddChild ); + ADD_METHOD_OBJECT( "removeChild", GroupRemoveChild ); }