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