OpenSceneGraph/include/osg/ScriptEngine
Robert Osfield 5f8e2bda2f Added osg::CallbackObject to be used to extend C++ class from scripting languages by providing callback objects assigned to the osg::Object UserDataContainer, with the CallbackObject's Name used to map the "method" provided by the CallbackObject. The CallbackObject is implemented by the script engine to provide the neccessary glue to invoking the script with the appropriate input parameters and handling the output parameters.
To the Lua plugin added support for assigned lua functions to C++ osg::Objects via the new osg::CallbackObject mechanism.  To invoke the scripts function from C++ one must get the CallbackObject and call run on it.

Renamed ScriptCallback to ScriptNodeCallback to avoid possibly confusion between osg::CallbackObject and the ScriptNodeCallback.
2014-01-31 16:20:29 +00:00

150 lines
5.3 KiB
C++

/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2013 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#ifndef OSG_SCRIPTENGINE
#define OSG_SCRIPTENGINE 1
#include <osg/Object>
#include <osg/NodeCallback>
#include <osg/NodeVisitor>
#include <osg/UserDataContainer>
namespace osg
{
typedef std::vector< osg::ref_ptr<osg::Object> > Parameters;
// forward declare
class ScriptEngine;
/* Script class for wrapping a script and the language used in the script.*/
class Script : public osg::Object
{
public:
Script():_modifiedCount(0) {}
Script(const std::string& language, const std::string& str): _language(language), _script(str), _modifiedCount(0) {}
Script(const Script& rhs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY): _language(rhs._language), _script(rhs._script), _modifiedCount(0) {}
META_Object(osg, Script)
void setLanguage(const std::string& language) { _language = language; dirty(); }
const std::string& getLanguage() { return _language; }
void setScript(const std::string& str) { _script = str; dirty(); }
const std::string& getScript() const { return _script; }
void dirty() { ++_modifiedCount; }
unsigned int getModifiedCount() const { return _modifiedCount; }
protected:
virtual ~Script() {}
std::string _language;
std::string _script;
unsigned int _modifiedCount;
};
/** Callback for attaching a script to a Node's via there UserDataContainer for the purpose of overriding class methods within scripts.*/
class OSG_EXPORT CallbackObject : public osg::Object
{
public:
CallbackObject() {}
CallbackObject(const std::string& name) { setName(name); }
CallbackObject(const CallbackObject& rhs, const osg::CopyOp copyop=osg::CopyOp::SHALLOW_COPY):osg::Object(rhs,copyop) {}
META_Object(osg, CallbackObject);
inline bool run(osg::Object* object) const
{
osg::Parameters inputParameters;
osg::Parameters outputParameters;
return run(object, inputParameters, outputParameters);
}
virtual bool run(osg::Object* object, osg::Parameters& inputParameters, osg::Parameters& outputParameters) const;
};
/** Convinience function for getting the CallbackObject associated with specificed name from an Object's UserDataContainer.*/
inline CallbackObject* getCallbackObject(osg::Object* object, const std::string& name)
{
osg::UserDataContainer* udc = object->getUserDataContainer();
return udc ? dynamic_cast<osg::CallbackObject*>(udc->getUserObject(name)) : 0;
}
/** NodeCallback for attaching a script to a NodeCallback so that it can be called as an update or event callback.*/
class OSG_EXPORT ScriptNodeCallback : public osg::NodeCallback
{
public:
ScriptNodeCallback(Script* script=0, const std::string& entryPoint="") : _script(script), _entryPoint(entryPoint) {}
ScriptNodeCallback(const ScriptNodeCallback& rhs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY): osg::NodeCallback(rhs,copyop), _script(rhs._script) {}
META_Object(osg, ScriptNodeCallback)
/** Set the script to call.*/
void setScript(osg::Script* script) { _script = script; }
/** Get the script to call.*/
osg::Script* getScript() { return _script.get(); }
/** Get the script to call.*/
const osg::Script* getScript() const { return _script.get(); }
/** find the ScriptEngine from looking at the UserDataContainers of nodes in scene graph above the ScriptCallback.*/
osg::ScriptEngine* getScriptEngine(osg::NodePath& nodePath);
/** NodeCallback method, calls the Script.*/
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
protected:
virtual ~ScriptNodeCallback() {}
osg::ref_ptr<Script> _script;
std::string _entryPoint;
};
/** ScriptEngine base class for integrating different scripting languages.
* Concrete ScriptEngine's are provided by osgDB::readFile<ScriptEngine> */
class ScriptEngine : public osg::Object
{
public:
/** get the scripting language supported by the ScriptEngine.*/
inline const std::string& getLanguage() const { return _language; }
/** run a Script.*/
bool run(osg::Script* script)
{
// assumpt empty input and output paramters lists
Parameters inputParameters, outputParameters;
return run(script, "", inputParameters, outputParameters);
}
/** run a Script.*/
virtual bool run(osg::Script* script, const std::string& entryPoint, Parameters& inputParameters, Parameters& outputParameters) = 0;
protected:
ScriptEngine(const std::string& language):_language(language) { setName(language); }
virtual ~ScriptEngine() {}
std::string _language;
};
}
#endif