Update of /cvsroot/simspark/simspark/spark/zeitgeist/scriptserver In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11684/scriptserver Added Files: gcvalue.cpp gcvalue.h rubywrapper.cpp rubywrapper.h scriptserver.cpp scriptserver.h scriptserver_c.cpp Log Message: --- NEW FILE: scriptserver.cpp --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2002,2003 Koblenz University Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group $Id: scriptserver.cpp,v 1.1 2005/12/05 21:05:01 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program 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 GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <boost/any.hpp> #include <boost/scoped_array.hpp> #include <sstream> #include "scriptserver.h" #include <zeitgeist/corecontext.h> #include <zeitgeist/core.h> #include <zeitgeist/logserver/logserver.h> #include <zeitgeist/fileserver/fileserver.h> #include <sys/stat.h> using namespace boost; using namespace std; using namespace zeitgeist; boost::shared_ptr<CoreContext> gMyPrivateContext; void getParameterList(VALUE args, ParameterList& params) { int argc = RARRAY(args)->len; for (int i = 0; i<argc; ++i) { VALUE argument = rb_ary_entry(args, i); boost::any var; // do type conversion switch (TYPE(argument)) { case T_STRING: { char *c = STR2CSTR(argument); var = c; //printf("string: '%s'\n",boost::any_cast<char*>(var)); } break; case T_FIXNUM: { int i = FIX2INT(argument); var = i; //printf("int: '%d'\n", boost::any_cast<int>(var)); } break; case T_FLOAT: { float f = (float)NUM2DBL(argument); var = f; //printf("float: '%f'\n", boost::any_cast<float>(var)); } break; case T_TRUE: { var = true; //printf("bool: 'true'\n"); } break; case T_FALSE: { var = false; //printf("bool: 'false'\n"); } break; } params.AddValue(var); } } GCValue ScriptServer::GetZeitgeistObject(boost::shared_ptr<Leaf> leaf) { GCValue v; if (leaf.get() != 0) { stringstream ss; ss << "ZeitgeistObject.new(" << (unsigned long) leaf.get() <<")"; v = RbEvalStringWrap(ss.str()); } return v; } VALUE selectObject(VALUE /*self*/, VALUE path) { shared_ptr<Leaf> leaf = gMyPrivateContext->Select(STR2CSTR(path)); return ScriptServer::GetZeitgeistObject(leaf).Get(); } VALUE selectCall(VALUE /*self*/, VALUE functionName, VALUE args) { ParameterList in; getParameterList(args, in); Class::TCmdProc cmd = gMyPrivateContext->GetObject()->GetClass()->GetCmdProc (STR2CSTR(functionName)); GCValue out; if (cmd != 0) { out = cmd(static_cast<Object*>(gMyPrivateContext->GetObject().get()), in); } else { gMyPrivateContext->GetCore()->GetLogServer()->Error() << "(ScriptServer) ERROR: Unknown function '" << STR2CSTR(functionName) << "'" << endl; } return out.Get(); } VALUE thisCall(VALUE /*self*/, VALUE objPointer, VALUE functionName, VALUE args) { ParameterList in; getParameterList(args, in); Object *obj = (Object*)NUM2INT(objPointer); Class::TCmdProc cmd = obj->GetClass()->GetCmdProc(STR2CSTR(functionName)); GCValue out; if (cmd != 0) { out = cmd(obj, in); } else { gMyPrivateContext->GetCore()->GetLogServer()->Error() << "(ScriptServer) ERROR: Unknown function '" << STR2CSTR(functionName) << "'" << endl; } return out.Get(); } VALUE importBundle(VALUE /*self*/, VALUE path) { gMyPrivateContext->GetCore()->ImportBundle(STR2CSTR(path)); return Qnil; } VALUE run (VALUE /*self*/, VALUE file) { gMyPrivateContext->GetCore()->GetScriptServer()->Run(STR2CSTR(file)); return Qnil; } VALUE newObject(VALUE /*self*/, VALUE className, VALUE pathStr) { shared_ptr<Leaf> leaf = gMyPrivateContext->New(STR2CSTR(className), STR2CSTR(pathStr)); return ScriptServer::GetZeitgeistObject(leaf).Get(); } VALUE deleteObject(VALUE /*self*/, VALUE name) { gMyPrivateContext->Delete(STR2CSTR(name)); return Qnil; } VALUE getObject(VALUE /*self*/, VALUE path) { shared_ptr<Leaf> leaf = gMyPrivateContext->Get(STR2CSTR(path)); return ScriptServer::GetZeitgeistObject(leaf).Get(); } VALUE listObjects(VALUE /*self*/) { gMyPrivateContext->ListObjects(); return Qnil; } VALUE pushd(VALUE /*self*/) { gMyPrivateContext->Push(); return Qnil; } VALUE popd(VALUE /*self*/) { gMyPrivateContext->Pop(); return Qnil; } VALUE dirs(VALUE /*self*/) { gMyPrivateContext->Dir(); return Qnil; } ScriptServer::ScriptServer() { ruby_init(); // register built-in commands rb_define_global_function("selectObject", RUBY_METHOD_FUNC(selectObject), 1); rb_define_global_function("selectCall", RUBY_METHOD_FUNC(selectCall), 2); rb_define_global_function("thisCall", RUBY_METHOD_FUNC(thisCall), 3); rb_define_global_function("importBundle", RUBY_METHOD_FUNC(importBundle), 1); rb_define_global_function("run", RUBY_METHOD_FUNC(run), 1); rb_define_global_function("new", RUBY_METHOD_FUNC(newObject), 2); rb_define_global_function("delete", RUBY_METHOD_FUNC(deleteObject), 1); rb_define_global_function("get", RUBY_METHOD_FUNC(getObject), 1); rb_define_global_function("ls", RUBY_METHOD_FUNC(listObjects), 0); rb_define_global_function("pushd", RUBY_METHOD_FUNC(pushd), 0); rb_define_global_function("popd", RUBY_METHOD_FUNC(popd), 0); rb_define_global_function("dirs", RUBY_METHOD_FUNC(dirs), 0); mRelPathPrefix = "../../"; } ScriptServer::~ScriptServer() { } void ScriptServer::UpdateCachedAllNodes() { GetLog()->Debug() << "(ScriptServer) updating cached script variables\n"; GetCore()->GetRoot()->UpdateCached(); } bool ScriptServer::Run(shared_ptr<salt::RFile> file) { if (file.get() == 0) { return false; } boost::scoped_array<char> buffer(new char[file->Size() + 1]); file->Read(buffer.get(), file->Size()); buffer[file->Size()] = 0; bool ok = Eval(buffer.get()); UpdateCachedAllNodes(); return ok; } bool ScriptServer::Run(const string &fileName) { shared_ptr<salt::RFile> file = GetFile()->Open(fileName.c_str()); if (file.get() == 0) { GetLog()->Error() << "(ScriptServer) ERROR: Cannot locate file '" << fileName << "'\n"; return false; } GetLog()->Debug() << "(ScriptServer) Running " << fileName << endl; return Run(file); } bool ScriptServer::Eval(const string &command) { int error; RbEvalStringWrap(command,error); return (error == 0); } bool ScriptServer::Eval(const std::string &command, GCValue& value) { int error; value = RbEvalStringWrap(command,error); return (error == 0); } void ScriptServer::CreateVariable(const string &varName, int value) { // create a string with: "createVariable 'varName', value" stringstream s; s << "createVariable('" << varName << "', " << value << ")"; Eval(s.str()); } void ScriptServer::CreateVariable(const string &varName, float value) { // create a string with: "createVariable 'ns', 'varName', value" stringstream s; s << "createVariable('" << varName << "', " << value << ")"; Eval(s.str()); } void ScriptServer::CreateVariable(const string &varName, const string &value) { // create a string with: "createVariable 'ns', 'varName', 'value'" stringstream s; s << "createVariable('" << varName << "', '" << value << "')"; Eval(s.str()); } bool ScriptServer::ParseVarName(const string& varName, string& nameSpace, string& name) { stringstream ss(varName); string current; vector<string> tokens; // segment varName while(! ss.eof()) { getline(ss, current,'.'); if (current.size()) { tokens.push_back(current); } } if (tokens.size() != 2) { return false; } nameSpace = tokens[0]; name = tokens[1]; return ( (nameSpace.size() >= 1) && (nameSpace[0] >= 'A') && (nameSpace[0] <= 'Z') && (name.size() >= 1) && (name[0] >= 'A') && (name[0] <= 'Z') ); } bool ScriptServer::ExistsVariable(const string &varName) { return (! GetVariable(varName).IsNil()); } GCValue ScriptServer::GetVariable(const string &varName) { string nameSpace; string name; if (! ParseVarName(varName,nameSpace,name)) { return GCValue(); } GCValue v; if (nameSpace != "") { // get namespace class GCValue ns = rb_const_get(rb_cObject, rb_intern(nameSpace.c_str())); if (! ns.IsNil()) { // get member variable of namespace object ID var = rb_intern(name.c_str()); int error; RbArguments arg(ns.Get(), var, 0, 0); v = rb_protect( RbFuncallWrap, reinterpret_cast<VALUE>(&arg), &error ); if (error) { GetLog()->Debug() << "(ScriptServer) Ruby ERROR: " << RbGetError() << "\n"; v = Qnil; } } } else { v = rb_const_get(rb_cObject, rb_intern(name.c_str())); } return v; } bool ScriptServer::GetVariable(const string &varName, int &value) { return GetVariable(varName).GetInt(value); } bool ScriptServer::GetVariable(const std::string &varName, float &value) { return GetVariable(varName).GetFloat(value); } bool ScriptServer::GetVariable(const string &varName, bool &value) { return GetVariable(varName).GetBool(value); } bool ScriptServer::GetVariable(const string &varName, string &value) { return GetVariable(varName).GetString(value); } boost::shared_ptr<CoreContext> ScriptServer::GetContext() const { return gMyPrivateContext; } bool ScriptServer::ConstructInternal() { if (! Leaf::ConstructInternal()) { return false; } gMyPrivateContext = GetCore()->CreateContext(); return true; } void ScriptServer::SetInitRelPathPrefix(const std::string &relPathPrefix) { mRelPathPrefix = relPathPrefix; } bool ScriptServer::RunInitScriptInternal(const string &sourceDir, const string &name, bool copy, const string& destDir) { // run the init script in the sourceDir string sourcePath = sourceDir + "/" + name; GetLog()->Debug() << "(ScriptServer) Running " << sourcePath << "... "; shared_ptr<salt::StdFile> file(new(salt::StdFile)); if ( (! file->Open(sourcePath.c_str())) || (! Run(file)) ) { GetLog()->Debug() << "failed" << endl; return false; } else { GetLog()->Debug() << "ok" << endl; } // copy it to the destDir if (! copy) { return true; } string destPath = destDir + "/" + name; GetLog()->Normal() << "Copying " << sourcePath << " to " << destPath << endl; stringstream s; s << "cp " << sourcePath << " " << destPath; system(s.str().c_str()); return true; } bool ScriptServer::GetDotDirName(string& dotDir) { if (mDotName == "") { GetLog()->Warning() << "(ScriptServer) WARNING: Dot directory name unset.\n"; return false; } char* home = getenv("HOME"); if (!home) { GetLog()->Warning() << "(ScriptServer) WARNING: $HOME is unset.\n"; return false; } dotDir = string(home) + "/" + mDotName; return true; } bool ScriptServer::CreateDotDir(const string& dotDir) { char cwd[PATH_MAX+1]; if (getcwd(cwd,sizeof(cwd)) == NULL) { GetLog()->Error() << "(ScriptServer) ERROR: Cannot get current directory\n"; return false; } if (chdir(dotDir.c_str()) == 0) { // dot dir exists; change back to original directory chdir(cwd); return true; } // dot dir is not existent, try to create it if (mkdir(dotDir.c_str(),0777) != 0) { GetLog()->Error() << "(ScriptServer) ERROR: Cannot create directory '" << dotDir << "'\n"; return false; } GetLog()->Normal() << "(ScriptServer) Created Directory '" << dotDir << "'\n"; return true; } bool ScriptServer::RunInitScript(const string &fileName, const string &relPath, EInitScriptType type) { string dotDir; bool validDotDir = (type == IS_USERLOCAL) && GetDotDirName(dotDir) && CreateDotDir(dotDir); // some macro magic (not at all) string pkgdatadir = PREFIX "/share/" PACKAGE_NAME; bool ok = ( ( (validDotDir) && (RunInitScriptInternal(dotDir, fileName, false)) ) || (RunInitScriptInternal(pkgdatadir, fileName, validDotDir, dotDir)) || (RunInitScriptInternal(mRelPathPrefix+relPath, fileName, validDotDir, dotDir)) ); if (! ok) { GetLog()->Error() << "(ScriptServer) ERROR: Cannot locate init script '" << fileName << "'\n"; } return ok; } --- NEW FILE: rubywrapper.h --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2002,2003 Koblenz University Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group $Id: rubywrapper.h,v 1.1 2005/12/05 21:05:01 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program 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 GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef ZEITGEIST_RUBYWRAPPER_H #define ZEITGEIST_RUBYWRAPPER_H // // Both <ruby.h> and "config.h" define PACKAGE_ constants. // To suppress compiler warnings about redefinitions they // are #undef'ed in this wrapper // #undef PACKAGE_BUGREPORT #undef PACKAGE_NAME #undef PACKAGE_STRING #undef PACKAGE_TARNAME #undef PACKAGE_VERSION #ifndef __GNUC__ #define EXTERN extern __declspec(dllimport) #endif #include <ruby.h> #undef EXTERN #undef PACKAGE_BUGREPORT #undef PACKAGE_NAME #undef PACKAGE_STRING #undef PACKAGE_TARNAME #undef PACKAGE_VERSION #include <iostream> namespace zeitgeist { /** RbArguments is a structure that describes a ruby function call. \param recv is the ruby object that receives the function call \param id is the ruby id of the receiver member function \param n is the number of parameters passed \param *argv is a pointer to an array containnig the function parameters */ struct RbArguments { VALUE recv; ID id; int n; VALUE *argv; RbArguments(VALUE recv, ID id, int n, VALUE *argv) : recv(recv), id(id), n(n), argv(argv) {}; }; /** a functor for the rb_protect function, used to safely excecute ruby code */ VALUE RbFuncallWrap(VALUE arg); /** calls a safe rb_eval_string variant and prints any ruby error messages along with a backtrace to stdout */ VALUE RbEvalStringWrap(const std::string& str); /** calls a safe rb_eval_string variant and prints any ruby error messages along with a backtrace to stdout. The error code returned from ruby is stored in the 'error' parameter. */ VALUE RbEvalStringWrap(const std::string& str, int& error); /** qeuries ruby for a string that describes the last error */ std::string RbGetError(); /** prints the last ruby error to stdout along with a backtrace */ void RbPrintError(); }; #endif // ZEITGEIST_RUBYWRAPPER_H --- NEW FILE: scriptserver_c.cpp --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2002,2003 Koblenz University Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group $Id: scriptserver_c.cpp,v 1.1 2005/12/05 21:05:01 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program 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 GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "scriptserver.h" using namespace zeitgeist; void CLASS(ScriptServer)::DefineClass() { DEFINE_BASECLASS(zeitgeist/Leaf); } --- NEW FILE: gcvalue.cpp --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2002,2003 Koblenz University Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group $Id: gcvalue.cpp,v 1.1 2005/12/05 21:05:01 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program 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 GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "gcvalue.h" #include <sstream> using namespace zeitgeist; using namespace std; GCValue::GCValue() { mValue = Qnil; } GCValue::GCValue(const GCValue& value) { mValue = Qnil; Set(value.mValue); } GCValue::GCValue(VALUE v) { mValue = Qnil; Set(v); } GCValue::GCValue(bool b) { mValue = Qnil; Set(b ? Qtrue:Qfalse); } GCValue::GCValue(const string& str) { mValue = Qnil; Set(rb_str_new2(str.c_str())); } GCValue::GCValue(const char* str) { mValue = Qnil; Set(rb_str_new2(str)); } GCValue::GCValue(float f) { mValue = Qnil; Set(rb_float_new(f)); } GCValue::GCValue(int i) { mValue = Qnil; Set(rb_int_new(i)); } GCValue::~GCValue() { GC_Unregister(); } void GCValue::operator = (const GCValue& value) { mValue = Qnil; Set(value.mValue); } void GCValue::operator = (const VALUE& value) { mValue = Qnil; Set(value); } VALUE GCValue::Get() { return mValue; } void GCValue::Set(VALUE v) { GC_Unregister(); mValue = v; GC_Register(); } bool GCValue::IsNil() { return NIL_P(mValue); } bool GCValue::GetInt(int& value) { if (IsNil()) { return false; } value = NUM2INT(mValue); return true; } bool GCValue::GetFloat(float& value) { if (IsNil()) { return false; } value = (float)NUM2DBL(mValue); return true; } bool GCValue::GetBool(bool& value) { if (IsNil()) { return false; } switch(TYPE(mValue)) { case T_TRUE : value = true; return true; case T_FALSE : value = false; return true; default: return false; } } bool GCValue::GetString(std::string& value) { if (IsNil()) { return false; } switch(TYPE(mValue)) { case T_STRING: { value = STR2CSTR(mValue); return true; } case T_FLOAT: { stringstream ss; ss << (float)NUM2DBL(mValue); value = ss.str(); return true; } case T_FIXNUM: { stringstream ss; ss << NUM2INT(mValue); value = ss.str(); return true; } default: break; } return false; } void GCValue::GC_Unregister() { if (! IsNil()) { rb_gc_unregister_address(&mValue); } } void GCValue::GC_Register() { if (! IsNil()) { rb_gc_register_address(&mValue); } } --- NEW FILE: rubywrapper.cpp --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2002,2003 Koblenz University Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group $Id: rubywrapper.cpp,v 1.1 2005/12/05 21:05:01 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program 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 GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "rubywrapper.h" VALUE zeitgeist::RbFuncallWrap(VALUE arg) { RbArguments &a = *reinterpret_cast<RbArguments*>(arg); return rb_funcall2(a.recv, a.id, a.n, a.argv); } VALUE zeitgeist::RbEvalStringWrap(const std::string& str, int& error) { VALUE v = rb_eval_string_protect(str.c_str(),&error); if (error) { RbPrintError(); return Qnil; } return v; } VALUE zeitgeist::RbEvalStringWrap(const std::string& str) { int error; return RbEvalStringWrap(str,error); } std::string zeitgeist::RbGetError() { VALUE mes = rb_inspect(rb_gv_get("$!")); return RSTRING(mes)->ptr; } void zeitgeist::RbPrintError() { std::cout << RbGetError() << std::endl; rb_backtrace(); } --- NEW FILE: scriptserver.h --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2002,2003 Koblenz University Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group $Id: scriptserver.h,v 1.1 2005/12/05 21:05:01 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program 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 GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ScriptServer :TODO: Class description for ScriptServer HISTORY: 09.07.2002 MK - initial version */ #ifndef ZEITGEIST_SCRIPTSERVER_H #define ZEITGEIST_SCRIPTSERVER_H #include <zeitgeist/leaf.h> #include <zeitgeist/class.h> #include <salt/fileclasses.h> #include "gcvalue.h" namespace zeitgeist { class CoreContext; /** The ScriptServer provides scripting facilities to the zeitgeist framework. Up to now is realized using Ruby, though the ScritpServer could easily be extended to support other script languages. */ class ScriptServer : public Leaf { // // types // public: enum EInitScriptType { IS_COMMON, // the init script is common for all users, // i.e. it won't be copied to the local dot // directory IS_USERLOCAL // the init script is local to the user, i.e // it will be copied to the user's dot // direcotry }; protected: private: // // functions // public: /** constructs the ScriptServer */ ScriptServer(); virtual ~ScriptServer(); /** loads and runs a ruby script, returns true on success */ bool Run(const std::string &fileName); /** loads and runs a ruby script from an RFile */ bool Run(boost::shared_ptr<salt::RFile> file); /** sets the relative path prefix RunInitScript() searches for an InitScript. Default is '../../', suitable for all applications started from '/app' */ void SetInitRelPathPrefix(const std::string &relPathPrefix); /** searches in ~/<mDotName>/ if dotScript is true, * PREFIX/share/PACKAGE_NAME/ and <mRelPathPrefix><relPath>/ for * the script <fileName>. If found the script is run and if * dotScript is true copied to ~/<dotName>/. If this directory is * missing it is automatically created */ bool RunInitScript(const std::string &fileName, const std::string &relPath, EInitScriptType type = IS_USERLOCAL); /** sets name of the dot directory */ void SetDotName(const std::string &dotName) { mDotName = dotName; } /** evaluates a ruby statement, returns true on success */ bool Eval(const std::string &command); /** evaluates a ruby statement, returns true on success; \param value receives the result value if any */ bool Eval(const std::string &command, GCValue& value); void UpdateCachedAllNodes(); // script variable functions /** returns true if the variable varName exists */ bool ExistsVariable(const std::string &varName); /** creates a ruby integer variable */ void CreateVariable(const std::string &varName, int value); /** creates a ruby float variable */ void CreateVariable(const std::string &varName, float value); /** creates a ruby string variable */ void CreateVariable(const std::string &varName, const std::string &value); /** reads the value of a ruby integer, returns true on success */ bool GetVariable(const std::string &varName, int &value); /** reads the value of a ruby boolean, returns true on success */ bool GetVariable(const std::string &varName, bool &value); /** reads the value of a ruby string, returns true on success */ bool GetVariable(const std::string &varName, std::string &value); /** reads the value of a ruby float, returns true on success */ bool GetVariable(const std::string &varName, float &value); /** returns the context, the ScriptServer operates in */ boost::shared_ptr<CoreContext> GetContext() const; /** constructs the ZeitgeistObject corresponding to a given leaf */ static GCValue GetZeitgeistObject(boost::shared_ptr<Leaf> leaf); protected: /** initializes the ScriptServer and runs the default startup script 'sys/script/zeitgeist.rb', returning true on success. */ virtual bool ConstructInternal(); /** parses a ruby variable into a namespace and variable name part. Valid variable names are 'Namespace.Name'. \returns true if a valid variable name was parsed \param varName is the variable name to parse \param nameSpace receives the namespace \param name receives the variable name */ bool ParseVarName(const std::string& varName, std::string& nameSpace, std::string& name); /** returns the content of a variable*/ GCValue GetVariable(const std::string &varName); /** private helper function */ bool RunInitScriptInternal(const std::string &dir, const std::string &name, bool copy, const std::string& destDir = ""); /** construct the path of the local dot directory that contains the users init scripts */ bool GetDotDirName(std::string& dotDir); /** checks if the directory <dotDir> exists and if not creates it */ bool CreateDotDir(const std::string& dotDir); private: ScriptServer(const ScriptServer& obj); ScriptServer& operator=(const ScriptServer& obj); // // members // public: protected: /** the name of the users dot directory, used by ::RunInitScript to search * for script files: ~/<mDotName> */ std::string mDotName; /** the prefix RunInitScript() prepends all relativ paths */ std::string mRelPathPrefix; private: }; DECLARE_CLASS(ScriptServer); } //namespace zeitgeist #endif //ZEITGEIST_SCRIPTSERVER_H --- NEW FILE: gcvalue.h --- /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- this file is part of rcssserver3D Fri May 9 2003 Copyright (C) 2002,2003 Koblenz University Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group $Id: gcvalue.h,v 1.1 2005/12/05 21:05:01 rollmark Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program 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 GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef ZEITGEIST_GCVALUE_H #define ZEITGEIST_GCVALUE_H #include <zeitgeist/scriptserver/rubywrapper.h> namespace zeitgeist { /** \class GCValue is a ruby VALUE wrapper. It is responsible to register and unregister the wrapped value as busy with the ruby garbage collector. The ruby garbage collector might be transparently invoked on any call to ruby. If a returned VALUE must stay valid during a series of ruby function calls you should use this wrapper. A simple use case is a VALUE returned from ruby that is used as an argument in a subsequent function call. This wrapper also provides some helpers to access and convert the stored value. */ class GCValue { public: GCValue(); GCValue(const GCValue& value); GCValue(VALUE v); /** constructs the corresponding ruby boolean */ GCValue(bool b); /** constructs a new ruby string object */ GCValue(const std::string& str); /** constructs a new ruby string object */ GCValue(const char* str); /** constructs a new ruby float object */ GCValue(float f); /** constructs a new riby int object */ GCValue(int i); ~GCValue(); void operator = (const GCValue& value); void operator = (const VALUE& value); /** returns the stored ruby VALUE */ VALUE Get(); /** sets the setored value to v. Any previously stored value is properly unregistered */ void Set(VALUE v); /** returns true if the stored value equals QNil */ bool IsNil(); /** tries to convert the stored value to an integer value, returns true on success */ bool GetInt(int& value); /** tries to convert the stored value to a float value, returns true on success */ bool GetFloat(float& value); /** tries to convert the stored value to a bool value, returns true on success */ bool GetBool(bool& value); /** tries to convert the stored value to a string, returns true on success */ bool GetString(std::string& value); protected: /** unregisters the stored VALUE from the ruby garbage collector, i.e marks mValue no longer as busy */ void GC_Unregister(); /** registers the stored VALUE to the ruby garbage collector, i.e. marks it as busy */ void GC_Register(); protected: /** the wrapped ruby VALUE */ VALUE mValue; }; } // namespace zeitgeist #endif // ZEITGEIST_GCVALUE_H |