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
end
----[[
--[[
testobj = LCPUNative.CreateTest()
print(testobj:Test())
print(testobj.Variable)
@ -24,7 +24,7 @@ if SERVER then
print(testobj.Variable)
print(testobj.Name)
--]]
]]
-- rapid iteration requires rapid solutions
--[[
@ -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

View File

@ -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

View File

@ -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<riscv::Bus::Device*>(device)));

View File

@ -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<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 {
// 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<double>(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<double>(address));
lua->Call(2, 1);
auto result = static_cast<u32>(LuaState->GetNumber(-1));
LuaState->Pop(2); // pop result and the table off
auto result = static_cast<u32>(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<double>(address));
LuaState->PushNumber(static_cast<double>(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<double>(address));
lua->PushNumber(static_cast<double>(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<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 "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<LuaDevice> {
/// 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>;
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;
};

View File

@ -1,3 +1,5 @@
#pragma once
//#include <functional>
#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