diff --git a/lua/autorun/lcpu_load.lua b/lua/autorun/lcpu_load.lua index b835679..910b2fe 100644 --- a/lua/autorun/lcpu_load.lua +++ b/lua/autorun/lcpu_load.lua @@ -10,7 +10,7 @@ if SERVER then return end -----[[ +--[[ testobj = LCPUNative.CreateTest() print(testobj:Test()) print(testobj.Variable) @@ -24,10 +24,10 @@ if SERVER then print(testobj.Variable) print(testobj.Name) ---]] +]] -- rapid iteration requires rapid solutions - --[[ +--[[ device = LCPUNative.CreateDevice(0x100000f0, 0x10) device.a = 12 device.apple = {} @@ -36,6 +36,10 @@ if SERVER then --print(device.a) --print(device.apple) + print("name property is " .. device.Name) + print("base property is " .. device.Base) + print("size property is " .. device.Size) + function device:Clock() print("a") end @@ -71,5 +75,6 @@ end 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 a720ac6..321845c 100644 --- a/native/projects/lcpu/src/LcpuGlobals.cpp +++ b/native/projects/lcpu/src/LcpuGlobals.cpp @@ -66,8 +66,7 @@ LUA_FUNCTION(LCPUNative_CreateDevice) { void GlobalsBind(GarrysMod::Lua::ILuaBase* LUA) { LuaCpu::Bind(LUA); - LuaDevice::Bind(LUA); - + LuaDevice::RegisterClass(LUA); TestLuaObject::RegisterClass(LUA); // clang-format off diff --git a/native/projects/lcpu/src/LuaCpu.cpp b/native/projects/lcpu/src/LuaCpu.cpp index cf2d4a2..255be64 100644 --- a/native/projects/lcpu/src/LuaCpu.cpp +++ b/native/projects/lcpu/src/LuaCpu.cpp @@ -75,7 +75,7 @@ LUA_MEMBER_FUNCTION_IMPLEMENT(LuaCpu, Reset) { LUA_MEMBER_FUNCTION_IMPLEMENT(LuaCpu, AttachDevice) { auto self = LUA_CLASS_GET(LuaCpu)(1); - auto device = LUA_CLASS_GET(LuaDevice)(2); + auto device = LuaDevice::FromLua(LUA, 2); // Attach it LUA->PushBool(self->system->bus->AttachDevice(static_cast(device))); diff --git a/native/projects/lcpu/src/LuaDevice.cpp b/native/projects/lcpu/src/LuaDevice.cpp index 2bfb48c..af31841 100644 --- a/native/projects/lcpu/src/LuaDevice.cpp +++ b/native/projects/lcpu/src/LuaDevice.cpp @@ -1,6 +1,18 @@ #include "LuaDevice.hpp" -LUA_CLASS_BIND_VARIABLES_IMPLEMENT(LuaDevice); +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("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, @@ -10,15 +22,15 @@ bool LuaDevice::Clocked() const { void LuaDevice::Clock() { // clang-format off - LuaState->ReferencePush(tableReference); - LuaState->GetField(-1,"Clock"); - if(LuaState->GetType(-1) == GarrysMod::Lua::Type::Function) { - LuaState->Push(-2); // 'self' argument - LuaState->Call(1, 0); + 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 { - LuaState->Pop(); // pop the Clock function off the stack + lua->Pop(); // pop the Clock function off the stack } - LuaState->Pop(); // pop the reference + lua->Pop(); // pop the reference // clang-format off } @@ -32,126 +44,53 @@ riscv::Address LuaDevice::Size() const { u32 LuaDevice::Peek(riscv::Address address) { // clang-format off - LuaState->ReferencePush(tableReference); - LuaState->GetField(-1,"Peek"); - if(LuaState->GetType(-1) == GarrysMod::Lua::Type::Function) { - LuaState->Push(-2); // 'self' argument - LuaState->PushNumber(static_cast(address)); - LuaState->Call(2, 1); + 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(LuaState->GetNumber(-1)); - LuaState->Pop(2); // pop result and the table off + auto result = static_cast(lua->GetNumber(-1)); + lua->Pop(2); // pop result and the table off return result; } else { - LuaState->Pop(); // pop whatever Peek is off the stack + lua->Pop(); // pop whatever Peek is off the stack } - LuaState->Pop(); // pop the table reference + lua->Pop(); // pop the table reference // clang-format on return 0xffffffff; } void LuaDevice::Poke(riscv::Address address, u32 value) { // clang-format off - LuaState->ReferencePush(tableReference); - LuaState->GetField(-1,"Poke"); - if(LuaState->GetType(-1) == GarrysMod::Lua::Type::Function) { - LuaState->Push(-2); // 'self' argument - LuaState->PushNumber(static_cast(address)); - LuaState->PushNumber(static_cast(value)); - LuaState->Call(3, 0); + 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 { - LuaState->Pop(); // pop whatever Peek is + lua->Pop(); // pop whatever Peek is } - LuaState->Pop(); // pop the table reference + lua->Pop(); // pop the table reference // clang-format on } void LuaDevice::Reset() { // clang-format off - LuaState->ReferencePush(tableReference); - LuaState->GetField(-1,"Reset"); - if(LuaState->GetType(-1) == GarrysMod::Lua::Type::Function) { - LuaState->Push(-2); // 'self' argument - LuaState->Call(1, 0); + 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 { - LuaState->Pop(); // pop whatever reset is + lua->Pop(); // pop whatever reset is } - LuaState->Pop(); // pop the reference + lua->Pop(); // pop the reference // clang-format on } LuaDevice::LuaDevice(riscv::Address base, riscv::Address size) : base(base), size(size) { } - -LuaDevice::~LuaDevice() { - // Free all refererences - if(tableReference == -1) - LuaState->ReferenceFree(tableReference); -} - -LUA_MEMBER_FUNCTION_IMPLEMENT(LuaDevice, __index) { - auto self = LUA_CLASS_GET(LuaDevice)(1); - // lucore::LogInfo("metamethod __index call"); - - // TODO: before moving this to a shared lua object class thing - // and moving the CPU class to use this way of doing things - // I should probably try and like, add stuff to ensure native - // methods can be registered as well,, - LUA->ReferencePush(self->tableReference); - LUA->Push(2); - LUA->GetTable(-2); - return 1; // the value -} - -LUA_MEMBER_FUNCTION_IMPLEMENT(LuaDevice, __newindex) { - auto self = LUA_CLASS_GET(LuaDevice)(1); - // lucore::LogInfo("metamethod __newindex call"); - - // Always push onto the table. - // TODO: This function - // should error on attempt to __newindex any native methods - // (when moved to a shared place) - LUA->ReferencePush(self->tableReference); - LUA->Push(2); - LUA->Push(3); - LUA->SetTable(-3); - LUA->Pop(); - return 0; -} - -void LuaDevice::Bind(GarrysMod::Lua::ILuaBase* LUA) { - // clang-format off - //LUA_CLASS_BIND_BEGIN(LuaDevice) - __lua_typeid = LUA->CreateMetaTable("LuaDevice"); - LUA->PushSpecial(GarrysMod::Lua::SPECIAL_REG); - LUA->PushNumber(__lua_typeid); - LUA->SetField(-2, "LuaDevice__typeid"); - LUA->Pop(); /* pop registry */ - - LUA_SET_C_FUNCTION(__gc) - LUA_SET_C_FUNCTION(__index) - LUA_SET_C_FUNCTION(__newindex) - LUA_CLASS_BIND_END(); - // clang-format on -} - -void LuaDevice::Create(GarrysMod::Lua::ILuaBase* LUA, riscv::Address base, riscv::Address size) { - auto device = new LuaDevice(base, size); - device->LuaState = LUA; - - LUA->CreateTable(); - device->tableReference = LUA->ReferenceCreate(); - LUA->Pop(); - - // push base/size properties for lua to have a looksee at ! - // ideally these should be handled as metamethods in __index, - // but i don't quite feel like making gmod sol2 yet /shrug - LUA->ReferencePush(device->tableReference); - LUA->PushNumber(static_cast(base)); - LUA->SetField(-2, "Base"); - LUA->PushNumber(static_cast(base)); - LUA->SetField(-2, "Size"); - LUA->Pop(); - - LUA->PushUserType(device, __lua_typeid); -} diff --git a/native/projects/lcpu/src/LuaDevice.hpp b/native/projects/lcpu/src/LuaDevice.hpp index 4b8dd98..4589231 100644 --- a/native/projects/lcpu/src/LuaDevice.hpp +++ b/native/projects/lcpu/src/LuaDevice.hpp @@ -3,15 +3,15 @@ #include #include "LuaHelpers.hpp" +#include "LuaObject.hpp" /// A work-in-progress binding of [riscv::Bus::MmioDevice] to lua -struct LuaDevice : public riscv::Bus::MmioDevice { +struct LuaDevice : public riscv::Bus::MmioDevice, lcpu::lua::LuaObject { /// Lua binding stuff - static void Bind(GarrysMod::Lua::ILuaBase* LUA); - static void Create(GarrysMod::Lua::ILuaBase* LUA, riscv::Address base, riscv::Address size); - - ~LuaDevice(); + 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; @@ -22,19 +22,12 @@ struct LuaDevice : public riscv::Bus::MmioDevice { u32 Peek(riscv::Address address) override; void Poke(riscv::Address address, u32 value) override; - private: - // class binding stuff - LUA_CLASS_BIND_VARIABLES(private); - - LUA_MEMBER_FUNCTION(__index); - LUA_MEMBER_FUNCTION(__newindex); - + protected: + friend lcpu::lua::LuaObject; LuaDevice(riscv::Address base, riscv::Address size); + ~LuaDevice() = default; + private: riscv::Address base {}; riscv::Address size {}; - GarrysMod::Lua::ILuaBase* LuaState; - - // this should be a common type tbh - int tableReference = -1; }; diff --git a/native/projects/lcpu/src/LuaObject.hpp b/native/projects/lcpu/src/LuaObject.hpp index 1d16811..dceee83 100644 --- a/native/projects/lcpu/src/LuaObject.hpp +++ b/native/projects/lcpu/src/LuaObject.hpp @@ -1,3 +1,5 @@ +#pragma once + //#include #include "GarrysMod/Lua/Interface.h" @@ -93,6 +95,8 @@ namespace lcpu::lua { RegisterGetter("Name", [](GarrysMod::Lua::ILuaBase* LUA) { LUA->PushString(TImpl::Name()); }); } + int GetTableReference() { return tableReference; } + LuaObject() = default; ~LuaObject() { // free the table reference