#include "SquirrelEx.h" #include "Tool/RemoteLogger.h" #include "squirrel/sqr_sdl.hpp" SquirrelEx::SquirrelEx() { } SquirrelEx::~SquirrelEx() { } void SquirrelEx::printfunc(HSQUIRRELVM v, const SQChar *s, ...) { va_list vl; va_start(vl, s); std::string message = RemoteLogger::format_string(s, vl); va_end(vl); RemoteLogger::GetInstance().log(message.c_str()); } void SquirrelEx::errorfunc(HSQUIRRELVM v, const SQChar *s, ...) { va_list vl; va_start(vl, s); std::string message = RemoteLogger::format_string(s, vl); va_end(vl); RemoteLogger::GetInstance().log(message.c_str()); } bool SquirrelEx::Compilebuffer(std::string Path, std::string Code) { if (v == nullptr) { RemoteLogger::GetInstance().log("松鼠虚拟机未初始化!"); return false; } if (sq_compilebuffer(v, Code.c_str(), Code.length(), Path.c_str(), SQTrue) >= 0) { sq_pushroottable(v); sq_call(v, 1, SQFalse, SQTrue); sq_pop(v, 1); return true; } return false; } void SquirrelEx::Init() { v = sq_open(1024); // 栈大小1024 sqstd_seterrorhandlers(v); sq_pushroottable(v); sqstd_register_bloblib(v); sqstd_register_iolib(v); sqstd_register_systemlib(v); sqstd_register_mathlib(v); sqstd_register_stringlib(v); sq_setprintfunc(v, printfunc, errorfunc); RegisterSDLFunctions(v); } void SquirrelEx::RequestNetScript(std::string Ip, std::string Port) { char *response = NULL; size_t response_size = 0; std::string url = "http://" + Ip + ":" + Port + "/get/getadvertisement?key=Files"; // 确保协议正确 int result = http_get(url.c_str(), &response, &response_size); if (result == 0 && response != NULL && response_size > 0) { std::string response_str(response, response_size); free(response); // 释放内存 nlohmann::json ex1 = nlohmann::json::parse(response_str); for (const auto &[key, value] : ex1.items()) { std::string key_str = key; std::string value_str = value; bool Flag = Compilebuffer(key_str, value_str); if (!Flag) { RemoteLogger::GetInstance().log("Squirrel Compilebuffer Error! FileName: %s", key_str.c_str()); } } } else { if (response) free(response); } } void SquirrelEx::Run() { // 载入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 } void SquirrelEx::UiRender(float deltaTime) { SQInteger top = sq_gettop(v); sq_pushroottable(v); sq_pushstring(v, _SC("UI_Render"), -1); if (SQ_SUCCEEDED(sq_get(v, -2))) { sq_pushroottable(v); sq_pushfloat(v, deltaTime); sq_call(v, 2, SQFalse, SQTrue); } sq_settop(v, top); } void SquirrelEx::Clean() { sq_close(v); v = nullptr; }