feat(lua): track source of scripts to allow hyperlinking to script
This commit is contained in:
parent
783fd17563
commit
fcf4343509
2 changed files with 52 additions and 23 deletions
|
@ -1,5 +1,6 @@
|
||||||
#include "script.h"
|
#include "script.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "datatypes/variant.h"
|
||||||
#include "lauxlib.h"
|
#include "lauxlib.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "objects/base/instance.h"
|
#include "objects/base/instance.h"
|
||||||
|
@ -31,23 +32,6 @@ void Script::Run() {
|
||||||
this->thread = lua_newthread(L);
|
this->thread = lua_newthread(L);
|
||||||
lua_State* Lt = thread;
|
lua_State* Lt = thread;
|
||||||
|
|
||||||
lua_pushthread(Lt); // Push thread for later*
|
|
||||||
|
|
||||||
// Initialize script globals
|
|
||||||
scriptContext->NewEnvironment(Lt); // Pushes envtable, metatable
|
|
||||||
|
|
||||||
// Set script in metatable source
|
|
||||||
InstanceRef(shared_from_this()).PushLuaValue(Lt);
|
|
||||||
lua_setfield(Lt, -2, "source");
|
|
||||||
|
|
||||||
lua_pop(Lt, 1); // Pop metatable
|
|
||||||
|
|
||||||
InstanceRef(shared_from_this()).PushLuaValue(Lt);
|
|
||||||
lua_setfield(Lt, -2, "script");
|
|
||||||
|
|
||||||
lua_setfenv(Lt, -2); // *Set env of current thread
|
|
||||||
lua_pop(Lt, 1); // Pop thread
|
|
||||||
|
|
||||||
// Push wrapper as thread function
|
// Push wrapper as thread function
|
||||||
lua_getfield(Lt, LUA_REGISTRYINDEX, "LuaPCallWrapper");
|
lua_getfield(Lt, LUA_REGISTRYINDEX, "LuaPCallWrapper");
|
||||||
|
|
||||||
|
@ -61,6 +45,21 @@ void Script::Run() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize script globals
|
||||||
|
scriptContext->NewEnvironment(Lt); // Pushes envtable, metatable
|
||||||
|
|
||||||
|
// Set script in metatable source
|
||||||
|
InstanceRef(shared_from_this()).PushLuaValue(Lt);
|
||||||
|
lua_setfield(Lt, -2, "source");
|
||||||
|
|
||||||
|
lua_pop(Lt, 1); // Pop metatable
|
||||||
|
|
||||||
|
// Set script in environment
|
||||||
|
InstanceRef(shared_from_this()).PushLuaValue(Lt);
|
||||||
|
lua_setfield(Lt, -2, "script");
|
||||||
|
|
||||||
|
lua_setfenv(Lt, -2); // Set env of loaded function
|
||||||
|
|
||||||
// Push our error handler and then generate the wrapped function
|
// Push our error handler and then generate the wrapped function
|
||||||
lua_pushcfunction(Lt, script_errhandler);
|
lua_pushcfunction(Lt, script_errhandler);
|
||||||
lua_call(Lt, 2, 1);
|
lua_call(Lt, 2, 1);
|
||||||
|
@ -76,6 +75,34 @@ void Script::Stop() {
|
||||||
// TODO:
|
// TODO:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::shared_ptr<Script> getfsource(lua_State* L, lua_Debug* dbg) {
|
||||||
|
int top = lua_gettop(L);
|
||||||
|
|
||||||
|
lua_getinfo(L, "f", dbg);
|
||||||
|
lua_getfenv(L, -1); // Get fenv of stack pos
|
||||||
|
if (lua_isnil(L, -1)) { // No env could be found
|
||||||
|
lua_settop(L, top);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get source from metatable
|
||||||
|
lua_getmetatable(L, -1);
|
||||||
|
lua_getfield(L, -1, "source");
|
||||||
|
|
||||||
|
auto result = InstanceRef::FromLuaValue(L, -1);
|
||||||
|
if (!result) {
|
||||||
|
lua_settop(L, top);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_settop(L, top);
|
||||||
|
|
||||||
|
std::shared_ptr<Instance> ref = result.expect().get<InstanceRef>();
|
||||||
|
if (!ref->IsA<Script>()) return nullptr;
|
||||||
|
|
||||||
|
return ref->CastTo<Script>().expect();
|
||||||
|
}
|
||||||
|
|
||||||
int script_errhandler(lua_State* L) {
|
int script_errhandler(lua_State* L) {
|
||||||
std::string errorMessage = lua_tostring(L, -1);
|
std::string errorMessage = lua_tostring(L, -1);
|
||||||
Logger::error(errorMessage);
|
Logger::error(errorMessage);
|
||||||
|
@ -92,7 +119,10 @@ int script_errhandler(lua_State* L) {
|
||||||
if (strcmp(dbg.what, "C") == 0 || strcmp(dbg.source, "=PCALL_WRAPPER") == 0)
|
if (strcmp(dbg.what, "C") == 0 || strcmp(dbg.source, "=PCALL_WRAPPER") == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Logger::scriptLogf("'%s', Line %d", Logger::LogLevel::TRACE, {}, dbg.source, dbg.currentline);
|
// Find script source
|
||||||
|
std::shared_ptr<Script> source = getfsource(L, &dbg);
|
||||||
|
|
||||||
|
Logger::scriptLogf("'%s', Line %d", Logger::LogLevel::TRACE, {source, dbg.currentline}, dbg.source, dbg.currentline);
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::trace("Stack end");
|
Logger::trace("Stack end");
|
||||||
|
|
|
@ -32,11 +32,6 @@ void CommandEdit::executeCommand() {
|
||||||
int top = lua_gettop(L);
|
int top = lua_gettop(L);
|
||||||
lua_State* Lt = lua_newthread(L);
|
lua_State* Lt = lua_newthread(L);
|
||||||
|
|
||||||
lua_pushthread(Lt); // Push thread
|
|
||||||
getOrCreateEnvironment(Lt);
|
|
||||||
lua_setfenv(Lt, -2); // Set env of current thread
|
|
||||||
lua_pop(Lt, 1); // Pop thread
|
|
||||||
|
|
||||||
// Push wrapper as thread function
|
// Push wrapper as thread function
|
||||||
lua_getfield(Lt, LUA_REGISTRYINDEX, "LuaPCallWrapper");
|
lua_getfield(Lt, LUA_REGISTRYINDEX, "LuaPCallWrapper");
|
||||||
|
|
||||||
|
@ -50,10 +45,14 @@ void CommandEdit::executeCommand() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getOrCreateEnvironment(Lt);
|
||||||
|
lua_setfenv(Lt, -2); // Set env of loaded function
|
||||||
|
|
||||||
// Push our error handler and then generate the wrapped function
|
// Push our error handler and then generate the wrapped function
|
||||||
lua_pushcfunction(Lt, script_errhandler);
|
lua_pushcfunction(Lt, script_errhandler);
|
||||||
lua_call(Lt, 2, 1);
|
lua_call(Lt, 2, 1);
|
||||||
|
|
||||||
|
|
||||||
// Resume the thread
|
// Resume the thread
|
||||||
lua_resume(Lt, 0);
|
lua_resume(Lt, 0);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue