From: Markus R. <rol...@us...> - 2005-12-18 17:54:09
|
Update of /cvsroot/simspark/simspark/spark/plugin/rubysceneimporter In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5320 Modified Files: rubysceneimporter.cpp rubysceneimporter.h Log Message: - changed RubySceneImporter to defer method calls on Nodes until after the Scene is completely setup. Methods that the Transform node supports are carried out immediately (most import SetName). Other defered methods, like the 'attach' call on Joint nodes can therefore now reference nodes that were not constructed when the call is parsed. Index: rubysceneimporter.h =================================================================== RCS file: /cvsroot/simspark/simspark/spark/plugin/rubysceneimporter/rubysceneimporter.h,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** rubysceneimporter.h 13 Dec 2005 21:48:50 -0000 1.1 --- rubysceneimporter.h 18 Dec 2005 17:53:56 -0000 1.2 *************** *** 33,36 **** --- 33,46 ---- typedef std::map<std::string, int> TParameterMap; + //! defines a method invocation + struct MethodInvocation + { + boost::weak_ptr<zeitgeist::Node> node; + std::string method; + zeitgeist::ParameterList parameter; + }; + + typedef std::list<MethodInvocation> TMethodInvocationList; + //! a parameter environment struct ParamEnv *************** *** 38,41 **** --- 48,52 ---- TParameterMap parameterMap; boost::shared_ptr<zeitgeist::ParameterList> parameter; + TMethodInvocationList invocationList; ParamEnv(); *************** *** 75,79 **** --- 86,95 ---- bool ReadDeltaGraph(sexp_t* sexp, boost::shared_ptr<oxygen::BaseNode> root); boost::shared_ptr<zeitgeist::Object> CreateInstance(const std::string& className); + + void PushInvocation(const MethodInvocation& invoc); + bool Invoke(const MethodInvocation& invoc); + bool InvokeMethods(); bool ReadMethodCall(sexp_t* _sexp, boost::shared_ptr<oxygen::BaseNode> node); + bool ReplaceVariable(std::string& param); bool EvalParameter(sexp_t* sexp, std::string& value); Index: rubysceneimporter.cpp =================================================================== RCS file: /cvsroot/simspark/simspark/spark/plugin/rubysceneimporter/rubysceneimporter.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** rubysceneimporter.cpp 13 Dec 2005 21:48:50 -0000 1.1 --- rubysceneimporter.cpp 18 Dec 2005 17:53:56 -0000 1.2 *************** *** 24,27 **** --- 24,28 ---- #include <zeitgeist/fileserver/fileserver.h> #include <zeitgeist/scriptserver/scriptserver.h> + #include <oxygen/sceneserver/transform.h> #include <boost/scoped_array.hpp> *************** *** 55,58 **** --- 56,71 ---- */ + #define S_NODE "node" + #define S_SELECT "select" + #define S_PWD "pwd" + #define S_TEMPLATE "template" + #define S_DEFINE "define" + #define S_ATTACH "attach" + + #define S_DELTASCENE "RubyDeltaScene" + #define S_SCENEGRAPH "RubySceneGraph" + + #define S_FROMSTRING "<from string>"; + RubySceneImporter::RubySceneImporter() : SceneImporter() { *************** *** 100,104 **** shared_ptr<ParameterList> parameter) { ! mFileName = "<from string>"; return ParseScene(scene.c_str(),scene.size(),root,parameter); } --- 113,117 ---- shared_ptr<ParameterList> parameter) { ! mFileName = S_FROMSTRING; return ParseScene(scene.c_str(),scene.size(),root,parameter); } *************** *** 146,149 **** --- 159,163 ---- destroy_continuation(pcont); + InvokeMethods(); PopParameter(); return ok; *************** *** 204,211 **** mDeltaScene = false; ! if (val == "RubyDeltaScene") { mDeltaScene = true; ! } else if (val != "RubySceneGraph") { return false; --- 218,225 ---- mDeltaScene = false; ! if (val == S_DELTASCENE) { mDeltaScene = true; ! } else if (val != S_SCENEGRAPH) { return false; *************** *** 446,449 **** --- 460,540 ---- } + void RubySceneImporter::PushInvocation(const MethodInvocation& invoc) + { + shared_ptr<Class> baseNodeClass = + shared_dynamic_cast<Class>(GetCore()->Get("/classes/oxygen/Transform")); + + if (baseNodeClass.get() == 0) + { + GetLog()->Error() + << "(RubySceneImporter) ERROR: failed to get class object for Transform\n"; + return; + } + + if (baseNodeClass->SupportsCommand(invoc.method)) + { + // invoke basic methods, i.e. methods already supported by + // Transform immediately (e.g. setName, setLocalPos etc.) + Invoke(invoc); + } else + { + // defer methods on other nodes, to allow for forward + // references to nodes that are not installed yet + // (e.g. 'attach' on Joint nodes) + ParamEnv& env = GetParamEnv(); + env.invocationList.push_back(invoc); + } + } + + bool RubySceneImporter::Invoke(const MethodInvocation& invoc) + { + if (invoc.node.expired()) + { + GetLog()->Error() + << "(RubySceneImporter) ERROR: Invoke called with expired node\n"; + return false; + } + + // invoke the method on the object + shared_ptr<Node> node = invoc.node.lock(); + shared_ptr<Class> theClass = node->GetClass(); + + if (theClass.get() == 0) + { + GetLog()->Error() + << "(RubySceneImporter) ERROR: cannot get class object for node " + << node->GetFullPath() << "\n"; + return false; + } + + if (! theClass->SupportsCommand(invoc.method)) + { + GetLog()->Error() + << "(RubySceneImporter) ERROR: in file '" << mFileName + << "': unknown method name '" + << invoc.method << "' for node '" << node->GetFullPath() + << "' (a " << theClass->GetName() << ")\n"; + return false; + } + + node->Invoke(invoc.method, invoc.parameter); + return true; + } + + bool RubySceneImporter::InvokeMethods() + { + RubySceneImporter::ParamEnv& env = GetParamEnv(); + + for ( + TMethodInvocationList::const_iterator iter = env.invocationList.begin(); + iter != env.invocationList.end(); + ++iter + ) + { + const MethodInvocation& invoc = (*iter); + Invoke(invoc); + } + } + bool RubySceneImporter::ReadMethodCall(sexp_t* sexp, shared_ptr<BaseNode> node) { *************** *** 457,462 **** sexp = sexp->next; ! // collect the parameters ! ParameterList parameter; while (sexp != 0) --- 548,555 ---- sexp = sexp->next; ! // build method invocation struct ! MethodInvocation invocation; ! invocation.node = node; ! invocation.method = method; while (sexp != 0) *************** *** 484,513 **** } ! parameter.AddValue(param); sexp = sexp->next; } ! // invoke the method on the object ! shared_ptr<Class> theClass = node->GetClass(); ! ! if (theClass.get() == 0) ! { ! GetLog()->Error() ! << "(RubySceneImporter) ERROR: cannot get class object for node " ! << node->GetFullPath() << "\n"; ! return false; ! } ! ! if (! theClass->SupportsCommand(method)) ! { ! GetLog()->Error() ! << "(RubySceneImporter) ERROR: in file '" << mFileName ! << "': unknown method name '" ! << method << "' for node '" << node->GetFullPath() ! << "' (a " << theClass->GetName() << ")\n"; ! return false; ! } ! ! node->Invoke(method, parameter); return true; } --- 577,585 ---- } ! invocation.parameter.AddValue(param); sexp = sexp->next; } ! PushInvocation(invocation); return true; } *************** *** 648,652 **** string name(sexp->val); ! if (name == "node") { while ( --- 720,724 ---- string name(sexp->val); ! if (name == S_NODE) { while ( *************** *** 672,676 **** if ( (sub->ty == SEXP_VALUE) && ! (string(sub->val) == "node") ) { --- 744,748 ---- if ( (sub->ty == SEXP_VALUE) && ! (string(sub->val) == S_NODE) ) { *************** *** 711,715 **** string name(sexp->val); ! if (name == "node") { sexp = sexp->next; --- 783,787 ---- string name(sexp->val); ! if (name == S_NODE) { sexp = sexp->next; *************** *** 724,728 **** root = node; } ! else if (name == "select") { sexp = sexp->next; --- 796,800 ---- root = node; } ! else if (name == S_SELECT) { sexp = sexp->next; *************** *** 739,752 **** root = node; } ! else if (name == "pwd") { ! GetLog()->Error() << "DEBUG: pwd: " << root->GetFullPath() << "\n"; } ! else if (name == "template") { sexp = sexp->next; return ParseTemplate(sexp); } ! else if (name == "define") { sexp = sexp->next; --- 811,824 ---- root = node; } ! else if (name == S_PWD) { ! GetLog()->Debug() << "DEBUG: pwd: " << root->GetFullPath() << "\n"; } ! else if (name == S_TEMPLATE) { sexp = sexp->next; return ParseTemplate(sexp); } ! else if (name == S_DEFINE) { sexp = sexp->next; |