Leviathan  0.8.0.0
Leviathan game engine
ScriptExecutor.cpp
Go to the documentation of this file.
1 // ------------------------------------ //
2 #include "ScriptExecutor.h"
3 
4 #include "AccessMask.h"
7 #include "ScriptModule.h"
8 #include "ScriptNotifiers.h"
9 
10 #include <add_on/datetime/datetime.h>
11 #include <add_on/scriptany/scriptany.h>
12 #include <add_on/scriptarray/scriptarray.h>
13 #include <add_on/scriptdictionary/scriptdictionary.h>
14 #include <add_on/scriptgrid/scriptgrid.h>
15 #include <add_on/scripthandle/scripthandle.h>
16 #include <add_on/scripthelper/scripthelper.h>
17 #include <add_on/scriptmath/scriptmath.h>
18 #include <add_on/scriptmath/scriptmathcomplex.h>
19 #include <add_on/scriptstdstring/scriptstdstring.h>
20 #include <add_on/weakref/weakref.h>
21 
22 // Bindings
25 #include "Bindings/EntityBind.h"
26 #include "Bindings/GuiScriptBind.h"
27 #include "Bindings/OgreBind.h"
28 #include "Bindings/PhysicsBind.h"
29 #include "Bindings/TypesBind.h"
30 
31 // Exception support
32 #include "OgreException.h"
33 
34 using namespace Leviathan;
35 // ------------------------------------ //
36 namespace Leviathan {
37 
38 void ScriptMessageCallback(const asSMessageInfo* msg, void* param)
39 {
40 
41  if(msg->type == asMSGTYPE_WARNING) {
42 
43  Logger::Get()->Write(std::string("[SCRIPT] [WARNING] ") + msg->section + " (" +
44  std::to_string(msg->row) + ", " + std::to_string(msg->col) +
45  ") : " + msg->message);
46 
47  } else if(msg->type == asMSGTYPE_INFORMATION) {
48 
49  Logger::Get()->Write(std::string("[SCRIPT] [INFO] ") + msg->section + " (" +
50  std::to_string(msg->row) + ", " + std::to_string(msg->col) +
51  ") : " + msg->message);
52 
53  } else {
54 
55  Logger::Get()->Write(std::string("[SCRIPT] [ERROR] ") + msg->section + " (" +
56  std::to_string(msg->row) + ", " + std::to_string(msg->col) +
57  ") : " + msg->message);
58  }
59 }
60 
61 #ifdef ANGELSCRIPT_HAS_TRANSLATE_CALLBACK
62 void ScriptTranslateExceptionCallback(asIScriptContext* context, void* userdata)
63 {
64  try {
65  std::rethrow_exception(std::current_exception());
66 
67  } catch(const Leviathan::InvalidAccess& e) {
68  context->SetException(
69  (std::string("Caught Leviathan::InvalidAccess exception: ") + e.what()).c_str());
70  } catch(const Leviathan::InvalidArgument& e) {
71  context->SetException(
72  (std::string("Caught Leviathan::InvalidArgument exception: ") + e.what()).c_str());
73  } catch(const Leviathan::InvalidState& e) {
74  context->SetException(
75  (std::string("Caught Leviathan::InvalidState exception: ") + e.what()).c_str());
76  } catch(const Leviathan::InvalidType& e) {
77  context->SetException(
78  (std::string("Caught Leviathan::InvalidType exception: ") + e.what()).c_str());
79  } catch(const Leviathan::NotFound& e) {
80  context->SetException(
81  (std::string("Caught Leviathan::NotFound exception: ") + e.what()).c_str());
82  } catch(const Leviathan::NULLPtr& e) {
83  context->SetException(
84  (std::string("Caught Leviathan::NULLPtr exception: ") + e.what()).c_str());
85  } catch(const Leviathan::Exception& e) {
86  context->SetException(
87  (std::string("Caught Leviathan::Exception: ") + e.what()).c_str());
88  } catch(const Ogre::Exception& e) {
89  context->SetException((std::string("Caught Ogre::Exception: ") + e.what()).c_str());
90  } catch(const std::exception& e) {
91  context->SetException(
92  (std::string("Caught (unknown type) application exception: ") + e.what()).c_str());
93  } catch(...) {
94  // Use default message
95  }
96 }
97 #endif // ANGELSCRIPT_HAS_TRANSLATE_CALLBACK
98 
99 asIScriptContext* RequestContextCallback(asIScriptEngine* engine, void* userdata)
100 {
101  return static_cast<ScriptExecutor*>(userdata)->_GetContextForExecution();
102 }
103 
104 void ReturnContextCallback(asIScriptEngine* engine, asIScriptContext* context, void* userdata)
105 {
106  static_cast<ScriptExecutor*>(userdata)->_DoneWithContext(context);
107 }
108 
109 } // namespace Leviathan
110 
111 ScriptExecutor::ScriptExecutor() : engine(nullptr), AllocatedScriptModules()
112 {
113 
114  instance = this;
115 
116  // Initialize AngelScript //
117  engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
118  if(engine == nullptr) {
119 
120  Logger::Get()->Error("ScriptExecutor: Init: asCreateScriptEngine failed");
121  Logger::Get()->Info("ScriptExecutor: tried to init angelscript version " +
122  Convert::ToString(ANGELSCRIPT_VERSION));
123  Logger::Get()->Write("Did you use a wrong angelscript version? copy header files to "
124  "leviathan/Angelscript/include from your angelscript.zip");
125  throw Exception("Failed to init angelscript");
126  }
127 
128  // set callback to error report function //
129  engine->SetMessageCallback(asFUNCTION(ScriptMessageCallback), 0, asCALL_CDECL);
130 
131  // The ScriptExecutor can be retrieved from asIScriptEngine user data
132  engine->SetUserData(this);
133 
134 #ifdef ANGELSCRIPT_HAS_TRANSLATE_CALLBACK
135  // Set error translation callback
136  engine->SetTranslateAppExceptionCallback(
137  asFUNCTION(ScriptTranslateExceptionCallback), nullptr, asCALL_CDECL);
138 #endif // ANGELSCRIPT_HAS_TRANSLATE_CALLBACK
139 
140  // Context pool usage callbacks
141  engine->SetContextCallbacks(RequestContextCallback, ReturnContextCallback, this);
142 
143 
144  // Builtins are in this access group //
145  const auto initialMask =
146  engine->SetDefaultAccessMask(static_cast<AccessFlags>(ScriptAccess::Builtin));
147 
148  // math functions //
149  RegisterScriptMath(engine);
150  RegisterScriptMathComplex(engine);
151 
152  // register script string type //
153  RegisterStdString(engine);
154  RegisterScriptArray(engine, true);
155  // register other script extensions //
156  RegisterStdStringUtils(engine);
157 
158 
159  RegisterScriptDateTime(engine);
160 
161  // register dictionary object //
162  RegisterScriptDictionary(engine);
163 
164  // Register the grid addon //
165  RegisterScriptGrid(engine);
166 
167  // Register reference handles //
168  RegisterScriptHandle(engine);
169 
170  RegisterScriptWeakRef(engine);
171 
172  RegisterScriptAny(engine);
173 
174  // Put the extended standard stuff also in Builtin access mask
175 
176  if(!BindStandardFunctions(engine))
177  throw Exception("BindStandardFunctions failed");
178 
179  // All normal engine stuff is in the DefaultEngine access mask //
180  engine->SetDefaultAccessMask(static_cast<AccessFlags>(ScriptAccess::DefaultEngine));
181 
182  if(!BindOgre(engine))
183  throw Exception("BindOgre failed");
184 
185  if(!BindTypes(engine))
186  throw Exception("BindTypes failed");
187 
188  if(!BindPhysics(engine))
189  throw Exception("BindNewton failed");
190 
191  if(!BindEngineCommon(engine))
192  throw Exception("BindEngineCommon failed");
193 
194  if(!BindGUI(engine))
195  throw Exception("BindGUI failed");
196 
197  if(!BindEntity(engine))
198  throw Exception("BindEntity failed");
199 
200  // Bind notifiers //
201  if(!RegisterNotifiersWithAngelScript(engine)) {
202  // failed //
203  LOG_ERROR("ScriptExecutor: Init: AngelScript: register Notifier types failed");
204  throw Exception("Script bind failed");
205  }
206 
207  // Restore the default mask to let the application do what it wants with the masks
208  engine->SetDefaultAccessMask(initialMask);
209 
210  // bind application specific //
211  auto leviathanengine = Engine::GetEngine();
212 
213  if(leviathanengine) {
214 
215  if(!leviathanengine->GetOwningApplication()->InitLoadCustomScriptTypes(engine)) {
216 
217  LOG_ERROR("ScriptExecutor: Init: AngelScript: application register failed");
218  throw Exception("Script bind failed");
219  }
220  }
221 
222  // Verify void type //
223  const auto actualVoid = engine->GetTypeIdByDecl("void");
224  if(actualVoid != ANGELSCRIPT_VOID_TYPEID) {
225 
226  LOG_FATAL("ScriptExecutor: angelscript void type has changed! expected " +
227  std::to_string(ANGELSCRIPT_VOID_TYPEID) +
228  " (constexpr) == " + std::to_string(actualVoid) + " (actual value)");
229  }
230 }
232 {
233  {
234  Lock lock(ModulesLock);
235  auto end = AllocatedScriptModules.end();
236  for(auto iter = AllocatedScriptModules.begin(); iter != end; ++iter) {
237 
238  (*iter)->Release();
239  }
240 
241  // release/delete all modules //
242  AllocatedScriptModules.clear();
243  }
244 
245  // Release all context objects
246  for(asIScriptContext* context : ContextPool) {
247  context->Release();
248  }
249 
250  ContextPool.clear();
251 
252  // release AngelScript //
253  if(engine) {
254 
255  engine->Release();
256  engine = nullptr;
257  }
258 
259  instance = nullptr;
260 }
261 
263 {
264  return instance;
265 }
266 
267 ScriptExecutor* Leviathan::ScriptExecutor::instance = nullptr;
268 // ------------------------------------ //
270  ScriptModule* module, ScriptRunningSetup& parameters)
271 {
272  if(!module) {
273 
274  if(parameters.PrintErrors) {
275  Logger::Get()->Error("ScriptExecutor: GetFunctionFromModule: module is nullptr");
276  }
277 
278  return nullptr;
279  }
280 
281  asIScriptFunction* func;
282 
283  asIScriptModule* asModule = module->GetModule();
284 
285  if(!asModule) {
286 
287  if(parameters.PrintErrors) {
288  Logger::Get()->Error(
289  "ScriptExecutor: GetFunctionFromModule: cannot get function from "
290  "an invalid script module: " +
291  module->GetInfoString());
292  }
293 
294  return nullptr;
295  }
296 
297  // Get the entry function from the module //
298  if(!parameters.FullDeclaration) {
299 
300  func = asModule->GetFunctionByName(parameters.Entryfunction.c_str());
301 
302  } else {
303 
304  func = asModule->GetFunctionByDecl(parameters.Entryfunction.c_str());
305  }
306 
307  if(!_CheckScriptFunctionPtr(func, parameters, module)) {
308 
309  return nullptr;
310  }
311 
312  return func;
313 }
314 // ------------------------------------ //
316 {
317  asITypeInfo* info = engine->GetTypeInfoById(objid);
318 
319  asUINT count = info->GetBehaviourCount();
320 
321  for(asUINT i = 0; i < count; ++i) {
322 
323  asEBehaviours behaviour;
324  asIScriptFunction* func = info->GetBehaviourByIndex(i, &behaviour);
325 
326  if(!func) {
327 
328  LOG_ERROR("ScriptExecutor: RunReleaseRefOnObject: failed to get behaviour");
329  continue;
330  }
331 
332  if(behaviour == asBEHAVE_RELEASE) {
333 
334  LOG_INFO(
335  "ScriptExecutor: RunReleaseRefOnObject: Found asBEHAVE_RELEASE, calling it");
336 
337  ScriptRunningSetup ssetup;
338  const auto result = RunScriptMethod<void>(ssetup, func, obj);
339 
340  if(result.Result != SCRIPT_RUN_RESULT::Success)
341  throw Exception("Failed to run release behaviour");
342 
343  return;
344  }
345  }
346 
347  throw Exception("Didn't find release ref behaviour on object type");
348 }
349 // ------------------------------------ //
350 DLLEXPORT std::unique_ptr<CustomScriptRun> ScriptExecutor::PrepareCustomScriptRun(
351  asIScriptFunction* func, ScriptRunningSetup extraoptions /*= ScriptRunningSetup()*/)
352 {
353  if(!func)
354  return nullptr;
355 
356  auto run = std::make_unique<CustomScriptRun>(this);
357  run->Setup = extraoptions;
358  run->Func = func;
359 
360  // // TODO: this is a performance waste if there are no errors
361  // std::shared_ptr<ScriptModule> module =
362  // GetScriptModuleByFunction(func, run->Setup.PrintErrors);
363 
364  // Create a running context for the function //
365  run->Context = _GetContextForExecution();
366 
367  if(!run->Context) {
368  // Should this be fatal?
369  LOG_ERROR("ScriptExecutor: PrepareCustomScriptRun: failed to create a new context");
370  return nullptr;
371  }
372 
373  if(!_PrepareContextForPassingParameters(
374  func, run->Context, run->Setup, run->Module.get())) {
375 
376  _DoneWithContext(run->Context);
377  return nullptr;
378  }
379 
380  return run;
381 }
382 // ------------------------------------ //
384  asIScriptFunction* func, bool reporterror)
385 {
386  const char* nameStr = func->GetModuleName();
387 
388  if(!nameStr || strlen(nameStr) <= 1)
389  return nullptr;
390 
391  // static_cast<ScriptModule*>(func->GetModule()->GetUserData());
392  // then find by pointer in valid script modules
393 
394  std::shared_ptr<ScriptModule> module =
395  GetModuleByAngelScriptName(func->GetModuleName()).lock();
396 
397  if(!module) {
398 
399  if(reporterror) {
400  LOG_WARNING("ScriptExecutor: GetScriptModuleByFunction: the module is no longer "
401  "available: " +
402  std::string(func->GetModuleName()));
403  }
404  }
405 
406  return module;
407 }
408 // ------------------------------------ //
409 DLLEXPORT bool Leviathan::ScriptExecutor::_CheckScriptFunctionPtr(
410  asIScriptFunction* func, ScriptRunningSetup& parameters, ScriptModule* scriptmodule)
411 {
412  // Check is it null //
413  if(func == nullptr) {
414  // Set exists state //
415  parameters.ScriptExisted = false;
416 
417  // Check should we print an error //
418  if(parameters.PrintErrors && parameters.ErrorOnNonExistingFunction) {
419 
420  LOG_ERROR(
421  "ScriptExecutor: RunScript: Could not find starting function: " +
422  parameters.Entryfunction +
423  (scriptmodule ? (" in: " + scriptmodule->GetInfoString()) : std::string()));
424 
425  if(scriptmodule)
426  scriptmodule->PrintFunctionsInModule();
427  }
428 
429  // Not valid //
430  return false;
431  }
432 
433  // Set exists state //
434  parameters.ScriptExisted = true;
435 
436  return true;
437 }
438 
439 DLLEXPORT bool Leviathan::ScriptExecutor::_PrepareContextForPassingParameters(
440  asIScriptFunction* func, asIScriptContext* ScriptContext, ScriptRunningSetup& parameters,
441  ScriptModule* scriptmodule)
442 {
443  if(ScriptContext->Prepare(func) < 0) {
444 
445  Logger::Get()->Error(
446  "ScriptExecutor: RunScript: prepare context failed, func: " +
447  parameters.Entryfunction +
448  (scriptmodule ? (" in: " + scriptmodule->GetInfoString()) : std::string()));
449 
450  return false;
451  }
452 
453  return true;
454 }
455 
456 // ------------------------------------ //
458 {
459  // TODO: check for recursive call
460 
461  Lock guard(ContextPoolLock);
462 
463  // Get from pool if possible
464  if(!ContextPool.empty()) {
465  auto* ptr = ContextPool.back();
466  ContextPool.pop_back();
467  return ptr;
468  }
469 
470  // Needs more contexts
471  asIScriptContext* scriptContext = engine->CreateContext();
472 
473  if(!scriptContext) {
474 
475  LOG_ERROR("ScriptExecutor: _GetContextForExecution: Failed to create a new context");
476  return nullptr;
477  }
478 
479  return scriptContext;
480 }
481 
483 {
484  Lock guard(ContextPoolLock);
485 
486  // Only keep 1000 contexts at most
487  if(ContextPool.size() < 1000) {
488 
489  ContextPool.push_back(context);
490  context->Unprepare();
491 
492  } else {
493 
494  context->Release();
495  }
496 }
497 // ------------------------------------ //
498 DLLEXPORT std::weak_ptr<ScriptModule> Leviathan::ScriptExecutor::GetModule(const int& ID)
499 {
500  // loop modules and return a ptr to matching id //
501  Lock lock(ModulesLock);
502 
503  for(size_t i = 0; i < AllocatedScriptModules.size(); i++) {
504  if(AllocatedScriptModules[i]->GetID() == ID)
505  return AllocatedScriptModules[i];
506  }
507 
508  return std::shared_ptr<ScriptModule>(nullptr);
509 }
510 
512  const char* nameofmodule)
513 {
514  // Find a matching name //
515  std::string module(nameofmodule);
516 
517  Lock lock(ModulesLock);
518 
519  // TODO: check could this be checked by comparing pointers
520  for(size_t i = 0; i < AllocatedScriptModules.size(); i++) {
521  if(AllocatedScriptModules[i]->GetModuleName() == module)
522  return AllocatedScriptModules[i];
523  }
524 
525  return std::shared_ptr<ScriptModule>(nullptr);
526 }
527 // ------------------------------------ //
529  const std::string& name, const std::string& source, const int& modulesid
530  /*= IDFactory::GetID()*/)
531 {
532  // create new module to a smart pointer //
533  auto tmpptr = std::make_shared<ScriptModule>(engine, name, modulesid, source);
534 
535  // add to vector and return //
536  Lock lock(ModulesLock);
537  AllocatedScriptModules.push_back(tmpptr);
538  return tmpptr;
539 }
540 
542 {
543 
544  Lock lock(ModulesLock);
545 
546  // find module based on pointer and remove //
547  for(size_t i = 0; i < AllocatedScriptModules.size(); i++) {
548  if(AllocatedScriptModules[i].get() == ptrtomatch) {
549 
550  AllocatedScriptModules[i]->Release();
551  // remove //
552  AllocatedScriptModules.erase(AllocatedScriptModules.begin() + i);
553  return;
554  }
555  }
556 }
557 
559 {
560 
561  Lock lock(ModulesLock);
562 
563  // Find based on the id //
564  for(size_t i = 0; i < AllocatedScriptModules.size(); i++) {
565  if(AllocatedScriptModules[i]->GetID() == ID) {
566  // Check reference count //
567  if(AllocatedScriptModules[i].use_count() != 1) {
568  // Other references exist //
569  return false;
570  }
571 
572  AllocatedScriptModules[i]->Release();
573 
574  // remove //
575  AllocatedScriptModules.erase(AllocatedScriptModules.begin() + i);
576  return true;
577  }
578  }
579  // Nothing found //
580  return false;
581 }
582 // ------------------------------------ //
583 DLLEXPORT bool ScriptExecutor::_DoPassParameterTypeError(
584  ScriptRunningSetup& setup, ScriptModule* module, int i, int scriptwanted, int provided)
585 {
586  if(setup.PrintErrors) {
587 
588  LOG_ERROR("ScriptExecutor: pass parameters to script failed, func: " +
589  setup.Entryfunction + " param number: " + std::to_string(i) +
590  " script wanted type: " + std::to_string(scriptwanted) +
591  " but application provided: " + std::to_string(provided) +
592  (module ? (" in: " + module->GetInfoString()) : std::string()));
593  }
594 
595  return false;
596 }
597 
598 DLLEXPORT void ScriptExecutor::_DoReceiveParameterTypeError(
599  ScriptRunningSetup& setup, ScriptModule* module, int applicationwanted, int scripthad)
600 {
601  if(setup.PrintErrors) {
602 
603  LOG_ERROR("ScriptExecutor: return parameter from script failed, func: " +
604  setup.Entryfunction +
605  " application wanted type: " + std::to_string(applicationwanted) +
606  " but script return type is: " + std::to_string(scripthad) +
607  (module ? (" in: " + module->GetInfoString()) : std::string()));
608  }
609 }
610 // ------------------------------------ //
612  LErrorReporter& output, asIScriptFunction* func /*= nullptr*/,
613  ScriptModule* scriptmodule /*= nullptr*/)
614 {
615 
616  std::string declaration = ctx->GetExceptionFunction()->GetDeclaration() ?
617  ctx->GetExceptionFunction()->GetDeclaration() :
618  "unknown function";
619 
620  std::string section = ctx->GetExceptionFunction()->GetScriptSectionName() ?
621  ctx->GetExceptionFunction()->GetScriptSectionName() :
622  "unknown";
623 
624  std::string exception =
625  ctx->GetExceptionString() ? ctx->GetExceptionString() : "unknown exception";
626 
627  std::string funcDeclaration =
628  func ? (func->GetDeclaration() ? func->GetDeclaration() : "unknown function") : "";
629 
630  output.Error(
631  std::string("[SCRIPT][EXCEPTION] ") + exception +
632  (func ? std::string(", while running function: ") + funcDeclaration : std::string()) +
633  "\n\t in function " + declaration + " defined in " + section + "(" +
634  std::to_string(ctx->GetExceptionLineNumber()) + ") " +
635  (scriptmodule ? scriptmodule->GetInfoString() : std::string()));
636 
637  PrintCallstack(ctx, output);
638 }
639 
640 DLLEXPORT void ScriptExecutor::PrintCallstack(asIScriptContext* ctx, LErrorReporter& output)
641 {
642 
643  // Print callstack as additional information //
644  output.WriteLine("// ------------------ CallStack ------------------ //");
645 
646  // Loop the stack starting from the frame below the current function
647  // (actually might be nice to print the top frame too)
648  for(asUINT n = 0; n < ctx->GetCallstackSize(); n++) {
649 
650  // Get the function object //
651  const asIScriptFunction* function = ctx->GetFunction(n);
652 
653  // If the function doesn't exist this frame is used internally by the script engine //
654  if(function) {
655 
656  // Check function type //
657  if(function->GetFuncType() == asFUNC_SCRIPT) {
658 
659  // Print info about the script function //
660  output.WriteLine(std::string("\t> ") + function->GetScriptSectionName() + ":" +
661  std::to_string(ctx->GetLineNumber(n)) + " " +
662  function->GetDeclaration());
663 
664  } else {
665  // Info about the application functions //
666  // The context is being reused by the application for a nested call
667  output.WriteLine(
668  std::string("\t> {...Application...}: ") + function->GetDeclaration());
669  }
670  } else {
671  // The context is being reused by the script engine for a nested call
672  output.WriteLine("\t> {...Script internal...}");
673  }
674  }
675 }
676 // ------------------------------------ //
678 {
679 
680  return engine->GetTypeIdByDecl(str);
681 }
682 
683 DLLEXPORT asITypeInfo* ScriptExecutor::GetTypeInfo(int type) const
684 {
685 
686  if(type < 0)
687  return nullptr;
688 
689  return engine->GetTypeInfoById(type);
690 }
691 // ------------------------------------ //
693 {
694  engine->GarbageCollect(asGC_FULL_CYCLE);
695 }
696 // ------------------------------------ //
697 // CustomScriptRun
699 {
700 
701  if(Context) {
702 
703  Exec->_DoneWithContext(Context);
704  }
705 }
Access to the builtin types like string and math functions.
DLLEXPORT asIScriptModule * GetModule(Lock &guard)
Builds the script if applicable.
DLLEXPORT int ResolveStringToASID(const char *str) const
Converts a string to angelscript type id. Returns -1 on error.
DLLEXPORT void Write(const std::string &data) override
Definition: Logger.cpp:113
DLLEXPORT asIScriptFunction * GetFunctionFromModule(ScriptModule *module, ScriptRunningSetup &parameters)
Finds a script function in module matching setup.
asIScriptContext * RequestContextCallback(asIScriptEngine *engine, void *userdata)
#define LOG_INFO(x)
Definition: Define.h:81
friend void ReturnContextCallback(asIScriptEngine *engine, asIScriptContext *context, void *userdata)
DLLEXPORT void Info(const std::string &data) override
Definition: Logger.cpp:164
#define LOG_ERROR(x)
Definition: Define.h:83
DLLEXPORT std::shared_ptr< ScriptModule > GetScriptModuleByFunction(asIScriptFunction *func, bool reporterror)
Returns module in which script function was defined in.
DLLEXPORT void RunReleaseRefOnObject(void *obj, int objid)
Finds release ref behaviour on object and calls it.
#define LOG_FATAL(x)
Definition: Define.h:85
constexpr auto ANGELSCRIPT_VOID_TYPEID
This has to be constant (and luckily so far it has been)
bool RegisterNotifiersWithAngelScript(asIScriptEngine *engine)
DLLEXPORT std::weak_ptr< ScriptModule > GetModuleByAngelScriptName(const char *nameofmodule)
DLLEXPORT asITypeInfo * GetTypeInfo(int type) const
Returns an asITypeInfo object for type id or null.
Handles ScriptModule creation and AngelScript code execution.
DLLEXPORT void CollectGarbage()
Does a full garbage collection cycle.
bool BindEngineCommon(asIScriptEngine *engine)
static DLLEXPORT void PrintCallstack(asIScriptContext *ctx, LErrorReporter &output)
static DLLEXPORT void PrintExceptionInfo(asIScriptContext *ctx, LErrorReporter &output, asIScriptFunction *func=nullptr, ScriptModule *scrptmodule=nullptr)
Prints exception info and stacktrace to a logger.
Base class for all exceptions thrown by Leviathan.
Definition: Exceptions.h:10
#define LOG_WARNING(x)
Definition: Define.h:82
DLLEXPORT std::weak_ptr< ScriptModule > CreateNewModule(const std::string &name, const std::string &source, const int &modulesid=IDFactory::GetID())
DLLEXPORT void PrintFunctionsInModule()
static DLLEXPORT ScriptExecutor * Get()
DLLEXPORT bool DeleteModuleIfNoExternalReferences(int ID)
DLLEXPORT const char * what() const noexcept override
Definition: Exceptions.cpp:29
bool BindStandardFunctions(asIScriptEngine *engine)
Binds standard and other utilities like: std::min, std::max etc.
bool BindTypes(asIScriptEngine *engine)
Definition: TypesBind.cpp:813
void ReturnContextCallback(asIScriptEngine *engine, asIScriptContext *context, void *userdata)
virtual void WriteLine(const std::string &Text)=0
Default mask for engine classes (some things are accessible even with this off)
static std::string ToString(const T &val)
Definition: Convert.h:72
bool BindOgre(asIScriptEngine *engine)
Definition: OgreBind.cpp:845
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
bool BindGUI(asIScriptEngine *engine)
void ScriptMessageCallback(const asSMessageInfo *msg, void *param)
virtual void Error(const std::string &Text)=0
#define DLLEXPORT
Definition: Include.h:115
DLLEXPORT void _DoneWithContext(asIScriptContext *context)
Called after a script has been executed and the context is no longer needed.
DLLEXPORT std::unique_ptr< CustomScriptRun > PrepareCustomScriptRun(asIScriptFunction *func, ScriptRunningSetup extraoptions=ScriptRunningSetup())
Starts a script run that supports custom argument passing.
static DLLEXPORT Engine * GetEngine()
Definition: Engine.cpp:79
DLLEXPORT std::weak_ptr< ScriptModule > GetModule(const int &ID)
DLLEXPORT void DeleteModule(ScriptModule *ptrtomatch)
bool BindPhysics(asIScriptEngine *engine)
The access mask controls which registered functions and classes a script sees.
Definition: GameModule.h:12
friend asIScriptContext * RequestContextCallback(asIScriptEngine *engine, void *userdata)
bool BindEntity(asIScriptEngine *engine)
Definition: EntityBind.cpp:521
DLLEXPORT void Error(const std::string &data) override
Definition: Logger.cpp:177
std::unique_lock< std::mutex > Lock
Definition: ThreadSafe.h:16
DLLEXPORT asIScriptContext * _GetContextForExecution()
Called when a context is required for script execution.
asIScriptContext * Context
DLLEXPORT std::string GetInfoString()