Files
mini/source/mini/lua/lua.cpp
Raimon Zamora 380295aed0 - [WIP] Fase 2 quasi acabada
- [FIX] Arreglos per al debugger
- [FIX] Calcul de la posició del mouse en coordenades tenint en compte view.origin
2026-04-13 20:09:57 +02:00

174 lines
5.3 KiB
C++

#include "lua.h"
#include "lua.wrappers.h"
#include "lua.debug.h"
#include "external/lua/lua.hpp"
#include "mini/file/file.h"
#include "aux/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;
}
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(), lua_tostring(L, -1));
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", lua_tostring(L, -1));
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", lua_tostring(L, -1));
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", lua_tostring(L, -1));
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");
is_playing = debug::call_and_handle_exceptions(L);
}
void update() {
if (!update_exists) return;
lua_getglobal(L, "mini");
lua_getfield(L, -1, "update");
is_playing = debug::call_and_handle_exceptions(L);
}
}
}
}