/* -*-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 #include #include #include namespace osg { typedef std::vector< osg::ref_ptr > 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(udc->getUserObject(name)) : 0; } /** Call run(..) on named CallbackObjects attached to specified Object. Return true if at least one CallbackObject has been successfully invoked.*/ inline bool runNamedCallbackObjects(osg::Object* object, const std::string& name, osg::Parameters& inputParameters, osg::Parameters& outputParameters) { bool result = false; osg::UserDataContainer* udc = object->getUserDataContainer(); if (udc) { for(unsigned int i = 0; igetNumUserObjects(); ++i) { osg::Object* obj = udc->getUserObject(i); if (obj && obj->getName()==name) { osg::CallbackObject* co = dynamic_cast(obj); if (co) result = co->run(object, inputParameters, outputParameters) | result; } } } return result; } /** 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