// Copyright (C) 2002-2003 Gideon May (gideon@computer.org) // // Permission to copy, use, sell and distribute this software is granted // provided this copyright notice appears in all copies. // Permission to modify the code and to distribute modified code is granted // provided this copyright notice appears in all copies, and a notice // that the code was modified is included with the copyright notice. // // This software is provided "as is" without express or implied warranty, // and with no claim as to its suitability for any purpose. #include #include #include #include #include #include #include #include "PythonInterpreter.hpp" using namespace osg; using namespace osgScript; namespace { class UpdateCallback : public NodeCallback { virtual void operator()(Node* node, NodeVisitor* nv) { PythonScript * script = dynamic_cast(node); if (script->getUpdateHandle()) { try { boost::python::call(static_cast(script->getUpdateHandle()), boost::python::ptr(static_cast(script)), boost::python::ptr(nv)); } catch(...) { PyErr_Print(); } } traverse(node,nv); if (script->getPostUpdateHandle()) { try { boost::python::call(static_cast(script->getPostUpdateHandle()), boost::python::ptr(static_cast(script)), boost::python::ptr(nv)); } catch(...) { PyErr_Print(); } } } }; class CullCallback : public NodeCallback { virtual void operator()(Node* node, NodeVisitor* nv) { PythonScript * script = dynamic_cast(node); if (script->getCullHandle()) { try { boost::python::call(static_cast(script->getCullHandle()), boost::python::ptr(static_cast(script)), boost::python::ptr(nv)); } catch(...) { PyErr_Print(); } } traverse(node,nv); if (script->getPostCullHandle()) { try { boost::python::call(static_cast(script->getPostCullHandle()), boost::python::ptr(static_cast(script)), boost::python::ptr(nv)); } catch(...) { PyErr_Print(); } } } }; } PythonScript::PythonScript(): _firstTime(true), _module(NULL), _initHandle(NULL), _updateHandle(NULL), _postUpdateHandle(NULL), _cullHandle(NULL), _postCullHandle(NULL) { notify(DEBUG_INFO) << "PythonScript::PythonScript()" << std::endl; } PythonScript::PythonScript(const PythonScript& script,const CopyOp& copyop): Script(script,copyop), _firstTime(script._firstTime), _module(script._module), _initHandle(script._initHandle), _updateHandle(script._updateHandle), _postUpdateHandle(script._postUpdateHandle), _cullHandle(script._cullHandle), _postCullHandle(script._postCullHandle) { } void PythonScript::setup() { notify(DEBUG_INFO) << "PythonScript::setup(), inlineCode.length = " << _inlineCode.length() << " externCode.length = " << _externCode.length() << std::endl; PythonInterpreter * interp = PythonInterpreter::Instance(); if (_inlineCode.length()) { interp->runSimpleString(_inlineCode.c_str()); _firstTime = false; _module = PyImport_AddModule("__main__"); PyObject * _dict = PyModule_GetDict(static_cast(_module)); _initHandle = PyDict_GetItemString(_dict, const_cast(_initFunc.c_str())); } else if (_externCode.length()) { PyObject * pName = PyString_FromString(_externCode.c_str()); _module = PyImport_Import(pName); _firstTime = false; if (_module == NULL) { PyErr_Print(); notify(NOTICE) << "osgScript::PythonScript, Unable to load python script : " << _externCode << std::endl; } } if (_firstTime == false && _module) { PyObject * dict = PyModule_GetDict(static_cast(_module)); if (_updateFunc.length()) { _updateHandle = PyDict_GetItemString(dict, const_cast(_updateFunc.c_str())); if (_updateHandle == NULL) { notify(NOTICE) << "update callback " << _updateFunc << " not defined" << std::endl; } } if (_postUpdateFunc.length()) { _postUpdateHandle = PyDict_GetItemString(dict, const_cast(_postUpdateFunc.c_str())); if (_postUpdateHandle == NULL) { notify(NOTICE) << "postupdate callback " << _postUpdateFunc << " not defined" << std::endl; } } if (_updateHandle || _postUpdateHandle) { this->setUpdateCallback(new UpdateCallback()); } if (_cullFunc.length()) { _cullHandle = PyDict_GetItemString(dict, const_cast(_cullFunc.c_str())); if (_cullHandle == NULL) { notify(NOTICE) << "cull callback " << _cullFunc << " not defined" << std::endl; } } if (_postCullFunc.length()) { _postCullHandle = PyDict_GetItemString(dict, const_cast(_postCullFunc.c_str())); if (_postCullHandle == NULL) { notify(NOTICE) << "postcull callback " << _postCullFunc << " not defined" << std::endl; } } if (_cullHandle || _postCullHandle) { this->setCullCallback(new CullCallback()); } } } void PythonScript::traverse(NodeVisitor& nv) { notify(DEBUG_INFO) << "PythonScript::traverse()" << std::endl; if (_firstTime) { setup(); // When setup has succeeded, _firstTime is set to false if (_firstTime == false && _module) { // Try to call the init function on first successfull traverse if (_initFunc.length()) { PyObject * dict = PyModule_GetDict(static_cast(_module)); PyObject * func = PyDict_GetItemString(dict, const_cast(_initFunc.c_str())); if (func == NULL) { notify(NOTICE) << "init callback " << _initFunc << " not defined" << std::endl; } else { try { boost::python::call(func, boost::python::ptr(static_cast(this))); } catch(...) { PyErr_Print(); } } } } } Group::traverse(nv); } PythonScript::~PythonScript() { notify(NOTICE) << "Deleting python script node\n"; }