📄 rubysceneimporter.cpp
字号:
if (expr.empty()) { GetLog()->Error() << "(RubySceneImporter) ERROR: in file '" << mFileName << "': empty eval expression in parameter list\n"; return false; } GCValue gcValue; if (! script->Eval(expr, gcValue)) { GetLog()->Error() << "(RubySceneImporter) ERROR: in file '" << mFileName << "': failed to eval expression " << expr << "\n"; return false; } if (! gcValue.GetString(value)) { GetLog()->Error() << "(RubySceneImporter) ERROR: in file '" << mFileName << "': failed to get string result form expresion result\n"; return false; } return true;}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); } return true;}bool RubySceneImporter::ReadMethodCall(sexp_t* sexp, shared_ptr<BaseNode> node){ if (sexp == 0) { return false; } // read the method name string method = Lookup(sexp->val); sexp = sexp->next; // build method invocation struct MethodInvocation invocation; invocation.node = node; invocation.method = method; while (sexp != 0) { string param; if (sexp->ty == SEXP_LIST) { if (! EvalParameter(sexp->list,param)) { return false; } } else { param = sexp->val; //Todo: use TranslationTable here? if ( (param[0] == '$') && (! ReplaceVariable(param)) ) { return false; } } invocation.parameter.AddValue(param); sexp = sexp->next; } PushInvocation(invocation); return true;}bool RubySceneImporter::ParseDefine(sexp_t* sexp){ string varname = sexp->val; //Todo: use TranslationTable here? sexp = sexp->next; if ( (varname[0] != '$') || (varname.size() < 2) ) { GetLog()->Error() << "(RubySceneImporter) ERROR: in file '" << mFileName << "': parameter name expected\n"; return false; } varname.erase(varname.begin(),varname.begin()+1); if (sexp == 0) { GetLog()->Error() << "(RubySceneImporter) ERROR: in file '" << mFileName << "': define without value\n"; return false; } string value; if (sexp->ty == SEXP_LIST) { if (sexp->ty == SEXP_LIST) { if (! EvalParameter(sexp->list,value)) { return false; } } } else { value = sexp->val; if ( (value[0] == '$') && (! ReplaceVariable(value)) ) { return false; } } ParamEnv& env = GetParamEnv(); TParameterMap::const_iterator iter = env.parameterMap.find(varname); if (iter == env.parameterMap.end()) { // create a new variable env.parameter->AddValue(value); int idx = (static_cast<int>(env.parameterMap.size())); env.parameterMap[varname] = idx; } else { // update value of existing variable ParameterList::TVector::iterator valIter = (*env.parameter)[(*iter).second]; (*valIter) = value; } return true;}bool RubySceneImporter::ParseTemplate(sexp_t* sexp){ if (sexp == 0) { return false; } ParamEnv& env = GetParamEnv(); while ( (sexp != 0) && (sexp->ty == SEXP_VALUE) ) { string param = sexp->val; //todo: use abbrevTable here? if (param.size() == 0) { sexp = sexp->next; continue; } if ( (param[0] != '$') || (param.size() < 2) ) { GetLog()->Error() << "(RubySceneImporter) ERROR: in file '" << mFileName << "': template parameter name expected\n"; return false; } param.erase(param.begin(),param.begin()+1); TParameterMap::const_iterator iter = env.parameterMap.find(param); if (iter != env.parameterMap.end()) { GetLog()->Error() << "(RubySceneImporter) ERROR: in file '" << mFileName << "': duplicate template parameter name '" << param << "'\n"; return false; } int idx = static_cast<int>(env.parameterMap.size()); env.parameterMap[param] = idx; sexp = sexp->next; } return true;}// bool RubySceneImporter::ParseSwitch(sexp_t* sexp, string& value)bool RubySceneImporter::ParseSwitch(sexp_t* sexp, boost::shared_ptr<oxygen::BaseNode> root){ if (sexp == 0) { return false; } string varname; if (sexp->ty == SEXP_LIST) { // if the switch after is a list, it should be evaled. if (! EvalParameter(sexp->list,varname)) { return false; } } else { varname = sexp->val; if ( (varname[0] == '$') && (! ReplaceVariable(varname)) ) { return false; } } sexp = sexp->next; if (sexp == 0) { GetLog()->Debug() << "(RubySceneImporter) ERROR: in file '" << mFileName << "': no case sentences of switch '" << varname << "'\n"; return true; } sexp_t* tmp; string value; // find the sub list whose header is equal to 'varname', // then it's that case. while (sexp != 0) { if (sexp->ty == SEXP_LIST) { tmp = sexp->list; if (tmp == 0) break; if (tmp->ty == SEXP_LIST) { // if the case header is a list, it should be evaled. if (! EvalParameter(tmp->list,value)) { return false; } } else { value = tmp->val; if ( (value[0] == '$') && (! ReplaceVariable(value)) ) { return false; } } // the first case is here, then find is over if (value == varname) break; } sexp = sexp->next; } if (value != varname) { // default case GetLog()->Debug() << "(RubySceneImporter) ERROR: in file '" << mFileName << "': no switch case equal to '" << varname << "'\n"; return false; } else { tmp = tmp->next; if (tmp != 0) { if (tmp->ty == SEXP_LIST) { // get the value of this case // if (! EvalParameter(tmp->list,value)) // { // return false; // } ReadGraph(tmp->list, root); } else { value = tmp->val; if ( (value[0] == '$') && (! ReplaceVariable(value)) ) { return false; } } } else { GetLog()->Debug() << "(RubySceneImporter) ERROR: in file '" << mFileName << "': no execute sentences in case '" << value << "'\n"; return false; } } return true;}boolRubySceneImporter::ReadDeltaGraph(sexp_t* sexp, shared_ptr<BaseNode> root){ if ( root.get() == 0 ) return false; TLeafList::const_iterator iter = root->begin(); while (sexp != 0) { switch (sexp->ty) { case SEXP_VALUE: { string name = Lookup(string(sexp->val)); if (name == S_NODE) { while ( (sexp != 0) && (sexp->ty != SEXP_LIST) ) { sexp = sexp->next; } continue; } else { return ReadMethodCall(sexp, root); } } break; case SEXP_LIST: { sexp_t* sub = sexp->list; if (sub != 0) { shared_ptr<BaseNode> node; if ( (sub->ty == SEXP_VALUE) && (Lookup(string(sub->val)) == S_NODE) ) { node = shared_dynamic_cast<BaseNode>(*iter); if (iter != root->end()) { ++iter; } } else { node = root; } if (! ReadDeltaGraph(sub, node)) { return false; } } } break; default: return false; } sexp = sexp->next; } return true;}boolRubySceneImporter::ReadGraph(sexp_t* sexp, shared_ptr<BaseNode> root){ while (sexp != 0) { switch (sexp->ty) { case SEXP_VALUE: { string name = Lookup(string(sexp->val)); if (name == S_NODE) { sexp = sexp->next; shared_ptr<BaseNode> node = CreateNode(sexp); if (node.get() == 0) { return false; } root->AddChildReference(node); root = node; } else if (name == S_SELECT) { sexp = sexp->next; string name(sexp->val); //todo: use abbrevTable here? shared_ptr<BaseNode> node = shared_dynamic_cast<BaseNode>(root->GetChild(name)); if (node.get() == 0) { GetLog()->Error() << "ERROR: Select: " << name << " not found\n"; return false; } 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; return ParseDefine(sexp); } else if (name == S_SWITCH) { sexp = sexp->next; return ParseSwitch(sexp, root); } else { return ReadMethodCall(sexp, root); } } break; case SEXP_LIST: if (! ReadGraph(sexp->list,root)) { return false; } break; default: return false; } sexp = sexp->next; } return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -