diff --git a/lua/autorun/lcpu_load.lua b/lua/autorun/lcpu_load.lua index 33d1665..05e7f92 100644 --- a/lua/autorun/lcpu_load.lua +++ b/lua/autorun/lcpu_load.lua @@ -26,7 +26,7 @@ if SERVER then print("size property is " .. device.Size) function device:Clock() - print("a") + print(self.Base) end function device:Peek(address) @@ -59,7 +59,7 @@ end cpu:Cycle();cpu:Cycle();cpu:Cycle();cpu:Cycle(); cpu:Cycle();cpu:Cycle();cpu:Cycle();cpu:Cycle(); cpu:Cycle();cpu:Cycle();cpu:Cycle();cpu:Cycle(); -]] +--]] AddCSLuaFile("entities/gmod_lcpu_cpu.lua") end diff --git a/native/projects/lcpu/src/LcpuGlobals.cpp b/native/projects/lcpu/src/LcpuGlobals.cpp index 29448b9..21d6bb2 100644 --- a/native/projects/lcpu/src/LcpuGlobals.cpp +++ b/native/projects/lcpu/src/LcpuGlobals.cpp @@ -4,40 +4,43 @@ #include "LuaCpu.hpp" #include "LuaDevice.hpp" -LUA_FUNCTION(LCPUNative_CreateCPU) { - LUA->CheckType(1, GarrysMod::Lua::Type::Number); - auto memorySize = static_cast(LUA->GetNumber(1)); +namespace lcpu { + LUA_FUNCTION(LCPUNative_CreateCPU) { + LUA->CheckType(1, GarrysMod::Lua::Type::Number); + auto memorySize = static_cast(LUA->GetNumber(1)); - // TODO: There's probably a way to like, ensure a per-player max. - if(memorySize > (64 * 1024 * 1024)) - LUA->ThrowError("Over RAM size limit."); + // TODO: There's probably a way to like, ensure a per-player max. + if(memorySize > (64 * 1024 * 1024)) + LUA->ThrowError("Over RAM size limit."); - LuaCpu::Create(LUA, memorySize); - return 1; -} + LuaCpu::Create(LUA, memorySize); + return 1; + } -LUA_FUNCTION(LCPUNative_CreateDevice) { - auto base = LUA->CheckNumber(1); - auto size = LUA->CheckNumber(2); - lucore::LogInfo("Creating Lua device object mapped @ 0x{:08x} with size 0x{:08x}", static_cast(base), - static_cast(size)); - LuaDevice::Create(LUA, static_cast(base), static_cast(size)); - return 1; -} + LUA_FUNCTION(LCPUNative_CreateDevice) { + auto base = LUA->CheckNumber(1); + auto size = LUA->CheckNumber(2); + lucore::LogInfo("Creating Lua device object mapped @ 0x{:08x} with size 0x{:08x}", static_cast(base), + static_cast(size)); + LuaDevice::Create(LUA, static_cast(base), static_cast(size)); + return 1; + } -void GlobalsBind(GarrysMod::Lua::ILuaBase* LUA) { - LuaCpu::RegisterClass(LUA); - LuaDevice::RegisterClass(LUA); + void GlobalsBind(GarrysMod::Lua::ILuaBase* LUA) { + LuaCpu::RegisterClass(LUA); + LuaDevice::RegisterClass(LUA); - // clang-format off - LUA->PushSpecial(GarrysMod::Lua::SPECIAL_GLOB); - LUA->CreateTable(); - LUA->PushNumber(LCPU_MODULE_VERSION); - LUA->SetField(-2, "ModuleVersion"); + // clang-format off + LUA->PushSpecial(GarrysMod::Lua::SPECIAL_GLOB); + LUA->CreateTable(); + LUA->PushNumber(LCPU_MODULE_VERSION); + LUA->SetField(-2, "ModuleVersion"); - LUA_SET_C_FUNCTION_NAME(LCPUNative_CreateCPU, "CreateCPU"); - LUA_SET_C_FUNCTION_NAME(LCPUNative_CreateDevice, "CreateDevice"); - LUA->SetField(-2, "LCPUNative"); - LUA->Pop(); - // clang-format on -} + LUA_SET_C_FUNCTION_NAME(LCPUNative_CreateCPU, "CreateCPU"); + LUA_SET_C_FUNCTION_NAME(LCPUNative_CreateDevice, "CreateDevice"); + LUA->SetField(-2, "LCPUNative"); + LUA->Pop(); + // clang-format on + } + +} // namespace lcpu diff --git a/native/projects/lcpu/src/LcpuGlobals.hpp b/native/projects/lcpu/src/LcpuGlobals.hpp index 68ad63e..f5b7201 100644 --- a/native/projects/lcpu/src/LcpuGlobals.hpp +++ b/native/projects/lcpu/src/LcpuGlobals.hpp @@ -1,7 +1,10 @@ #include "LuaHelpers.hpp" +namespace lcpu { /// This should be bumped on any incompatible change to the native bindings /// that would break older Lua code, or requires newer Lua code to run. #define LCPU_MODULE_VERSION 1 -void GlobalsBind(GarrysMod::Lua::ILuaBase* LUA); + void GlobalsBind(GarrysMod::Lua::ILuaBase* LUA); + +} // namespace lcpu diff --git a/native/projects/lcpu/src/LuaCpu.cpp b/native/projects/lcpu/src/LuaCpu.cpp index b70dfab..9ae011d 100644 --- a/native/projects/lcpu/src/LuaCpu.cpp +++ b/native/projects/lcpu/src/LuaCpu.cpp @@ -4,8 +4,8 @@ #include "LuaDevice.hpp" -// this is temporary from the thing - +// this is temporary from the test harness, and will be replaced +// at some point. /// simple 16550 UART implementation struct SimpleUartDevice : public riscv::Bus::MmioDevice { constexpr static riscv::Address BASE_ADDRESS = 0x10000000; @@ -30,87 +30,90 @@ struct SimpleUartDevice : public riscv::Bus::MmioDevice { } }; -LUA_MEMBER_FUNCTION_IMPLEMENT(LuaCpu, PoweredOn) { - auto self = LuaCpu::FromLua(LUA, 1); - LUA->PushBool(self->poweredOn); - return 1; -} - -LUA_MEMBER_FUNCTION_IMPLEMENT(LuaCpu, Cycle) { - auto self = LuaCpu::FromLua(LUA, 1); - if(!self->poweredOn) - return 0; - self->system->Step(); - return 0; -} - -LUA_MEMBER_FUNCTION_IMPLEMENT(LuaCpu, PowerOff) { - auto self = LuaCpu::FromLua(LUA, 1); - if(!self->poweredOn) - return 0; - - self->poweredOn = false; - self->system->bus->Reset(); - return 0; -} - -LUA_MEMBER_FUNCTION_IMPLEMENT(LuaCpu, PowerOn) { - auto self = LuaCpu::FromLua(LUA, 1); - if(self->poweredOn) - return 0; - - self->poweredOn = true; - self->system->bus->Reset(); - return 0; -} - -LUA_MEMBER_FUNCTION_IMPLEMENT(LuaCpu, Reset) { - auto self = LuaCpu::FromLua(LUA, 1); - self->system->bus->Reset(); - return 0; -} - -LUA_MEMBER_FUNCTION_IMPLEMENT(LuaCpu, AttachDevice) { - auto self = LuaCpu::FromLua(LUA, 1); - auto device = LuaDevice::FromLua(LUA, 2); - - // Attach it - LUA->PushBool(self->system->bus->AttachDevice(static_cast(device))); - return 1; -} - -void LuaCpu::RegisterClass(GarrysMod::Lua::ILuaBase* LUA) { - RegisterClassStart(LUA); - - RegisterMethod("PoweredOn", PoweredOn); - RegisterMethod("Cycle", Cycle); - RegisterMethod("PowerOff", PowerOff); - RegisterMethod("PowerOn", PowerOn); - RegisterMethod("Reset", Reset); - RegisterMethod("AttachDevice", AttachDevice); -} - -LuaCpu::LuaCpu(u32 memorySize) { - poweredOn = true; - system = riscv::System::Create(memorySize); - system->OnPowerOff = [&]() { - poweredOn = false; - system->bus->Reset(); - }; - - // lame test code. this WILL be removed, I just want this for a quick test - system->bus->AttachDevice(new SimpleUartDevice); - auto fp = std::fopen("/home/lily/test-gmod.bin", "rb"); - if(fp) { - std::fseek(fp, 0, SEEK_END); - auto len = std::ftell(fp); - std::fseek(fp, 0, SEEK_SET); - - std::fread(system->ram->Raw(), 1, len, fp); - std::fclose(fp); +namespace lcpu { + LUA_MEMBER_FUNCTION_IMPLEMENT(LuaCpu, PoweredOn) { + auto self = LuaCpu::FromLua(LUA, 1); + LUA->PushBool(self->poweredOn); + return 1; } -} -LuaCpu::~LuaCpu() { - delete system; -} + LUA_MEMBER_FUNCTION_IMPLEMENT(LuaCpu, Cycle) { + auto self = LuaCpu::FromLua(LUA, 1); + if(!self->poweredOn) + return 0; + self->system->Step(); + return 0; + } + + LUA_MEMBER_FUNCTION_IMPLEMENT(LuaCpu, PowerOff) { + auto self = LuaCpu::FromLua(LUA, 1); + if(!self->poweredOn) + return 0; + + self->poweredOn = false; + self->system->bus->Reset(); + return 0; + } + + LUA_MEMBER_FUNCTION_IMPLEMENT(LuaCpu, PowerOn) { + auto self = LuaCpu::FromLua(LUA, 1); + if(self->poweredOn) + return 0; + + self->poweredOn = true; + self->system->bus->Reset(); + return 0; + } + + LUA_MEMBER_FUNCTION_IMPLEMENT(LuaCpu, Reset) { + auto self = LuaCpu::FromLua(LUA, 1); + self->system->bus->Reset(); + return 0; + } + + LUA_MEMBER_FUNCTION_IMPLEMENT(LuaCpu, AttachDevice) { + auto self = LuaCpu::FromLua(LUA, 1); + auto device = LuaDevice::FromLua(LUA, 2); + + // Attach it + LUA->PushBool(self->system->bus->AttachDevice(static_cast(device))); + return 1; + } + + void LuaCpu::RegisterClass(GarrysMod::Lua::ILuaBase* LUA) { + RegisterClassStart(LUA); + + RegisterMethod("PoweredOn", PoweredOn); + RegisterMethod("Cycle", Cycle); + RegisterMethod("PowerOff", PowerOff); + RegisterMethod("PowerOn", PowerOn); + RegisterMethod("Reset", Reset); + RegisterMethod("AttachDevice", AttachDevice); + } + + LuaCpu::LuaCpu(u32 memorySize) { + poweredOn = true; + system = riscv::System::Create(memorySize); + system->OnPowerOff = [&]() { + poweredOn = false; + system->bus->Reset(); + }; + + // lame test code. this WILL be removed, I just want this for a quick test + system->bus->AttachDevice(new SimpleUartDevice); + auto fp = std::fopen("/home/lily/test-gmod.bin", "rb"); + if(fp) { + std::fseek(fp, 0, SEEK_END); + auto len = std::ftell(fp); + std::fseek(fp, 0, SEEK_SET); + + std::fread(system->ram->Raw(), 1, len, fp); + std::fclose(fp); + } + } + + LuaCpu::~LuaCpu() { + delete system; + } + +} // namespace lcpu diff --git a/native/projects/lcpu/src/LuaCpu.hpp b/native/projects/lcpu/src/LuaCpu.hpp index 334c209..a5af3ce 100644 --- a/native/projects/lcpu/src/LuaCpu.hpp +++ b/native/projects/lcpu/src/LuaCpu.hpp @@ -4,25 +4,29 @@ #include "LuaObject.hpp" -/// Bindings of [riscv::System] to Lua. -struct LuaCpu : public lcpu::lua::LuaObject { - /// Lua binding stuff - constexpr static const char* Name() { return "LuaCpu"; } - static void RegisterClass(GarrysMod::Lua::ILuaBase* LUA); +namespace lcpu { + /// Bindings of [riscv::System] to Lua. + struct LuaCpu : public lua::LuaObject { + /// Lua binding stuff + constexpr static const char* Name() { return "LuaCpu"; } + static void RegisterClass(GarrysMod::Lua::ILuaBase* LUA); - protected: - friend struct lcpu::lua::LuaObject; - LuaCpu(u32 memorySize); - ~LuaCpu(); - private: - LUA_MEMBER_FUNCTION(PoweredOn); // Check if the CPU is powered on - LUA_MEMBER_FUNCTION(Cycle); // do a single cycle (called internally by LCPU entity) - LUA_MEMBER_FUNCTION(PowerOff); // power off and reset the LCPU - LUA_MEMBER_FUNCTION(PowerOn); // power on the LCPU - LUA_MEMBER_FUNCTION(Reset); // reset the LCPU - LUA_MEMBER_FUNCTION(AttachDevice); // attach a LuaDevice to this cpu + protected: + friend struct lua::LuaObject; + LuaCpu(u32 memorySize); + ~LuaCpu(); - // member variables - riscv::System* system; - bool poweredOn; -}; + private: + LUA_MEMBER_FUNCTION(PoweredOn); // Check if the CPU is powered on + LUA_MEMBER_FUNCTION(Cycle); // do a single cycle (called internally by LCPU entity) + LUA_MEMBER_FUNCTION(PowerOff); // power off and reset the LCPU + LUA_MEMBER_FUNCTION(PowerOn); // power on the LCPU + LUA_MEMBER_FUNCTION(Reset); // reset the LCPU + LUA_MEMBER_FUNCTION(AttachDevice); // attach a LuaDevice to this cpu + + // member variables + riscv::System* system; + bool poweredOn; + }; + +} // namespace lcpu diff --git a/native/projects/lcpu/src/LuaDevice.cpp b/native/projects/lcpu/src/LuaDevice.cpp index af31841..38ddc2e 100644 --- a/native/projects/lcpu/src/LuaDevice.cpp +++ b/native/projects/lcpu/src/LuaDevice.cpp @@ -1,96 +1,112 @@ #include "LuaDevice.hpp" -void LuaDevice::RegisterClass(GarrysMod::Lua::ILuaBase* LUA) { - RegisterClassStart(LUA); +namespace lcpu { + void LuaDevice::RegisterClass(GarrysMod::Lua::ILuaBase* LUA) { + RegisterClassStart(LUA); - RegisterGetter("Base", [](GarrysMod::Lua::ILuaBase* LUA) { - auto self = LuaDevice::FromLua(LUA, 1); - LUA->PushNumber(static_cast(self->base)); - }); + RegisterGetter("Base", [](GarrysMod::Lua::ILuaBase* LUA) { + auto self = LuaDevice::FromLua(LUA, 1); + LUA->PushNumber(static_cast(self->base)); + }); - RegisterGetter("Size", [](GarrysMod::Lua::ILuaBase* LUA) { - auto self = LuaDevice::FromLua(LUA, 1); - LUA->PushNumber(static_cast(self->size)); - }); -} + RegisterGetter("Size", [](GarrysMod::Lua::ILuaBase* LUA) { + auto self = LuaDevice::FromLua(LUA, 1); + LUA->PushNumber(static_cast(self->size)); + }); + } -bool LuaDevice::Clocked() const { - // no real good rationale for checking here, - // since function calling does bail out properly - return true; -} + bool LuaDevice::Clocked() const { + // no real good rationale for checking here, + // since function calling does bail out properly + return true; + } -void LuaDevice::Clock() { - // clang-format off - lua->ReferencePush(GetTableReference()); - lua->GetField(-1,"Clock"); + void LuaDevice::Clock() { + // clang-format off + lua->ReferencePush(GetTableReference()); + lua->GetField(-1,"Clock"); + if(lua->GetType(-1) == GarrysMod::Lua::Type::Function) { + lua->Push(-2); // 'self' argument + lua->Call(1, 0); + } else { + lua->Pop(); // pop the Clock function off the stack + } + lua->Pop(); // pop the reference + // clang-format on + } + + riscv::Address LuaDevice::Base() const { + return base; + } + + riscv::Address LuaDevice::Size() const { + return base; + } + + u32 LuaDevice::Peek(riscv::Address address) { + // clang-format off + lua->ReferencePush(GetTableReference()); + lua->GetField(-1,"Peek"); + if(lua->GetType(-1) == GarrysMod::Lua::Type::Function) { + lua->Push(-2); // 'self' argument + lua->PushNumber(static_cast(address)); + lua->Call(2, 1); + + auto result = static_cast(lua->GetNumber(-1)); + lua->Pop(2); // pop result and the table off + return result; + } else { + lua->Pop(); // pop whatever Peek is off the stack + } + lua->Pop(); // pop the table reference + // clang-format on + return 0xffffffff; + } + + void LuaDevice::Poke(riscv::Address address, u32 value) { + // clang-format off + lua->ReferencePush(GetTableReference()); + lua->GetField(-1,"Poke"); + if(lua->GetType(-1) == GarrysMod::Lua::Type::Function) { + lua->Push(-2); // 'self' argument + lua->PushNumber(static_cast(address)); + lua->PushNumber(static_cast(value)); + lua->Call(3, 0); + } else { + lua->Pop(); // pop whatever Peek is + } + lua->Pop(); // pop the table reference + // clang-format on + } + + void LuaDevice::Reset() { + // clang-format off + lua->ReferencePush(GetTableReference()); + lua->GetField(-1,"Reset"); if(lua->GetType(-1) == GarrysMod::Lua::Type::Function) { lua->Push(-2); // 'self' argument lua->Call(1, 0); } else { - lua->Pop(); // pop the Clock function off the stack + lua->Pop(); // pop whatever reset is } - lua->Pop(); // pop the reference - // clang-format off -} + lua->Pop(); // pop the reference + // clang-format on + } -riscv::Address LuaDevice::Base() const { - return base; -} + LuaDevice::LuaDevice(riscv::Address base, riscv::Address size) : base(base), size(size) { + } -riscv::Address LuaDevice::Size() const { - return base; -} - -u32 LuaDevice::Peek(riscv::Address address) { - // clang-format off - lua->ReferencePush(GetTableReference()); - lua->GetField(-1,"Peek"); - if(lua->GetType(-1) == GarrysMod::Lua::Type::Function) { - lua->Push(-2); // 'self' argument - lua->PushNumber(static_cast(address)); - lua->Call(2, 1); - - auto result = static_cast(lua->GetNumber(-1)); - lua->Pop(2); // pop result and the table off - return result; - } else { - lua->Pop(); // pop whatever Peek is off the stack - } - lua->Pop(); // pop the table reference - // clang-format on - return 0xffffffff; -} - -void LuaDevice::Poke(riscv::Address address, u32 value) { - // clang-format off - lua->ReferencePush(GetTableReference()); - lua->GetField(-1,"Poke"); - if(lua->GetType(-1) == GarrysMod::Lua::Type::Function) { - lua->Push(-2); // 'self' argument - lua->PushNumber(static_cast(address)); - lua->PushNumber(static_cast(value)); - lua->Call(3, 0); - } else { - lua->Pop(); // pop whatever Peek is - } - lua->Pop(); // pop the table reference - // clang-format on -} - -void LuaDevice::Reset() { - // clang-format off - lua->ReferencePush(GetTableReference()); - lua->GetField(-1,"Reset"); - if(lua->GetType(-1) == GarrysMod::Lua::Type::Function) { - lua->Push(-2); // 'self' argument - lua->Call(1, 0); - } else { - lua->Pop(); // pop whatever reset is - } - lua->Pop(); // pop the reference - // clang-format on -} - -LuaDevice::LuaDevice(riscv::Address base, riscv::Address size) : base(base), size(size) { -} + void LuaDevice::AfterLuaInit() { + // Our Lua callbacks only get the table, not the actual userdata, + // ao we have to mirror things :( kinda sucks, but meh + + // clang-format off + lua->ReferencePush(GetTableReference()); + lua->PushNumber(static_cast(base)); + lua->SetField(-2, "Base"); + lua->PushNumber(static_cast(base)); + lua->SetField(-2, "Size"); + lua->Pop(); + // clang-format on + } +} // namespace lcpu diff --git a/native/projects/lcpu/src/LuaDevice.hpp b/native/projects/lcpu/src/LuaDevice.hpp index 4589231..1ddb13e 100644 --- a/native/projects/lcpu/src/LuaDevice.hpp +++ b/native/projects/lcpu/src/LuaDevice.hpp @@ -5,29 +5,33 @@ #include "LuaHelpers.hpp" #include "LuaObject.hpp" -/// A work-in-progress binding of [riscv::Bus::MmioDevice] to lua -struct LuaDevice : public riscv::Bus::MmioDevice, lcpu::lua::LuaObject { - /// Lua binding stuff - constexpr static const char* Name() { return "LuaDevice"; } - static void RegisterClass(GarrysMod::Lua::ILuaBase* LUA); +namespace lcpu { + /// A work-in-progress binding of [riscv::Bus::MmioDevice] to lua + struct LuaDevice : public riscv::Bus::MmioDevice, lcpu::lua::LuaObject { + /// Lua binding stuff + constexpr static const char* Name() { return "LuaDevice"; } + static void RegisterClass(GarrysMod::Lua::ILuaBase* LUA); - // [riscv::Bus::MmioDevice] implementation - bool Clocked() const override; - void Clock() override; - void Reset() override; + // [riscv::Bus::MmioDevice] implementation + bool Clocked() const override; + void Clock() override; + void Reset() override; - riscv::Address Base() const override; - riscv::Address Size() const override; + riscv::Address Base() const override; + riscv::Address Size() const override; - u32 Peek(riscv::Address address) override; - void Poke(riscv::Address address, u32 value) override; + u32 Peek(riscv::Address address) override; + void Poke(riscv::Address address, u32 value) override; - protected: - friend lcpu::lua::LuaObject; - LuaDevice(riscv::Address base, riscv::Address size); - ~LuaDevice() = default; + protected: + friend lcpu::lua::LuaObject; + LuaDevice(riscv::Address base, riscv::Address size); + ~LuaDevice() = default; - private: - riscv::Address base {}; - riscv::Address size {}; -}; + void AfterLuaInit() override; + + private: + riscv::Address base {}; + riscv::Address size {}; + }; +} // namespace lcpu diff --git a/native/projects/lcpu/src/LuaHelpers.hpp b/native/projects/lcpu/src/LuaHelpers.hpp index d61d36f..83295b6 100644 --- a/native/projects/lcpu/src/LuaHelpers.hpp +++ b/native/projects/lcpu/src/LuaHelpers.hpp @@ -1,4 +1,6 @@ -//! Helpers for lua binding +//! Helpers for binding Lua and C++. +//! If you want to bind a C++ class to Lua, see the +//! [lcpu::lua::LuaObject] type in LuaObject.hpp #pragma once #include @@ -20,14 +22,6 @@ #define LUA_MEMBER_FUNCTION_IMPLEMENT(CLASS, FUNC) int CLASS::FUNC##__ImpStatic(GarrysMod::Lua::ILuaBase* LUA) -// this synthesizes a lambda which takes the stack argument to get. this can actually also be -// stored as a variable for later usage (... if you so desire?) -#define LUA_CLASS_GET(T) \ - [LUA](int stackPos) { \ - LUA->CheckType(stackPos, T::__lua_typeid); \ - return LUA->GetUserType(stackPos, T::__lua_typeid); \ - } - // Set a C function as a field. #define LUA_SET_C_FUNCTION(name) \ LUA->PushCFunction(name); \ diff --git a/native/projects/lcpu/src/LuaObject.hpp b/native/projects/lcpu/src/LuaObject.hpp index 4c8599f..ee08cdb 100644 --- a/native/projects/lcpu/src/LuaObject.hpp +++ b/native/projects/lcpu/src/LuaObject.hpp @@ -10,6 +10,9 @@ namespace lcpu::lua { /// A CRTP-based class which allows binding C++ to Lua, in a /// fairly sensible manner. + /// + /// Classes backed by this class can have arbitrary properties + /// created by Lua (using a backing table created by this object). template struct LuaObject { using CFunc = GarrysMod::Lua::CFunc; @@ -26,12 +29,15 @@ namespace lcpu::lua { /// C++ registered value read-write. static void RegisterSetter(const std::string& name, ILuaVoidFunc func) { setters()[name] = func; } + virtual void AfterLuaInit() {}; + /// Create an instance of this type to give to Lua. /// addl. arguments are forwarded to the C++ constructor template static void Create(GarrysMod::Lua::ILuaBase* LUA, Args&&... args) { auto ptr = new TImpl(static_cast(args)...); ptr->InitLuaStuff(LUA); + ptr->AfterLuaInit(); LUA->PushUserType(ptr, __lua_typeid); } @@ -85,14 +91,14 @@ namespace lcpu::lua { LUA->CreateTable(); tableReference = LUA->ReferenceCreate(); - // register some convinence things + // register some convinence getters RegisterGetter("Name", [](GarrysMod::Lua::ILuaBase* LUA) { LUA->PushString(TImpl::Name()); }); } int GetTableReference() { return tableReference; } LuaObject() = default; - ~LuaObject() { + virtual ~LuaObject() { // free the table reference if(tableReference != -1) lua->ReferenceFree(tableReference); diff --git a/native/projects/lcpu/src/main.cpp b/native/projects/lcpu/src/main.cpp index 3ee4596..23a0dda 100644 --- a/native/projects/lcpu/src/main.cpp +++ b/native/projects/lcpu/src/main.cpp @@ -11,7 +11,7 @@ GMOD_MODULE_OPEN() { lucore::Logger::The().AttachSink(lcpu::SourceSink::The()); lucore::LogInfo("LCPU Native Module! (ModuleVersion {})", LCPU_MODULE_VERSION); - GlobalsBind(LUA); + lcpu::GlobalsBind(LUA); return 0; }