148 lines
4.4 KiB
C++
148 lines
4.4 KiB
C++
|
|
#include "l_squirrel.h"
|
|||
|
|
// 虚拟机对象
|
|||
|
|
HSQUIRRELVM v;
|
|||
|
|
// Lock
|
|||
|
|
std::recursive_mutex SqMtx;
|
|||
|
|
|
|||
|
|
static void printfunc(HSQUIRRELVM v, const SQChar *s, ...)
|
|||
|
|
{
|
|||
|
|
fflush(stdout);
|
|||
|
|
va_list vl;
|
|||
|
|
va_start(vl, s);
|
|||
|
|
scvprintf(stdout, s, vl);
|
|||
|
|
va_end(vl);
|
|||
|
|
printf("\n");
|
|||
|
|
fflush(stdout);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static void errorfunc(HSQUIRRELVM v, const SQChar *s, ...)
|
|||
|
|
{
|
|||
|
|
fflush(stderr);
|
|||
|
|
va_list vl;
|
|||
|
|
va_start(vl, s);
|
|||
|
|
scvprintf(stderr, s, vl);
|
|||
|
|
va_end(vl);
|
|||
|
|
printf("\n");
|
|||
|
|
fflush(stderr);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static void ReloadingScript(HSQUIRRELVM v)
|
|||
|
|
{
|
|||
|
|
// 爬取出所有的脚本文件
|
|||
|
|
std::vector<std::string> vec = Tool::GetListFilesR("/Dnf_Sqr");
|
|||
|
|
std::map<std::string, std::string> SquirrelFilePath;
|
|||
|
|
|
|||
|
|
for (auto it = vec.cbegin(); it != vec.cend(); ++it)
|
|||
|
|
{
|
|||
|
|
std::string FileName = "/Dnf_Sqr/" + *it;
|
|||
|
|
if (FileName.find(".nut") == std::string::npos)
|
|||
|
|
continue;
|
|||
|
|
std::fstream F;
|
|||
|
|
F.open((FileName).c_str(), std::ios::in);
|
|||
|
|
std::stringstream ContentStringStream;
|
|||
|
|
ContentStringStream << F.rdbuf();
|
|||
|
|
std::string ContentString(ContentStringStream.str());
|
|||
|
|
F.close();
|
|||
|
|
SquirrelFilePath[FileName] = ContentString;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
std::map<std::string, std::string> SquirrelLastFilePath;
|
|||
|
|
|
|||
|
|
for (auto it = SquirrelFilePath.begin(); it != SquirrelFilePath.end(); it++)
|
|||
|
|
{
|
|||
|
|
std::string Sourcename = it->first;
|
|||
|
|
std::string ContentString = it->second;
|
|||
|
|
if (SQ_SUCCEEDED(sq_compilebuffer(v, (SQChar *)(ContentString.c_str()), ContentString.length(), (SQChar *)(Sourcename.c_str()), true)))
|
|||
|
|
{
|
|||
|
|
sq_pushroottable(v);
|
|||
|
|
sq_call(v, 1, 1, 1);
|
|||
|
|
sq_pop(v, 1);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
SquirrelLastFilePath[Sourcename] = ContentString;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
while (SquirrelLastFilePath.size() > 0)
|
|||
|
|
{
|
|||
|
|
std::map<std::string, std::string> FailMapBuffer;
|
|||
|
|
for (auto it = SquirrelLastFilePath.begin(); it != SquirrelLastFilePath.end(); it++)
|
|||
|
|
{
|
|||
|
|
std::string Sourcename = it->first;
|
|||
|
|
std::string ContentString = it->second;
|
|||
|
|
|
|||
|
|
if (SQ_SUCCEEDED(sq_compilebuffer(v, (SQChar *)(ContentString.c_str()), ContentString.length(), (SQChar *)(Sourcename.c_str()), true)))
|
|||
|
|
{
|
|||
|
|
sq_pushroottable(v);
|
|||
|
|
if (SQ_FAILED(sq_call(v, 1, 1, 1)))
|
|||
|
|
{
|
|||
|
|
FailMapBuffer[Sourcename] = ContentString;
|
|||
|
|
};
|
|||
|
|
sq_pop(v, 1);
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
SquirrelLastFilePath.clear();
|
|||
|
|
if (FailMapBuffer.size() > 0)
|
|||
|
|
{
|
|||
|
|
for (auto it = FailMapBuffer.begin(); it != FailMapBuffer.end(); it++)
|
|||
|
|
{
|
|||
|
|
std::string Sourcename = it->first;
|
|||
|
|
std::string ContentString = it->second;
|
|||
|
|
SquirrelLastFilePath[Sourcename] = ContentString;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static SQInteger SqReloadScript(HSQUIRRELVM v)
|
|||
|
|
{
|
|||
|
|
ReloadingScript(v);
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void InitSquirrel()
|
|||
|
|
{
|
|||
|
|
std::lock_guard<std::recursive_mutex> lock(SqMtx);
|
|||
|
|
|
|||
|
|
v = sq_open(4096); // 创建虚拟机,其栈的初始大小为1024
|
|||
|
|
|
|||
|
|
sq_pushroottable(v);
|
|||
|
|
|
|||
|
|
sqstd_register_bloblib(v);
|
|||
|
|
sqstd_register_iolib(v);
|
|||
|
|
sqstd_register_systemlib(v);
|
|||
|
|
sqstd_register_mathlib(v);
|
|||
|
|
sqstd_register_stringlib(v);
|
|||
|
|
sqstd_seterrorhandlers(v);
|
|||
|
|
|
|||
|
|
sq_setprintfunc(v, printfunc, errorfunc); // sets the print function
|
|||
|
|
|
|||
|
|
// 输出版本信息
|
|||
|
|
// scfprintf(stdout, _SC("%s %s (%d bits)\n"), SQUIRREL_VERSION, SQUIRREL_COPYRIGHT, (int)sizeof(SQInteger) * 8);
|
|||
|
|
|
|||
|
|
// 注册全局NutApi
|
|||
|
|
GlobaRegisterSquirrel(v);
|
|||
|
|
|
|||
|
|
// 加载基础脚本文件
|
|||
|
|
ReloadingScript(v);
|
|||
|
|
|
|||
|
|
// 执行虚拟机Main函数
|
|||
|
|
SQInteger top = sq_gettop(v); // saves the stack size before the call
|
|||
|
|
sq_pushroottable(v); // pushes the global table
|
|||
|
|
sq_pushstring(v, _SC("main"), -1);
|
|||
|
|
if (SQ_SUCCEEDED(sq_get(v, -2)))
|
|||
|
|
{ // gets the field 'foo' from the global table
|
|||
|
|
sq_pushroottable(v); // push the 'this' (in this case is the global table)
|
|||
|
|
sq_call(v, 1, SQFalse, SQTrue); // calls the function
|
|||
|
|
}
|
|||
|
|
sq_settop(v, top); // restores the original stack size
|
|||
|
|
|
|||
|
|
sq_pushroottable(v);
|
|||
|
|
sq_pushstring(v, "sq_ReloadScript", -1);
|
|||
|
|
sq_newclosure(v, SqReloadScript, 0); // create a new function
|
|||
|
|
sq_newslot(v, -3, SQFalse);
|
|||
|
|
sq_pop(v, 1); // pops the root table
|
|||
|
|
}
|