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.
This commit is contained in:
Robert Osfield 2014-01-06 15:45:46 +00:00
parent 534d21dffd
commit 6490f1b6a5
10 changed files with 262 additions and 11 deletions

View File

@ -16,6 +16,7 @@
#define OSGDB_OBJECTWRAPPER
#include <osgDB/Serializer>
#include <osg/ScriptEngine>
namespace osgDB
{
@ -23,6 +24,15 @@ namespace osgDB
typedef std::vector<std::string> 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<osg::Object> > 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<MethodObject> > 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:

View File

@ -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<std::string, PropertyMap> ObjectPropertyMap;

View File

@ -308,6 +308,13 @@ void ObjectWrapper::writeSchema( StringList& properties, TypeList& types )
}
}
void ObjectWrapper::addMethodObject(const std::string& methodName, MethodObject* mo)
{
OSG_NOTICE<<"Inserting MethodObject "<<methodName<<std::endl;
_methodObjectMap.insert(MethodObjectMap::value_type(methodName, mo));
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// RegisterWrapperProxy

View File

@ -279,7 +279,7 @@ osgDB::ObjectWrapper* PropertyInterface::getObjectWrapper(const osg::Object* obj
osgDB::BaseSerializer* PropertyInterface::getSerializer(const osg::Object* object, const std::string& propertyName, osgDB::BaseSerializer::Type& type) const
{
osgDB::ObjectWrapper* ow = getObjectWrapper(object);
return ow ? ow->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

View File

@ -1,11 +1,7 @@
SET(TARGET_H
MethodObject.h
LuaScriptEngine.h
)
SET(TARGET_SRC
MethodObject.cpp
GeodeMethods.cpp
GroupMethods.cpp
LuaScriptEngine.cpp
ReaderWriterLua.cpp
)

View File

@ -12,7 +12,6 @@
*/
#include "LuaScriptEngine.h"
#include "MethodObject.h"
#include <osg/io_utils>
#include <osgDB/ReadFile>
@ -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("<<object<<", "<<propertyName<<") has method need to call it."<<std::endl;
lua_pushlightuserdata(_lua, const_cast<LuaScriptEngine*>(this));

View File

@ -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;

View File

@ -15,10 +15,12 @@
#define METHODSOBJECT_H
#include <osg/ScriptEngine>
#include <osgDB/ObjectWrapper>
namespace osgDB
{
#if 0
struct MethodObject : public osg::Referenced
{
typedef std::vector< osg::ref_ptr<osg::Object> > 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
{

View File

@ -1,5 +1,6 @@
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/ValueObject>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
@ -15,7 +16,7 @@ static bool readDrawables( osgDB::InputStream& is, osg::Geode& node )
for ( unsigned int i=0; i<size; ++i )
{
osg::Drawable* drawable = dynamic_cast<osg::Drawable*>( 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<osg::Geode*>(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<osg::UIntValueObject*>(indexObject);
if (!uivo) return false;
osg::Geode* geode = reinterpret_cast<osg::Geode*>(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<osg::Drawable*>(inputParameters[0].get());
if (!child) return false;
osg::Geode* geode = reinterpret_cast<osg::Geode*>(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<osg::Drawable*>(inputParameters[0].get());
if (!child) return false;
osg::Geode* geode = reinterpret_cast<osg::Geode*>(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 );
}

View File

@ -1,4 +1,5 @@
#include <osg/Group>
#include <osg/ValueObject>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
@ -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<osg::Group*>(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 "<<indexObject->className()<<std::endl;
unsigned int index = 0;
osg::DoubleValueObject* dvo = dynamic_cast<osg::DoubleValueObject*>(indexObject);
if (dvo) index = static_cast<unsigned int>(dvo->getValue());
else
{
osg::UIntValueObject* uivo = dynamic_cast<osg::UIntValueObject*>(indexObject);
if (uivo) index = uivo->getValue();
}
osg::Group* group = reinterpret_cast<osg::Group*>(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<osg::Node*>(inputParameters[0].get());
if (!child) return false;
osg::Group* group = reinterpret_cast<osg::Group*>(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<osg::Node*>(inputParameters[0].get());
if (!child) return false;
osg::Group* group = reinterpret_cast<osg::Group*>(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 );
}