49cb0af228
- [FIX] Acallats warnings en findloader de lua - [FIX] Acallats alguns 'Illegal music handle' innecesaris - [NEW] Ara detecta que no s'ha conectat al debuger de vscode i trau els missatges per consola com abans - [NEW] Missatges de error més clars - [NEW] Ara també trau els missatges de debug per consola en la versió release
223 lines
7.3 KiB
C++
223 lines
7.3 KiB
C++
#include "lua.h"
|
|
#include "lua.wrappers.h"
|
|
#include "lua.debug.h"
|
|
#include "lua.utils.h"
|
|
#include "external/lua/lua.hpp"
|
|
#include "mini/file/file.h"
|
|
#include "other/log.h"
|
|
|
|
#include <algorithm>
|
|
#include <unistd.h>
|
|
|
|
namespace mini
|
|
{
|
|
namespace lua
|
|
{
|
|
lua_State *L;
|
|
bool is_playing = false;
|
|
bool init_exists = false;
|
|
bool update_exists = false;
|
|
|
|
bool running() {
|
|
debug::process_commands(L);
|
|
return is_playing;
|
|
}
|
|
|
|
std::string assemble_error_message(const char *lua_error_string) {
|
|
std::string error = lua_error_string; // tu cadena original
|
|
|
|
std::string nombre;
|
|
int linea = 0;
|
|
std::string mensaje;
|
|
|
|
// 1. Buscar el nombre entre comillas
|
|
auto p1 = error.find('"');
|
|
auto p2 = error.find('"', p1 + 1);
|
|
if (p1 != std::string::npos && p2 != std::string::npos)
|
|
nombre = error.substr(p1 + 1, p2 - (p1 + 1));
|
|
|
|
// 2. Buscar la línea después de "]:"
|
|
auto p3 = error.find("]:", p2);
|
|
if (p3 != std::string::npos) {
|
|
size_t start = p3 + 2;
|
|
linea = std::stoi(error.substr(start));
|
|
}
|
|
|
|
// 3. Buscar el mensaje después del siguiente ':'
|
|
auto p4 = error.find(':', p3 + 2);
|
|
if (p4 != std::string::npos)
|
|
mensaje = error.substr(p4 + 2); // saltar ": "
|
|
|
|
// Ahora tienes:
|
|
// nombre → "main"
|
|
// linea → 18
|
|
// mensaje → "unexpected symbol near '+'"
|
|
return debug::chunkToPath(nombre) + ":" + std::to_string(linea) + ":" + mensaje;
|
|
}
|
|
|
|
int MiniLoader(lua_State *L) {
|
|
const char *name = luaL_checkstring(L, 1);
|
|
|
|
// 1. Convertir puntos en barras
|
|
std::string path(name);
|
|
std::string regpath(name);
|
|
std::replace(path.begin(), path.end(), '.', '/');
|
|
|
|
// 2. Detectar comodín "/*"
|
|
bool load_all = false;
|
|
if (path.size() >= 2 && path.substr(path.size()-2) == "/*") {
|
|
load_all = true;
|
|
path = path.substr(0, path.size()-2); // quitar "/*"
|
|
regpath = regpath.substr(0, regpath.size()-2); // quitar "/*"
|
|
}
|
|
|
|
if (load_all) {
|
|
std::vector<std::string> files = file::listresourcesdir(path.c_str(), "lua");
|
|
|
|
// Ejecutar todos los módulos
|
|
for (auto &f : files) {
|
|
std::string fullpath = path + "/" + f;
|
|
std::string registerpath = std::string(regpath + "." + f.substr(0,f.size()-4));
|
|
|
|
int size;
|
|
char* buffer = file::getfilebuffer(fullpath.c_str(), size);
|
|
if (!buffer) continue;
|
|
|
|
if (luaL_loadbuffer(L, buffer, size, registerpath.c_str()) == LUA_OK) {
|
|
lua_pcall(L, 0, 0, 0); // ejecutar módulo, sin devolver nada
|
|
lua_getglobal(L, "package");
|
|
lua_getfield(L, -1, "loaded");
|
|
lua_pushboolean(L, 1);
|
|
lua_setfield(L, -2, registerpath.c_str());
|
|
lua_pop(L, 2);
|
|
} else {
|
|
log_msg(LOG_LUALD, "Error cargando %s: %s\n", fullpath.c_str(), assemble_error_message(lua_tostring(L, -1)).c_str());
|
|
lua_pop(L, 1);
|
|
}
|
|
|
|
free(buffer);
|
|
}
|
|
|
|
// Devolver un loader vacío
|
|
lua_pushcfunction(L, [](lua_State* L) -> int {
|
|
lua_pushboolean(L, 1); // require devuelve true
|
|
return 1;
|
|
});
|
|
|
|
return 1;
|
|
}
|
|
|
|
// 3. Cargar un único archivo
|
|
std::string filename = path + ".lua";
|
|
|
|
int size;
|
|
char* buffer = file::getfilebuffer(filename.c_str(), size);
|
|
if (!buffer) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
if (luaL_loadbuffer(L, buffer, size, name)) {
|
|
log_msg(LOG_LUALD, "%s\n", assemble_error_message(lua_tostring(L, -1)).c_str());
|
|
lua_pop(L, 1);
|
|
free(buffer);
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
free(buffer);
|
|
return 1;
|
|
}
|
|
|
|
void init(const char *main_lua_file) {
|
|
L = luaL_newstate();
|
|
luaL_openlibs(L);
|
|
|
|
push_functions(L);
|
|
lua_register(L, "mini_loader", MiniLoader);
|
|
luaL_dostring(L, "table.insert(package.searchers,2,mini_loader)\n");
|
|
|
|
int size;
|
|
char* buffer = file::getfilebuffer(main_lua_file, size);
|
|
if (luaL_loadbuffer(L, buffer, size, "main")) {
|
|
log_msg(LOG_LUALD, "%s\n", assemble_error_message(lua_tostring(L, -1)).c_str());
|
|
lua_pop(L,1);
|
|
return;
|
|
}
|
|
free(buffer);
|
|
if (lua_pcall(L,0, LUA_MULTRET, 0)) {
|
|
//luaL_traceback(L, L, NULL, 1);
|
|
log_msg(LOG_LUART, "%s\n", assemble_error_message(lua_tostring(L, -1)).c_str());
|
|
lua_pop(L,1);
|
|
return;
|
|
}
|
|
|
|
// Check if _init and _update exist
|
|
lua_getglobal(L, "mini");
|
|
lua_getfield(L, -1, "init");
|
|
if (lua_isfunction(L,-1)) init_exists = true;
|
|
lua_pop(L,1);
|
|
lua_pop(L,1);
|
|
|
|
lua_getglobal(L, "mini");
|
|
lua_getfield(L, -1, "update");
|
|
if (lua_isfunction(L,-1)) update_exists = true;
|
|
lua_pop(L,1);
|
|
lua_pop(L,1);
|
|
|
|
debug::init(L);
|
|
|
|
//std::thread(debugCommandThread).detach();
|
|
//printf("stdin isatty: %d\n", isatty(0));
|
|
is_playing = true;
|
|
}
|
|
|
|
void quit() {
|
|
if (!is_playing) return;
|
|
is_playing = false;
|
|
lua_close(L);
|
|
}
|
|
|
|
void cleanup() {
|
|
debug::kill_thread();
|
|
}
|
|
|
|
namespace callbacks
|
|
{
|
|
void init() {
|
|
if (!init_exists) return;
|
|
debug::process_commands(L);
|
|
lua_getglobal(L, "mini");
|
|
lua_getfield(L, -1, "init");
|
|
|
|
if (debug::is_enabled()) {
|
|
is_playing = debug::call_and_handle_exceptions(L);
|
|
} else {
|
|
if (lua_pcall(L, 0, 0, 0)) {
|
|
log_msg(LOG_LUART, "%s\n", assemble_error_message(lua_tostring(L, -1)).c_str());
|
|
lua_pop(L,1);
|
|
is_playing = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
void update() {
|
|
if (!update_exists) return;
|
|
lua_getglobal(L, "mini");
|
|
lua_getfield(L, -1, "update");
|
|
|
|
if (debug::is_enabled()) {
|
|
is_playing = debug::call_and_handle_exceptions(L);
|
|
} else {
|
|
if (lua_pcall(L, 0, 0, 0)) {
|
|
log_msg(LOG_LUART, "%s\n", assemble_error_message(lua_tostring(L, -1)).c_str());
|
|
lua_pop(L,1);
|
|
is_playing = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|