29 #include "scriptstdstring/scriptstdstring.h"
30 #include "scriptmath/scriptmath.h"
31 #include "scriptany/scriptany.h"
32 #include "scriptarray/scriptarray.h"
33 #include "scripthelper/scripthelper.h"
38 #include <curl/curl.h>
40 #include <curl/easy.h>
64 using namespace AngelScript;
70 case ScriptCategory::INVALID:
return "INVALID";
71 case ScriptCategory::ACTOR:
return "ACTOR";
72 case ScriptCategory::TERRAIN:
return "TERRAIN";
73 case ScriptCategory::CUSTOM:
return "CUSTOM";
78 ScriptUnit::ScriptUnit()
83 ScriptUnit::~ScriptUnit()
97 ScriptEngine::ScriptEngine() :
121 SLOG(
"ScriptEngine initializing ...");
125 engine = AngelScript::asCreateScriptEngine(ANGELSCRIPT_VERSION);
127 engine->SetEngineProperty(AngelScript::asEP_ALLOW_UNSAFE_REFERENCES,
true);
136 if (result == AngelScript::asINVALID_ARG)
138 SLOG(
"One of the arguments is incorrect, e.g. obj is null for a class method.");
141 else if (result == AngelScript::asNOT_SUPPORTED)
143 SLOG(
" The arguments are not supported, e.g. asCALL_GENERIC.");
146 SLOG(
"Unkown error while setting up message callback");
154 AngelScript::RegisterScriptArray(
engine,
true);
155 AngelScript::RegisterStdString(
engine);
156 AngelScript::RegisterStdStringUtils(
engine);
157 AngelScript::RegisterScriptMath(
engine);
158 static float SCRIPT_FLT_MAX = FLT_MAX;
159 static int SCRIPT_INT_MAX = INT_MAX;
160 result =
engine->RegisterGlobalProperty(
"const float FLT_MAX", &SCRIPT_FLT_MAX);
ROR_ASSERT( result >= 0 );
161 result =
engine->RegisterGlobalProperty(
"const int INT_MAX", &SCRIPT_INT_MAX);
ROR_ASSERT(result >= 0);
162 AngelScript::RegisterScriptAny(
engine);
163 AngelScript::RegisterScriptDictionary(
engine);
166 result =
engine->RegisterGlobalFunction(
"void log(const string &in)", AngelScript::asFUNCTION(
logString), AngelScript::asCALL_CDECL);
ROR_ASSERT( result >= 0 );
167 result =
engine->RegisterGlobalFunction(
"void print(const string &in)", AngelScript::asFUNCTION(
logString), AngelScript::asCALL_CDECL);
ROR_ASSERT( result >= 0 );
191 SLOG(
"Type registrations done. If you see no error above everything should be working");
198 const char *type =
"Error";
199 if ( msg->type == AngelScript::asMSGTYPE_INFORMATION )
201 else if ( msg->type == AngelScript::asMSGTYPE_WARNING )
205 sprintf(tmp,
"%s (%d, %d): %s = %s", msg->section, msg->row, msg->col, type, msg->message);
210 msg->section, msg->message);
213 std::string
ptr2str(
const char* ptr) {
if (ptr)
return ptr;
else return ""; }
217 std::string funcName, funcObjTypeName, objName;
218 if (ctx->GetFunction())
220 funcName =
ptr2str(ctx->GetFunction()->GetName());
221 objName =
ptr2str(ctx->GetFunction()->GetObjectName());
222 if (ctx->GetFunction()->GetObjectType())
223 funcObjTypeName =
ptr2str(ctx->GetFunction()->GetObjectType()->GetName());
229 funcName, funcObjTypeName, objName
236 std::string funcName;
237 if (ctx->GetExceptionFunction())
239 funcName =
ptr2str(ctx->GetExceptionFunction()->GetName());
243 funcName, ctx->GetExceptionString());
295 SLOG(
fmt::format(
"Warning: Could not attach LineCallback to NID {}, error code {}; continuing without it...", result, nid));
305 SLOG(
fmt::format(
"Warning: Could not attach ExceptionCallback to NID {}, error code {}; continuing without it...", result, nid));
311 int result =
context->Execute();
314 if ( result != AngelScript::asEXECUTION_FINISHED )
317 if ( result == AngelScript::asEXECUTION_ABORTED )
319 SLOG(
"The script was aborted before it could finish. Probably it timed out.");
321 else if ( result == AngelScript::asEXECUTION_EXCEPTION )
325 SLOG(
"The script ended with exception; details below:");
327 SLOG(
"\tcontext.ExceptionLineNumber: " +
TOSTRING(
context->GetExceptionLineNumber()));
328 SLOG(
"\tcontext.ExceptionString: " +
ptr2str(
context->GetExceptionString()));
329 AngelScript::asIScriptFunction* func =
context->GetExceptionFunction();
332 SLOG(
"\tcontext.ExceptionFunction.Declaration: " +
ptr2str(func->GetDeclaration()));
333 SLOG(
"\tcontext.ExceptionFunction.ModuleName: " +
ptr2str(func->GetModuleName()));
334 SLOG(
"\tcontext.ExceptionFunction.ScriptSectionName: " +
ptr2str(func->GetScriptSectionName()));
335 SLOG(
"\tcontext.ExceptionFunction.ObjectName: " +
ptr2str(func->GetObjectName()));
338 else if (result == AngelScript::asCONTEXT_NOT_PREPARED)
342 SLOG(
fmt::format(
"The script ended with error code asCONTEXT_NOT_PREPARED; Function to execute: {},currently triggered event: {}, NID: {}",
347 SLOG(
fmt::format(
"The script ended with error code asCONTEXT_NOT_PREPARED; Function to execute NOT SET,currently triggered event: {}, NID: {}",
353 SLOG(
"The script ended for some unforeseen reason " +
TOSTRING(result));
359 context->ClearExceptionCallback();
366 asIScriptFunction* scriptFunc = this->
engine->GetFunctionById(asFunctionID);
369 SLOG(
fmt::format(
"Cannot execute script function with ID {} - not found", asFunctionID));
373 int result = this->
context->Prepare(scriptFunc);
376 SLOG(
fmt::format(
"Cannot execute script function '{}': `AngelScript::Context::Prepare()` reported error code {}",
377 scriptFunc->GetName(), result));
387 std::vector<String> tmpQueue;
389 std::vector<String>::iterator it;
390 for (it=tmpQueue.begin(); it!=tmpQueue.end();it++)
421 AngelScript::asIScriptFunction* func =
m_script_units[id].scriptModule->GetFunctionByDecl(
422 "void fireEvent(string, float)");
427 context->SetArgObject(0, &instanceName);
428 context->SetArgFloat (1, intensity);
433 if ( r == AngelScript::asEXECUTION_FINISHED )
436 AngelScript::asDWORD ret =
context->GetReturnDWord();
455 int functionId = _functionId;
456 if (functionId <= 0 && (
m_script_units[
id].defaultEventCallbackFunctionPtr !=
nullptr))
459 functionId =
m_script_units[id].defaultEventCallbackFunctionPtr->GetId();
465 context->SetArgDWord (0, type);
469 context->SetArgDWord (3,
static_cast<AngelScript::asDWORD
>(nodenum));
471 context->SetArgDWord (3,
static_cast<AngelScript::asDWORD
>(-1));
493 int result = ExecuteString(
engine, command.c_str(), mod,
context);
496 SLOG(
"error " +
TOSTRING(result) +
" while executing string: " + command +
".");
515 AngelScript::asIScriptFunction *func = 0;
516 int r = mod->CompileFunction(
"addfunc", arg.c_str(), 0, AngelScript::asCOMP_ADD_TO_MODULE, &func);
521 snprintf(tmp, 512,
"An error occurred while trying to add a function ('%s') to script module '%s'.", arg.c_str(), mod->GetName());
528 if (func == mod->GetFunctionByDecl(
"void frameStep(float)"))
533 else if (func == mod->GetFunctionByDecl(
"void eventCallback(int, int)"))
538 else if (func == mod->GetFunctionByDecl(
"void eventCallbackEx(scriptEvents, int, int, int, int, string, string, string, string)"))
573 return AngelScript::asNO_FUNCTION;
577 AngelScript::asIScriptFunction* fn = mod->GetFunctionByDecl(arg.c_str());
581 return AngelScript::asNO_FUNCTION;
588 return AngelScript::asERROR;
596 if ( mod->GetFunctionCount() == 0 )
599 sprintf(tmp,
"An error occurred while trying to remove a function ('%s') from script module '%s': No functions have been added (and consequently: the function does not exist).", arg.c_str(), mod->GetName());
601 return AngelScript::asNO_FUNCTION;
604 AngelScript::asIScriptFunction* func = mod->GetFunctionByDecl(arg.c_str());
608 mod->RemoveFunction(func);
628 return func->GetId();
633 sprintf(tmp,
"An error occurred while trying to remove a function ('%s') from script module '%s'.", arg.c_str(), mod->GetName());
635 return AngelScript::asERROR;
648 int r = mod->CompileGlobalVar(
"addvar", arg.c_str(), 0);
652 sprintf(tmp,
"An error occurred while trying to add a variable ('%s') to script module '%s'.", arg.c_str(), mod->GetName());
667 if ( mod == 0 || mod->GetGlobalVarCount() == 0 )
670 sprintf(tmp,
"An error occurred while trying to remove a variable ('%s') from script module '%s': No variables have been added (and consequently: the variable does not exist).", arg.c_str(), mod->GetName());
672 return AngelScript::asNO_GLOBAL_VAR;
675 int index = mod->GetGlobalVarIndexByName(arg.c_str());
678 index = mod->RemoveGlobalVar(index);
683 sprintf(tmp,
"An error occurred while trying to remove a variable ('%s') from script module '%s'.", arg.c_str(), mod->GetName());
692 std::string decl =
fmt::format(fmtFuncDecl, funcName);
693 asIScriptFunction* retval =
m_script_units[nid].scriptModule->GetFunctionByDecl(decl.c_str());
696 asIScriptFunction* candidate =
m_script_units[nid].scriptModule->GetFunctionByName(funcName.c_str());
699 SLOG(
fmt::format(
"Warning: a callback function with signature '{}' was not found"
700 " but a function with given name exists: '{}' - did you make a typo in arguments?",
701 decl, candidate->GetDeclaration()));
705 SLOG(
fmt::format(
"Warning: a callback function with signature '{}' was not found",
719 asIScriptFunction* callback =
m_script_units[id].eventCallbackExFunctionPtr;
732 context->SetArgDWord(0, eventnum);
737 context->SetArgDWord(2, arg2ex);
738 context->SetArgDWord(3, arg3ex);
739 context->SetArgDWord(4, arg4ex);
740 context->SetArgObject(5, &arg5ex);
741 context->SetArgObject(6, &arg6ex);
742 context->SetArgObject(7, &arg7ex);
743 context->SetArgObject(8, &arg8ex);
761 ActorPtr associatedActor , std::string buffer )
822 result = builder.StartNewModule(
engine, moduleName.c_str());
826 fmt::format(
"Could not load script '{}' - failed to create module.", moduleName));
829 m_script_units[unit_id].scriptModule =
engine->GetModule(moduleName.c_str(), AngelScript::asGM_ONLY_IF_EXISTS);
838 fmt::format(
"Could not load script '{}' - failed to create global variable `thisActor`.", moduleName));
845 fmt::format(
"const int thisScript = {};", unit_id).c_str());
849 fmt::format(
"Could not load script '{}' - failed to create global variable `thisScript`.", moduleName));
860 fmt::format(
"Could not load script '{}' from buffer", moduleName));
867 result = builder.AddSectionFromFile(
m_script_units[unit_id].scriptName.c_str());
871 fmt::format(
"Could not load script '{}' - failed to process file.", moduleName));
881 result = builder.BuildModule();
886 fmt::format(
"Could not load script '{}' - failed to build module. See 'Angelscript.log' for more info.", moduleName));
892 scriptHash = builder.
GetHash();
897 m_script_units[unit_id].eventCallbackFunctionPtr =
m_script_units[unit_id].scriptModule->GetFunctionByDecl(
"void eventCallback(int, int)");
898 m_script_units[unit_id].eventCallbackExFunctionPtr =
m_script_units[unit_id].scriptModule->GetFunctionByDecl(
"void eventCallbackEx(scriptEvents, int, int, int, int, string, string, string, string)");
905 auto main_func =
m_script_units[unit_id].scriptModule->GetFunctionByDecl(
"void main()");
906 if ( main_func ==
nullptr )
917 result =
context->Prepare(main_func);
921 fmt::format(
"Could not load script '{}' - failed to build module.", moduleName));
929 int var_index =
m_script_units[unit_id].scriptModule->GetGlobalVarIndexByName(
"thisActor");
932 SLOG(
"Could not find global var `thisActor`");
938 if (thisActorAddr ==
nullptr)
940 SLOG(
"Could not retrieve address of global var `thisActor`");
943 *thisActorAddr =
m_script_units[unit_id].associatedActor.GetRef();
944 (*thisActorAddr)->AddRef();
949 SLOG(
fmt::format(
"Executing main() in {}", moduleName));
951 if ( mainfunc_result != AngelScript::asEXECUTION_FINISHED )
954 fmt::format(
"Could not load script '{}' - error running function `main()`, check AngelScript.log", moduleName));
958 SLOG(
"The script finished successfully.");
961 return mainfunc_result;