00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "ScriptEngine.h"
00018 #include "Log.h"
00019 #include "events/EngineEvent.h"
00020 #include "EventManager.h"
00021 #include "VariadicArgument.h"
00022 #include "IScript.h"
00023
00024 namespace nrEngine{
00025
00026
00027 ScriptFunctionDec(scriptLoad, ScriptEngine)
00028 {
00029
00030 if (args.size() < 2){
00031 return ScriptResult(std::string("Not valid parameter count! Parameters (name, filename)"));
00032 }
00033
00034
00035 IResourcePtr ptr = Engine::sScriptEngine()->load(args[1], args[2]);
00036
00037 if (ptr.isNull())
00038 {
00039 return ScriptResult(std::string("Can not load script ") + args[1] + " from file " + args[2]);
00040 }
00041
00042 return ScriptResult();
00043 }
00044
00045
00046 ScriptFunctionDec(scriptRun, ScriptEngine)
00047 {
00048
00049 if (args.size() < 1){
00050 return ScriptResult(std::string("Not valid parameter count! Parameters (name [, runonce = true [, immediate = false]])"));
00051 }
00052
00053
00054 try{
00055 const std::string& name = args[1];
00056 bool once = true;
00057 if (args.size() > 2) once = boost::lexical_cast<bool>(args[2]);
00058 bool force = false;
00059 if (args.size() > 3) force = boost::lexical_cast<bool>(args[3]);
00060
00061
00062 if (!Engine::sScriptEngine()->execute(name, once, force))
00063 return ScriptResult(std::string("Can not execute script ") + name);
00064 }catch(boost::bad_lexical_cast s){
00065 return ScriptResult(std::string("Wrong parameter value! "));
00066 }
00067
00068 return ScriptResult();
00069 }
00070
00071
00072 ScriptFunctionDec(scriptLoadAndRun, ScriptEngine)
00073 {
00074
00075 if (args.size() < 2){
00076 return ScriptResult(std::string("Not valid parameter count! Parameters (name, filename)"));
00077 }
00078
00079
00080 const std::string& name = args[1];
00081 const std::string& fileName = args[2];
00082
00083
00084 std::vector<std::string> arg;
00085 arg.push_back(args[0]);
00086 arg.push_back(name);
00087 arg.push_back(fileName);
00088
00089
00090 ScriptResult res = scriptLoad(arg, param);
00091
00092
00093 arg.pop_back();
00094
00095
00096 if (res.size() == 0) res = scriptRun(arg, param);
00097
00098 return res;
00099 }
00100
00101
00102 ScriptFunctionDec(scriptCall, ScriptEngine)
00103 {
00104
00105 if (args.size() < 2){
00106 return ScriptResult(std::string("Not valid parameter count! Parameters (name, funcname, [, param1, ..., paramn])"));
00107 }
00108
00109 IScript::ArgumentList ar;
00110
00111
00112 if (args.size() >= 3 )
00113 {
00114 for (uint32 i=3; i < args.size(); i++)
00115 {
00116
00117 std::string param = args[i];
00118
00119
00120 std::string::size_type pos = param.find(':');
00121 if (pos == std::string::npos)
00122 {
00123 char msg[4096];
00124 sprintf(msg, "ScriptEngine: Parameter %s does not contain type information", param.c_str());
00125 return ScriptResult(std::string(msg));
00126 }
00127
00128
00129 std::string type = param.substr(pos + 1);
00130 std::string value = param.substr(0, pos);
00131
00132
00133 ar.push_back(std::pair<std::string, std::string>(type, value));
00134 }
00135 }
00136
00137
00138 ResourcePtr<IScript> ptr = Engine::sResourceManager()->getByName(args[1]);
00139 if (ptr.isNull())
00140 return ScriptResult(std::string("Can not find script ") + args[1]);
00141
00142
00143 ptr->setArguments(args[2], ar);
00144 ScriptResult res;
00145 ptr->call(args[2]);
00146
00147
00148 return res;
00149 }
00150
00151
00152 ScriptEngine::ScriptEngine(){
00153 mDatabase["scriptLoad"].first = scriptLoad;
00154 mDatabase["scriptRun"].first = scriptRun;
00155 mDatabase["scriptExecute"].first = scriptRun;
00156 mDatabase["scriptCall"].first = scriptCall;
00157 mDatabase["scriptLoadAndRun"].first = scriptLoadAndRun;
00158 }
00159
00160
00161 ScriptEngine::~ScriptEngine(){
00162
00163
00164 mDatabase.clear();
00165
00166 }
00167
00168
00169 Result ScriptEngine::add(const std::string& name, ScriptFunctor func, const std::vector<ScriptParam>& param)
00170 {
00171
00172 if (isRegistered(name))
00173 return SCRIPT_FUNCTION_REGISTERED;
00174
00175
00176 mDatabase[name].first = func;
00177 mDatabase[name].second = param;
00178
00179
00180 NR_Log(Log::LOG_ENGINE, Log::LL_DEBUG, "ScriptEngine: New function \"%s\" registered", name.c_str());
00181
00182
00183 SharedPtr<Event> msg(new ScriptRegisterFunctionEvent(name, func));
00184 Engine::sEventManager()->emitSystem(msg);
00185
00186 return OK;
00187 }
00188
00189
00190 Result ScriptEngine::add(const std::string& name, ScriptFunctor func, const VarArg& v){
00191
00192
00193 std::vector<ScriptParam> p;
00194 v.convert<ScriptParam>(p);
00195
00196
00197 return add(name, func, p);
00198 }
00199
00200
00201 Result ScriptEngine::del(const std::string& name)
00202 {
00203
00204 FunctionDatabase::iterator it = mDatabase.find(name);
00205 if (it == mDatabase.end()) return SCRIPT_FUNCTION_NOT_REGISTERED;
00206
00207 mDatabase.erase(it);
00208
00209
00210 NR_Log(Log::LOG_ENGINE, Log::LL_DEBUG, "ScriptEngine: Function \"%s\" was removed", name.c_str());
00211
00212
00213 SharedPtr<Event> msg(new ScriptRemoveFunctionEvent(name));
00214 Engine::sEventManager()->emitSystem(msg);
00215
00216 return OK;
00217 }
00218
00219
00220 ScriptResult ScriptEngine::call(const std::string& name, const std::vector<std::string>& args)
00221 {
00222
00223 FunctionDatabase::iterator f = get(name);
00224 if (f == mDatabase.end()){
00225 NR_Log(Log::LOG_ENGINE, Log::LL_WARNING, "ScriptEngine: Function \"%s\" was not found!", name.c_str());
00226 return ScriptResult();
00227 }
00228
00229
00230 std::string msg;
00231 for (unsigned int i=1; i < args.size(); i++) msg += std::string(" ") + args[i];
00232 NR_Log(Log::LOG_ENGINE, Log::LL_DEBUG, "ScriptEngine: Call \"%s (%s)\" function!", name.c_str(), msg.c_str());
00233
00234
00235 return ((*f).second).first(args, (*f).second.second);
00236 }
00237
00238
00239 bool ScriptEngine::isRegistered(const std::string& name)
00240 {
00241
00242 FunctionDatabase::const_iterator it = mDatabase.find(name);
00243 return it != mDatabase.end();
00244 }
00245
00246
00247 ScriptEngine::FunctionDatabase::iterator ScriptEngine::get(const std::string& name)
00248 {
00249
00250 FunctionDatabase::iterator it = mDatabase.find(name);
00251
00252 return it;
00253 }
00254
00255
00256 ResourcePtr<IScript> ScriptEngine::load(const std::string& name, const std::string& file)
00257 {
00258
00259 ResourcePtr<IScript> plg = Engine::sResourceManager()->loadResource(name, "Scripts", file);
00260
00261 if (plg.isNull()){
00262 NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "Can not load the script %s from %s", name.c_str(), file.c_str());
00263 }
00264 return plg;
00265 }
00266
00267
00268
00269 Result ScriptEngine::execute(const std::string& name, bool runOnce, bool immediate)
00270 {
00271
00272 ResourcePtr<IScript> scr = Engine::sResourceManager()->getByName(name);
00273 return _execute(scr, runOnce, immediate);
00274 }
00275
00276
00277 Result ScriptEngine::execute(const std::string& name, const std::string& fileName, bool runOnce, bool immediate)
00278 {
00279 ResourcePtr<IScript> scr = load(name, fileName);
00280 return _execute(scr, runOnce, immediate);
00281 }
00282
00283
00284 Result ScriptEngine::_execute(const ResourcePtr<IScript>& ptr, bool runOnce, bool immediate)
00285 {
00286 if (ptr.isNull()) return RES_NOT_FOUND;
00287 if (immediate) return ptr->forceExecute(runOnce);
00288 return ptr->execute(runOnce);
00289 }
00290
00291
00292 const std::string& ScriptEngine::getFunction(uint32 index, ScriptFunctor& functor)
00293 {
00294 NR_ASSERT(index < getFunctionCount());
00295 FunctionDatabase::const_iterator it = mDatabase.begin();
00296 for (uint32 i = 0; i < index; i++, it++){}
00297
00298 functor = it->second.first;
00299 return it->first;
00300 }
00301
00302 };
00303