Move LuaDevice to LuaObject

This commit is contained in:
Lily Tsuru 2023-07-27 16:30:59 -04:00
parent df8647525b
commit deadeb5c51
6 changed files with 69 additions and 129 deletions

View File

@ -10,7 +10,7 @@ if SERVER then
return return
end end
----[[ --[[
testobj = LCPUNative.CreateTest() testobj = LCPUNative.CreateTest()
print(testobj:Test()) print(testobj:Test())
print(testobj.Variable) print(testobj.Variable)
@ -24,10 +24,10 @@ if SERVER then
print(testobj.Variable) print(testobj.Variable)
print(testobj.Name) print(testobj.Name)
--]] ]]
-- rapid iteration requires rapid solutions -- rapid iteration requires rapid solutions
--[[ --[[
device = LCPUNative.CreateDevice(0x100000f0, 0x10) device = LCPUNative.CreateDevice(0x100000f0, 0x10)
device.a = 12 device.a = 12
device.apple = {} device.apple = {}
@ -36,6 +36,10 @@ if SERVER then
--print(device.a) --print(device.a)
--print(device.apple) --print(device.apple)
print("name property is " .. device.Name)
print("base property is " .. device.Base)
print("size property is " .. device.Size)
function device:Clock() function device:Clock()
print("a") print("a")
end end
@ -71,5 +75,6 @@ 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(); cpu:Cycle();cpu:Cycle();cpu:Cycle();cpu:Cycle();
]] ]]
AddCSLuaFile("entities/gmod_lcpu_cpu.lua") AddCSLuaFile("entities/gmod_lcpu_cpu.lua")
end end

View File

@ -66,8 +66,7 @@ LUA_FUNCTION(LCPUNative_CreateDevice) {
void GlobalsBind(GarrysMod::Lua::ILuaBase* LUA) { void GlobalsBind(GarrysMod::Lua::ILuaBase* LUA) {
LuaCpu::Bind(LUA); LuaCpu::Bind(LUA);
LuaDevice::Bind(LUA); LuaDevice::RegisterClass(LUA);
TestLuaObject::RegisterClass(LUA); TestLuaObject::RegisterClass(LUA);
// clang-format off // clang-format off

View File

@ -75,7 +75,7 @@ LUA_MEMBER_FUNCTION_IMPLEMENT(LuaCpu, Reset) {
LUA_MEMBER_FUNCTION_IMPLEMENT(LuaCpu, AttachDevice) { LUA_MEMBER_FUNCTION_IMPLEMENT(LuaCpu, AttachDevice) {
auto self = LUA_CLASS_GET(LuaCpu)(1); auto self = LUA_CLASS_GET(LuaCpu)(1);
auto device = LUA_CLASS_GET(LuaDevice)(2); auto device = LuaDevice::FromLua(LUA, 2);
// Attach it // Attach it
LUA->PushBool(self->system->bus->AttachDevice(static_cast<riscv::Bus::Device*>(device))); LUA->PushBool(self->system->bus->AttachDevice(static_cast<riscv::Bus::Device*>(device)));

View File

@ -1,6 +1,18 @@
#include "LuaDevice.hpp" #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<double>(self->base));
});
RegisterGetter("Size", [](GarrysMod::Lua::ILuaBase* LUA) {
auto self = LuaDevice::FromLua(LUA, 1);
LUA->PushNumber(static_cast<double>(self->size));
});
}
bool LuaDevice::Clocked() const { bool LuaDevice::Clocked() const {
// no real good rationale for checking here, // no real good rationale for checking here,
@ -10,15 +22,15 @@ bool LuaDevice::Clocked() const {
void LuaDevice::Clock() { void LuaDevice::Clock() {
// clang-format off // clang-format off
LuaState->ReferencePush(tableReference); lua->ReferencePush(GetTableReference());
LuaState->GetField(-1,"Clock"); lua->GetField(-1,"Clock");
if(LuaState->GetType(-1) == GarrysMod::Lua::Type::Function) { if(lua->GetType(-1) == GarrysMod::Lua::Type::Function) {
LuaState->Push(-2); // 'self' argument lua->Push(-2); // 'self' argument
LuaState->Call(1, 0); lua->Call(1, 0);
} else { } 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 // clang-format off
} }
@ -32,126 +44,53 @@ riscv::Address LuaDevice::Size() const {
u32 LuaDevice::Peek(riscv::Address address) { u32 LuaDevice::Peek(riscv::Address address) {
// clang-format off // clang-format off
LuaState->ReferencePush(tableReference); lua->ReferencePush(GetTableReference());
LuaState->GetField(-1,"Peek"); lua->GetField(-1,"Peek");
if(LuaState->GetType(-1) == GarrysMod::Lua::Type::Function) { if(lua->GetType(-1) == GarrysMod::Lua::Type::Function) {
LuaState->Push(-2); // 'self' argument lua->Push(-2); // 'self' argument
LuaState->PushNumber(static_cast<double>(address)); lua->PushNumber(static_cast<double>(address));
LuaState->Call(2, 1); lua->Call(2, 1);
auto result = static_cast<u32>(LuaState->GetNumber(-1)); auto result = static_cast<u32>(lua->GetNumber(-1));
LuaState->Pop(2); // pop result and the table off lua->Pop(2); // pop result and the table off
return result; return result;
} else { } 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 // clang-format on
return 0xffffffff; return 0xffffffff;
} }
void LuaDevice::Poke(riscv::Address address, u32 value) { void LuaDevice::Poke(riscv::Address address, u32 value) {
// clang-format off // clang-format off
LuaState->ReferencePush(tableReference); lua->ReferencePush(GetTableReference());
LuaState->GetField(-1,"Poke"); lua->GetField(-1,"Poke");
if(LuaState->GetType(-1) == GarrysMod::Lua::Type::Function) { if(lua->GetType(-1) == GarrysMod::Lua::Type::Function) {
LuaState->Push(-2); // 'self' argument lua->Push(-2); // 'self' argument
LuaState->PushNumber(static_cast<double>(address)); lua->PushNumber(static_cast<double>(address));
LuaState->PushNumber(static_cast<double>(value)); lua->PushNumber(static_cast<double>(value));
LuaState->Call(3, 0); lua->Call(3, 0);
} else { } 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 // clang-format on
} }
void LuaDevice::Reset() { void LuaDevice::Reset() {
// clang-format off // clang-format off
LuaState->ReferencePush(tableReference); lua->ReferencePush(GetTableReference());
LuaState->GetField(-1,"Reset"); lua->GetField(-1,"Reset");
if(LuaState->GetType(-1) == GarrysMod::Lua::Type::Function) { if(lua->GetType(-1) == GarrysMod::Lua::Type::Function) {
LuaState->Push(-2); // 'self' argument lua->Push(-2); // 'self' argument
LuaState->Call(1, 0); lua->Call(1, 0);
} else { } 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 // clang-format on
} }
LuaDevice::LuaDevice(riscv::Address base, riscv::Address size) : base(base), size(size) { 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<double>(base));
LUA->SetField(-2, "Base");
LUA->PushNumber(static_cast<double>(base));
LUA->SetField(-2, "Size");
LUA->Pop();
LUA->PushUserType(device, __lua_typeid);
}

View File

@ -3,15 +3,15 @@
#include <riscv/Bus.hpp> #include <riscv/Bus.hpp>
#include "LuaHelpers.hpp" #include "LuaHelpers.hpp"
#include "LuaObject.hpp"
/// A work-in-progress binding of [riscv::Bus::MmioDevice] to lua /// 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<LuaDevice> {
/// Lua binding stuff /// Lua binding stuff
static void Bind(GarrysMod::Lua::ILuaBase* LUA); constexpr static const char* Name() { return "LuaDevice"; }
static void Create(GarrysMod::Lua::ILuaBase* LUA, riscv::Address base, riscv::Address size); static void RegisterClass(GarrysMod::Lua::ILuaBase* LUA);
~LuaDevice();
// [riscv::Bus::MmioDevice] implementation
bool Clocked() const override; bool Clocked() const override;
void Clock() override; void Clock() override;
void Reset() override; void Reset() override;
@ -22,19 +22,12 @@ struct LuaDevice : public riscv::Bus::MmioDevice {
u32 Peek(riscv::Address address) override; u32 Peek(riscv::Address address) override;
void Poke(riscv::Address address, u32 value) override; void Poke(riscv::Address address, u32 value) override;
private: protected:
// class binding stuff friend lcpu::lua::LuaObject<LuaDevice>;
LUA_CLASS_BIND_VARIABLES(private);
LUA_MEMBER_FUNCTION(__index);
LUA_MEMBER_FUNCTION(__newindex);
LuaDevice(riscv::Address base, riscv::Address size); LuaDevice(riscv::Address base, riscv::Address size);
~LuaDevice() = default;
private:
riscv::Address base {}; riscv::Address base {};
riscv::Address size {}; riscv::Address size {};
GarrysMod::Lua::ILuaBase* LuaState;
// this should be a common type tbh
int tableReference = -1;
}; };

View File

@ -1,3 +1,5 @@
#pragma once
//#include <functional> //#include <functional>
#include "GarrysMod/Lua/Interface.h" #include "GarrysMod/Lua/Interface.h"
@ -93,6 +95,8 @@ namespace lcpu::lua {
RegisterGetter("Name", [](GarrysMod::Lua::ILuaBase* LUA) { LUA->PushString(TImpl::Name()); }); RegisterGetter("Name", [](GarrysMod::Lua::ILuaBase* LUA) { LUA->PushString(TImpl::Name()); });
} }
int GetTableReference() { return tableReference; }
LuaObject() = default; LuaObject() = default;
~LuaObject() { ~LuaObject() {
// free the table reference // free the table reference