Move LuaDevice to LuaObject
This commit is contained in:
parent
df8647525b
commit
deadeb5c51
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue