fixup luadevice binding a bit
This commit is contained in:
parent
edc5def251
commit
1d0830160b
|
@ -26,7 +26,7 @@ if SERVER then
|
||||||
print("size property is " .. device.Size)
|
print("size property is " .. device.Size)
|
||||||
|
|
||||||
function device:Clock()
|
function device:Clock()
|
||||||
print("a")
|
print(self.Base)
|
||||||
end
|
end
|
||||||
|
|
||||||
function device:Peek(address)
|
function device:Peek(address)
|
||||||
|
@ -59,7 +59,7 @@ 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();
|
||||||
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
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "LuaCpu.hpp"
|
#include "LuaCpu.hpp"
|
||||||
#include "LuaDevice.hpp"
|
#include "LuaDevice.hpp"
|
||||||
|
|
||||||
|
namespace lcpu {
|
||||||
LUA_FUNCTION(LCPUNative_CreateCPU) {
|
LUA_FUNCTION(LCPUNative_CreateCPU) {
|
||||||
LUA->CheckType(1, GarrysMod::Lua::Type::Number);
|
LUA->CheckType(1, GarrysMod::Lua::Type::Number);
|
||||||
auto memorySize = static_cast<u32>(LUA->GetNumber(1));
|
auto memorySize = static_cast<u32>(LUA->GetNumber(1));
|
||||||
|
@ -41,3 +42,5 @@ void GlobalsBind(GarrysMod::Lua::ILuaBase* LUA) {
|
||||||
LUA->Pop();
|
LUA->Pop();
|
||||||
// clang-format on
|
// clang-format on
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace lcpu
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
#include "LuaHelpers.hpp"
|
#include "LuaHelpers.hpp"
|
||||||
|
|
||||||
|
namespace lcpu {
|
||||||
/// This should be bumped on any incompatible change to the native bindings
|
/// This should be bumped on any incompatible change to the native bindings
|
||||||
/// that would break older Lua code, or requires newer Lua code to run.
|
/// that would break older Lua code, or requires newer Lua code to run.
|
||||||
#define LCPU_MODULE_VERSION 1
|
#define LCPU_MODULE_VERSION 1
|
||||||
|
|
||||||
void GlobalsBind(GarrysMod::Lua::ILuaBase* LUA);
|
void GlobalsBind(GarrysMod::Lua::ILuaBase* LUA);
|
||||||
|
|
||||||
|
} // namespace lcpu
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
|
|
||||||
#include "LuaDevice.hpp"
|
#include "LuaDevice.hpp"
|
||||||
|
|
||||||
// this is temporary from the thing
|
// this is temporary from the test harness, and will be replaced
|
||||||
|
// at some point.
|
||||||
/// simple 16550 UART implementation
|
/// simple 16550 UART implementation
|
||||||
struct SimpleUartDevice : public riscv::Bus::MmioDevice {
|
struct SimpleUartDevice : public riscv::Bus::MmioDevice {
|
||||||
constexpr static riscv::Address BASE_ADDRESS = 0x10000000;
|
constexpr static riscv::Address BASE_ADDRESS = 0x10000000;
|
||||||
|
@ -30,6 +30,7 @@ struct SimpleUartDevice : public riscv::Bus::MmioDevice {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace lcpu {
|
||||||
LUA_MEMBER_FUNCTION_IMPLEMENT(LuaCpu, PoweredOn) {
|
LUA_MEMBER_FUNCTION_IMPLEMENT(LuaCpu, PoweredOn) {
|
||||||
auto self = LuaCpu::FromLua(LUA, 1);
|
auto self = LuaCpu::FromLua(LUA, 1);
|
||||||
LUA->PushBool(self->poweredOn);
|
LUA->PushBool(self->poweredOn);
|
||||||
|
@ -114,3 +115,5 @@ LuaCpu::LuaCpu(u32 memorySize) {
|
||||||
LuaCpu::~LuaCpu() {
|
LuaCpu::~LuaCpu() {
|
||||||
delete system;
|
delete system;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace lcpu
|
||||||
|
|
|
@ -4,16 +4,18 @@
|
||||||
|
|
||||||
#include "LuaObject.hpp"
|
#include "LuaObject.hpp"
|
||||||
|
|
||||||
|
namespace lcpu {
|
||||||
/// Bindings of [riscv::System] to Lua.
|
/// Bindings of [riscv::System] to Lua.
|
||||||
struct LuaCpu : public lcpu::lua::LuaObject<LuaCpu> {
|
struct LuaCpu : public lua::LuaObject<LuaCpu> {
|
||||||
/// Lua binding stuff
|
/// Lua binding stuff
|
||||||
constexpr static const char* Name() { return "LuaCpu"; }
|
constexpr static const char* Name() { return "LuaCpu"; }
|
||||||
static void RegisterClass(GarrysMod::Lua::ILuaBase* LUA);
|
static void RegisterClass(GarrysMod::Lua::ILuaBase* LUA);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend struct lcpu::lua::LuaObject<LuaCpu>;
|
friend struct lua::LuaObject<LuaCpu>;
|
||||||
LuaCpu(u32 memorySize);
|
LuaCpu(u32 memorySize);
|
||||||
~LuaCpu();
|
~LuaCpu();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LUA_MEMBER_FUNCTION(PoweredOn); // Check if the CPU is powered on
|
LUA_MEMBER_FUNCTION(PoweredOn); // Check if the CPU is powered on
|
||||||
LUA_MEMBER_FUNCTION(Cycle); // do a single cycle (called internally by LCPU entity)
|
LUA_MEMBER_FUNCTION(Cycle); // do a single cycle (called internally by LCPU entity)
|
||||||
|
@ -26,3 +28,5 @@ struct LuaCpu : public lcpu::lua::LuaObject<LuaCpu> {
|
||||||
riscv::System* system;
|
riscv::System* system;
|
||||||
bool poweredOn;
|
bool poweredOn;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace lcpu
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "LuaDevice.hpp"
|
#include "LuaDevice.hpp"
|
||||||
|
|
||||||
|
namespace lcpu {
|
||||||
void LuaDevice::RegisterClass(GarrysMod::Lua::ILuaBase* LUA) {
|
void LuaDevice::RegisterClass(GarrysMod::Lua::ILuaBase* LUA) {
|
||||||
RegisterClassStart(LUA);
|
RegisterClassStart(LUA);
|
||||||
|
|
||||||
|
@ -31,7 +32,7 @@ void LuaDevice::Clock() {
|
||||||
lua->Pop(); // pop the Clock function off the stack
|
lua->Pop(); // pop the Clock function off the stack
|
||||||
}
|
}
|
||||||
lua->Pop(); // pop the reference
|
lua->Pop(); // pop the reference
|
||||||
// clang-format off
|
// clang-format on
|
||||||
}
|
}
|
||||||
|
|
||||||
riscv::Address LuaDevice::Base() const {
|
riscv::Address LuaDevice::Base() const {
|
||||||
|
@ -94,3 +95,18 @@ void LuaDevice::Reset() {
|
||||||
|
|
||||||
LuaDevice::LuaDevice(riscv::Address base, riscv::Address size) : base(base), size(size) {
|
LuaDevice::LuaDevice(riscv::Address base, riscv::Address size) : base(base), size(size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LuaDevice::AfterLuaInit() {
|
||||||
|
// Our Lua callbacks only get the table, not the actual userdata,
|
||||||
|
// ao we have to mirror things :( kinda sucks, but meh
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
lua->ReferencePush(GetTableReference());
|
||||||
|
lua->PushNumber(static_cast<double>(base));
|
||||||
|
lua->SetField(-2, "Base");
|
||||||
|
lua->PushNumber(static_cast<double>(base));
|
||||||
|
lua->SetField(-2, "Size");
|
||||||
|
lua->Pop();
|
||||||
|
// clang-format on
|
||||||
|
}
|
||||||
|
} // namespace lcpu
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "LuaHelpers.hpp"
|
#include "LuaHelpers.hpp"
|
||||||
#include "LuaObject.hpp"
|
#include "LuaObject.hpp"
|
||||||
|
|
||||||
|
namespace lcpu {
|
||||||
/// 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, lcpu::lua::LuaObject<LuaDevice> {
|
struct LuaDevice : public riscv::Bus::MmioDevice, lcpu::lua::LuaObject<LuaDevice> {
|
||||||
/// Lua binding stuff
|
/// Lua binding stuff
|
||||||
|
@ -27,7 +28,10 @@ struct LuaDevice : public riscv::Bus::MmioDevice, lcpu::lua::LuaObject<LuaDevice
|
||||||
LuaDevice(riscv::Address base, riscv::Address size);
|
LuaDevice(riscv::Address base, riscv::Address size);
|
||||||
~LuaDevice() = default;
|
~LuaDevice() = default;
|
||||||
|
|
||||||
|
void AfterLuaInit() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
riscv::Address base {};
|
riscv::Address base {};
|
||||||
riscv::Address size {};
|
riscv::Address size {};
|
||||||
};
|
};
|
||||||
|
} // namespace lcpu
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
//! Helpers for lua binding
|
//! Helpers for binding Lua and C++.
|
||||||
|
//! If you want to bind a C++ class to Lua, see the
|
||||||
|
//! [lcpu::lua::LuaObject<TImpl>] type in LuaObject.hpp
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <GarrysMod/Lua/Interface.h>
|
#include <GarrysMod/Lua/Interface.h>
|
||||||
|
@ -20,14 +22,6 @@
|
||||||
|
|
||||||
#define LUA_MEMBER_FUNCTION_IMPLEMENT(CLASS, FUNC) int CLASS::FUNC##__ImpStatic(GarrysMod::Lua::ILuaBase* LUA)
|
#define LUA_MEMBER_FUNCTION_IMPLEMENT(CLASS, FUNC) int CLASS::FUNC##__ImpStatic(GarrysMod::Lua::ILuaBase* LUA)
|
||||||
|
|
||||||
// this synthesizes a lambda which takes the stack argument to get. this can actually also be
|
|
||||||
// stored as a variable for later usage (... if you so desire?)
|
|
||||||
#define LUA_CLASS_GET(T) \
|
|
||||||
[LUA](int stackPos) { \
|
|
||||||
LUA->CheckType(stackPos, T::__lua_typeid); \
|
|
||||||
return LUA->GetUserType<T>(stackPos, T::__lua_typeid); \
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set a C function as a field.
|
// Set a C function as a field.
|
||||||
#define LUA_SET_C_FUNCTION(name) \
|
#define LUA_SET_C_FUNCTION(name) \
|
||||||
LUA->PushCFunction(name); \
|
LUA->PushCFunction(name); \
|
||||||
|
|
|
@ -10,6 +10,9 @@ namespace lcpu::lua {
|
||||||
|
|
||||||
/// A CRTP-based class which allows binding C++ to Lua, in a
|
/// A CRTP-based class which allows binding C++ to Lua, in a
|
||||||
/// fairly sensible manner.
|
/// fairly sensible manner.
|
||||||
|
///
|
||||||
|
/// Classes backed by this class can have arbitrary properties
|
||||||
|
/// created by Lua (using a backing table created by this object).
|
||||||
template <class TImpl>
|
template <class TImpl>
|
||||||
struct LuaObject {
|
struct LuaObject {
|
||||||
using CFunc = GarrysMod::Lua::CFunc;
|
using CFunc = GarrysMod::Lua::CFunc;
|
||||||
|
@ -26,12 +29,15 @@ namespace lcpu::lua {
|
||||||
/// C++ registered value read-write.
|
/// C++ registered value read-write.
|
||||||
static void RegisterSetter(const std::string& name, ILuaVoidFunc func) { setters()[name] = func; }
|
static void RegisterSetter(const std::string& name, ILuaVoidFunc func) { setters()[name] = func; }
|
||||||
|
|
||||||
|
virtual void AfterLuaInit() {};
|
||||||
|
|
||||||
/// Create an instance of this type to give to Lua.
|
/// Create an instance of this type to give to Lua.
|
||||||
/// addl. arguments are forwarded to the C++ constructor
|
/// addl. arguments are forwarded to the C++ constructor
|
||||||
template <class... Args>
|
template <class... Args>
|
||||||
static void Create(GarrysMod::Lua::ILuaBase* LUA, Args&&... args) {
|
static void Create(GarrysMod::Lua::ILuaBase* LUA, Args&&... args) {
|
||||||
auto ptr = new TImpl(static_cast<Args&&>(args)...);
|
auto ptr = new TImpl(static_cast<Args&&>(args)...);
|
||||||
ptr->InitLuaStuff(LUA);
|
ptr->InitLuaStuff(LUA);
|
||||||
|
ptr->AfterLuaInit();
|
||||||
LUA->PushUserType(ptr, __lua_typeid);
|
LUA->PushUserType(ptr, __lua_typeid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,14 +91,14 @@ namespace lcpu::lua {
|
||||||
LUA->CreateTable();
|
LUA->CreateTable();
|
||||||
tableReference = LUA->ReferenceCreate();
|
tableReference = LUA->ReferenceCreate();
|
||||||
|
|
||||||
// register some convinence things
|
// register some convinence getters
|
||||||
RegisterGetter("Name", [](GarrysMod::Lua::ILuaBase* LUA) { LUA->PushString(TImpl::Name()); });
|
RegisterGetter("Name", [](GarrysMod::Lua::ILuaBase* LUA) { LUA->PushString(TImpl::Name()); });
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetTableReference() { return tableReference; }
|
int GetTableReference() { return tableReference; }
|
||||||
|
|
||||||
LuaObject() = default;
|
LuaObject() = default;
|
||||||
~LuaObject() {
|
virtual ~LuaObject() {
|
||||||
// free the table reference
|
// free the table reference
|
||||||
if(tableReference != -1)
|
if(tableReference != -1)
|
||||||
lua->ReferenceFree(tableReference);
|
lua->ReferenceFree(tableReference);
|
||||||
|
|
|
@ -11,7 +11,7 @@ GMOD_MODULE_OPEN() {
|
||||||
lucore::Logger::The().AttachSink(lcpu::SourceSink::The());
|
lucore::Logger::The().AttachSink(lcpu::SourceSink::The());
|
||||||
lucore::LogInfo("LCPU Native Module! (ModuleVersion {})", LCPU_MODULE_VERSION);
|
lucore::LogInfo("LCPU Native Module! (ModuleVersion {})", LCPU_MODULE_VERSION);
|
||||||
|
|
||||||
GlobalsBind(LUA);
|
lcpu::GlobalsBind(LUA);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue