Skip to content

Commit 3a46590

Browse files
committed
feat(cffi/meta): meta model try out
1 parent 9589d70 commit 3a46590

1 file changed

Lines changed: 94 additions & 0 deletions

File tree

tests/test-cffi-lua-meta.lua

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
rps = require("RPS")
2+
3+
StructObjectMetaTable = {
4+
-- retrieve all the fields and values of this struct
5+
__pairs = function(tt)
6+
print("StructObjectMetaTable: __pairs", tt)
7+
local itF, itT, itK, itV = ipairs(tt[".meta"].fieldArray)
8+
return function(t, k)
9+
-- t and k are ignored because we provide pairs return values on an ipairs call
10+
itK, itV = itF(itT, itK)
11+
return itV, tt[itV]
12+
end, tt, nil
13+
end,
14+
__index = function(tt, k)
15+
print("StructObjectMetaTable: __index", tt, k)
16+
17+
local field = tt[".meta"].fields[k]
18+
return field:read(tt['.address'])
19+
end,
20+
__newindex = function(tt, k, v)
21+
print("StructObjectMetaTable: __newindex", tt, k,v)
22+
23+
local field = tt[".meta"].fields[k]
24+
field:write(tt['.address'], v)
25+
end,
26+
__gc = function(tt)
27+
if tt['.managed'] == true then
28+
print("__gc: deallocating")
29+
rps.deallocate(tt['.address'])
30+
return
31+
end
32+
print("__gc: not a managed object")
33+
end,
34+
}
35+
36+
IntField = {
37+
read = function(t, address)
38+
-- TODO: where to set the offset? Optimize so the number of fields is low and can be reused dynamically?
39+
-- metatable this stuff? Should the field know about its embedder, or be agnostic?
40+
local addr = address + t.offset
41+
print("int:read: at: ", addr)
42+
return rps.readInteger(addr)
43+
end,
44+
write = function(t, address, v)
45+
local addr = address + t.offset
46+
print("int:write: at: ", addr, v)
47+
rps.writeInteger(addr, v)
48+
end,
49+
}
50+
51+
function generateFieldInstance(field, offset)
52+
return setmetatable({
53+
offset = offset,
54+
}, {
55+
__index = field,
56+
})
57+
end
58+
59+
ExampleStruct = {
60+
size = 4,
61+
fields = {
62+
field1 = generateFieldInstance(IntField, 0),
63+
-- field1 = {
64+
-- read = function(f, t, offset)
65+
-- -- TODO: where to set the offset? Optimize so the number of fields is low and can be reused dynamically?
66+
-- -- metatable this stuff? Should the field know about its embedder, or be agnostic?
67+
-- local addr = t['.address'] + offset
68+
-- print("int:read: at: ", addr)
69+
-- return rps.readInteger(addr)
70+
-- end,
71+
-- write = function(f, t, offset, v)
72+
-- local addr = t['.address'] + offset
73+
-- print("int:write: at: ", addr, v)
74+
-- rps.writeInteger(addr, v)
75+
-- end,
76+
-- },
77+
},
78+
fieldArray = {"field1", }
79+
}
80+
81+
function generateStruct(t)
82+
return setmetatable({
83+
['.meta'] = t,
84+
['.address'] = rps.allocate(t.size, true),
85+
['.managed'] = true,
86+
}, StructObjectMetaTable)
87+
end
88+
89+
function generateStructExample()
90+
return generateStruct(ExampleStruct)
91+
end
92+
93+
s = generateStructExample()
94+

0 commit comments

Comments
 (0)