NLS Engine  v0.1
The Next Logical Step in game engine design.
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Defines
ScriptManager.cpp
Go to the documentation of this file.
00001 
00007 #include <cassert>
00008 #include <boost/lexical_cast.hpp>
00009 
00010 #include "../sharedbase/EventLogger.h"
00011 
00012 #include "ScriptManager.h"
00013 
00014 asIScriptEngine* ScriptManager::engine = nullptr;
00015 int ScriptManager::instanceCount = 0;
00016 
00017 asIScriptEngine* ScriptManager::GetEngine() {
00018   return ScriptManager::engine;
00019 }
00020 
00021 
00022 ScriptManager::ScriptManager( void ) : ctx(nullptr) {
00023   ++ScriptManager::instanceCount;
00024 }
00025 
00026 ScriptManager::~ScriptManager( void ) {
00027   this->ctx->Release();
00028   if (--ScriptManager::instanceCount <= 0) {
00029     ScriptManager::engine->Release();
00030     ScriptManager::engine = nullptr;
00031   }
00032 }
00033 
00034 
00035 void ScriptManager::MessageCallback(const asSMessageInfo *msg) {
00036   std::string type = "ERR ";
00037   if (msg->type == asMSGTYPE_WARNING) {
00038     type = "WARN";
00039   }
00040   else if (msg->type == asMSGTYPE_INFORMATION) {
00041     type = "INFO";
00042   }
00043   LOG(LOG_PRIORITY::RESTART, 
00044     type + 
00045     ": " + boost::lexical_cast<std::string>(msg->section) + 
00046     " at line " + boost::lexical_cast<std::string>(msg->row) + 
00047     ", column " + boost::lexical_cast<std::string>(msg->col) + 
00048     ": " + msg->message
00049     );
00050   
00051   //assert(msg->type != asMSGTYPE_ERROR); // Angelscript tends to make a mess of memory when it errors out
00052 }
00053 
00054 void ScriptManager::ExceptionCallback(asIScriptContext* ctx) {
00055   asIScriptEngine* engine = ctx->GetEngine();
00056   
00057   int funcID = ctx->GetExceptionFunction();
00058   const asIScriptFunction* function = engine->GetFunctionById(funcID);
00059   
00060   int line, column;
00061   line = ctx->GetExceptionLineNumber(&column);
00062   
00063   std::string errStr = 
00064     "Exception in script. Module " + std::string(function->GetModuleName()) +
00065     ", section " + function->GetScriptSectionName() +
00066     ", function " + function->GetDeclaration() +
00067     ", line " + boost::lexical_cast<std::string>(line) +
00068     ", column " + boost::lexical_cast<std::string>(column) +
00069     "\n\tMessage: " + ctx->GetExceptionString()
00070   ;
00071   LOG(LOG_PRIORITY::ERR, errStr);
00072 }
00073 
00074 int ScriptManager::InitAngelScript( void ) {
00075   int ret = 0;
00076   
00077   // Create the script engine
00078   if (ScriptManager::engine == nullptr) {
00079     ScriptManager::engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
00080     
00081     if (ScriptManager::engine == nullptr) {
00082       assert(false /* If the engine fails to init, this is a BIG problem in the source or logic flow. */);
00083       return -1;
00084     }
00085 
00086     // Set the message callback to receive information on errors in human readable form.
00087     ret = ScriptManager::engine->SetMessageCallback(asMETHOD(ScriptManager, MessageCallback), this, asCALL_THISCALL);
00088   }
00089   
00090   this->ctx = ScriptManager::engine->CreateContext(); // Create our context we will use for everything
00091   
00092   // Set the exception callback to receive information on errors in human readable form.
00093   ret = this->ctx->SetExceptionCallback(asMETHOD(ScriptManager, ExceptionCallback), this, asCALL_THISCALL);
00094   
00095   return ret;
00096 }
00097 
00098 int ScriptManager::PrepareFunction( std::string funcname, std::string modname ) {
00099   // Find the function that is to be called. 
00100   asIScriptModule *mod = ScriptManager::engine->GetModule(modname.c_str());
00101   int funcId = mod->GetFunctionIdByDecl(funcname.c_str());
00102   if( funcId >= 0 ) {
00103     return this->ctx->Prepare(funcId);
00104   }
00105   else {
00106     return -1;
00107   }
00108 }
00109 
00110 int ScriptManager::PrepareFunction( int funcID ) {
00111   // Find the function that is to be called. 
00112   if( funcID >= 0 ) {
00113     return this->ctx->Prepare(funcID);
00114   }
00115   else {
00116     return -1;
00117   }
00118 }
00119 
00120 int ScriptManager::SetFunctionParamObject(int argIndex, void* param) {
00121   return this->ctx->SetArgObject(argIndex, param);
00122 }
00123 
00124 int ScriptManager::SetFunctionParamFloat(int argIndex, float param) {
00125   return this->ctx->SetArgFloat(argIndex, param);
00126 }
00127 
00128 int ScriptManager::SetFunctionParamDouble(int argIndex, double param) {
00129   return this->ctx->SetArgDouble(argIndex, param);
00130 }
00131 
00132 int ScriptManager::ExecuteFunction() {
00133   return this->ctx->Execute();
00134 }
00135 
00136 std::string* ScriptManager::GetReturnString() {
00137   return (std::string*)this->ctx->GetReturnObject();
00138 }
00139 
00140 int ScriptManager::CreateModule( std::string modname ) {
00141   return this->StartNewModule(ScriptManager::engine, modname.c_str());
00142 }