204 lines
4.6 KiB
C++
204 lines
4.6 KiB
C++
|
#include "ScriptSystem.h"
|
||
|
|
||
|
#include "Utilities/Log.h"
|
||
|
|
||
|
// library includes
|
||
|
#include "physfs.h"
|
||
|
|
||
|
// system includes
|
||
|
#include <iostream>
|
||
|
#include <cmath>
|
||
|
#include <stdio.h>
|
||
|
#include <stdarg.h>
|
||
|
|
||
|
using namespace std;
|
||
|
|
||
|
namespace BlueCore
|
||
|
{
|
||
|
//--------------------------------------------------------------------------
|
||
|
static ScriptSystem* gScriptSystem = 0;
|
||
|
|
||
|
//--------------------------------------------------------------------------
|
||
|
void _sq_compiler_error_handler(HSQUIRRELVM vm, const SQChar *error,
|
||
|
const SQChar *source, SQInteger line, SQInteger column)
|
||
|
{
|
||
|
clog << "!!! Error compiling script '"<< source << ":"<< line << ": "
|
||
|
<< error << endlog;
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------------------
|
||
|
static SQInteger _sq_runtime_error_handler(HSQUIRRELVM vm)
|
||
|
{
|
||
|
const SQChar *error = 0;
|
||
|
|
||
|
if (sq_gettop(vm) >= 1)
|
||
|
{
|
||
|
if (SQ_SUCCEEDED(sq_getstring(vm, 2, &error) ) )
|
||
|
{
|
||
|
clog << "!!! Script Error: "<< error << endlog;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
clog << "!!! Script Error: unknown"<< endlog;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------------------
|
||
|
void _sq_print(HSQUIRRELVM vm, const SQChar* s, ...)
|
||
|
{
|
||
|
va_list vl;
|
||
|
va_start ( vl, s );
|
||
|
vprintf(s, vl);
|
||
|
va_end ( vl );
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------------------
|
||
|
static SQInteger _sq_require(HSQUIRRELVM v)
|
||
|
{
|
||
|
const SQChar *scriptname = 0;
|
||
|
|
||
|
if (SQ_SUCCEEDED(sq_getstring(v, 2, &scriptname) ))
|
||
|
{
|
||
|
if (gScriptSystem)
|
||
|
gScriptSystem->loadScript(scriptname);
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------------------
|
||
|
SQInteger _sq_file_reader(SQUserPointer file)
|
||
|
{
|
||
|
char c;
|
||
|
unsigned int count;
|
||
|
|
||
|
count = PHYSFS_read( (PHYSFS_file *)file, &c, sizeof (c), 1);
|
||
|
if (count > 0)
|
||
|
return c;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------------------
|
||
|
ScriptSystem::ScriptSystem()
|
||
|
{
|
||
|
gScriptSystem = this;
|
||
|
|
||
|
_VM = sq_open( 1024);
|
||
|
sq_setcompilererrorhandler(_VM, _sq_compiler_error_handler);
|
||
|
sq_newclosure(_VM, _sq_runtime_error_handler, 0);
|
||
|
sq_seterrorhandler(_VM);
|
||
|
sq_setprintfunc(_VM, _sq_print);
|
||
|
|
||
|
sq_pushroottable(_VM);
|
||
|
sq_pushstring(_VM, "require", -1);
|
||
|
sq_newclosure(_VM, _sq_require, 0);
|
||
|
sq_setparamscheck(_VM, 2, ".s");
|
||
|
sq_newslot(_VM, -3, false);
|
||
|
sq_pop(_VM, 1);
|
||
|
|
||
|
clog << ">>> ScriptSystem constructed ..."<< endlog;
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------------------
|
||
|
ScriptSystem::~ScriptSystem()
|
||
|
{
|
||
|
sq_close(_VM);
|
||
|
clog << ">>> ScriptSystem destructed ..."<< endlog;
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------------------
|
||
|
HSQUIRRELVM ScriptSystem::getVM()
|
||
|
{
|
||
|
return _VM;
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------------------
|
||
|
bool ScriptSystem::loadScript(const std::string &name)
|
||
|
{
|
||
|
for (unsigned int i = 0; i < _LoadedScripts.size(); i++)
|
||
|
{
|
||
|
if (_LoadedScripts[i] == name)
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (executeScript(name) )
|
||
|
{
|
||
|
_LoadedScripts.push_back(name);
|
||
|
return true;
|
||
|
}
|
||
|
else
|
||
|
clog << "!!! Script '"<< name << "' not found!"<< endlog;
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------------------
|
||
|
bool ScriptSystem::executeScript(const std::string &name)
|
||
|
{
|
||
|
string filename = name + ".nut";
|
||
|
PHYSFS_file *file = PHYSFS_openRead(filename.c_str() );
|
||
|
|
||
|
if ( !file)
|
||
|
{
|
||
|
clog << "!!! Script '"<< name << "' not found!"<< endlog;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
SQInteger ret;
|
||
|
|
||
|
ret = sq_compile(_VM, _sq_file_reader, file, name.c_str(), 1);
|
||
|
PHYSFS_close(file);
|
||
|
|
||
|
if (SQ_FAILED(ret) )
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
sq_pushroottable(_VM);
|
||
|
|
||
|
ret = sq_call(_VM, 1, SQFalse, SQTrue);
|
||
|
sq_pop(_VM, 1);
|
||
|
|
||
|
if (SQ_FAILED(ret) )
|
||
|
{
|
||
|
clog << "!!! Script execution failed: "<< name << endlog;
|
||
|
return false;
|
||
|
}
|
||
|
else
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------------------
|
||
|
void ScriptSystem::callFunction(const std::string &name)
|
||
|
{
|
||
|
sq_pushroottable(_VM);
|
||
|
sq_pushstring(_VM, name.c_str(), -1);
|
||
|
if (SQ_SUCCEEDED(sq_get(_VM, -2)) )
|
||
|
{
|
||
|
sq_pushroottable(_VM);
|
||
|
if (sq_call(_VM, 1, SQTrue, SQTrue) )
|
||
|
sq_pop(_VM, 1);
|
||
|
}
|
||
|
sq_pop(_VM, 1);
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------------------
|
||
|
void ScriptSystem::callFunction(const std::string &name, double value)
|
||
|
{
|
||
|
sq_pushroottable(_VM);
|
||
|
sq_pushstring(_VM, name.c_str(), -1);
|
||
|
if (SQ_SUCCEEDED(sq_get(_VM, -2)) )
|
||
|
{
|
||
|
sq_pushroottable(_VM);
|
||
|
sq_pushfloat(_VM, value);
|
||
|
if (sq_call(_VM, 2, SQTrue, SQTrue) )
|
||
|
sq_pop(_VM, 1);
|
||
|
}
|
||
|
sq_pop(_VM, 1);
|
||
|
}
|
||
|
}
|