aboutsummaryrefslogtreecommitdiff
path: root/deep_test/deep_test.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--deep_test/deep_test.c273
-rw-r--r--deep_test/deep_test.cpp259
2 files changed, 259 insertions, 273 deletions
diff --git a/deep_test/deep_test.c b/deep_test/deep_test.c
deleted file mode 100644
index cb89741..0000000
--- a/deep_test/deep_test.c
+++ /dev/null
@@ -1,273 +0,0 @@
1#include <malloc.h>
2#include <memory.h>
3#include <assert.h>
4
5#include "lua.h"
6#include "lualib.h"
7#include "lauxlib.h"
8
9#include "lanes/src/deep.h"
10#include "lanes/src/compat.h"
11
12#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC)
13#define LANES_API __declspec(dllexport)
14#else
15#define LANES_API
16#endif // (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC)
17
18// ################################################################################################
19
20// a lanes-deep userdata. needs DeepPrelude and luaG_newdeepuserdata from Lanes code.
21struct s_MyDeepUserdata
22{
23 DeepPrelude prelude; // Deep userdata MUST start with this header
24 lua_Integer val;
25};
26static void* deep_test_id( lua_State* L, enum eDeepOp op_);
27
28// ################################################################################################
29
30static int deep_set( lua_State* L)
31{
32 struct s_MyDeepUserdata* self = luaG_todeep( L, deep_test_id, 1);
33 lua_Integer i = lua_tointeger( L, 2);
34 self->val = i;
35 return 0;
36}
37
38// ################################################################################################
39
40// won't actually do anything as deep userdata don't have uservalue slots
41static int deep_setuv( lua_State* L)
42{
43 struct s_MyDeepUserdata* self = luaG_todeep( L, deep_test_id, 1);
44 int uv = (int) luaL_optinteger( L, 2, 1);
45 lua_settop( L, 3);
46 lua_pushboolean( L, lua_setiuservalue( L, 1, uv) != 0);
47 return 1;
48}
49
50// ################################################################################################
51
52// won't actually do anything as deep userdata don't have uservalue slots
53static int deep_getuv( lua_State* L)
54{
55 struct s_MyDeepUserdata* self = luaG_todeep( L, deep_test_id, 1);
56 int uv = (int) luaL_optinteger( L, 2, 1);
57 lua_getiuservalue( L, 1, uv);
58 return 1;
59}
60
61// ################################################################################################
62
63static int deep_tostring( lua_State* L)
64{
65 struct s_MyDeepUserdata* self = luaG_todeep( L, deep_test_id, 1);
66 lua_pushfstring( L, "%p:deep(%d)", lua_topointer( L, 1), self->val);
67 return 1;
68}
69
70// ################################################################################################
71
72static int deep_gc( lua_State* L)
73{
74 struct s_MyDeepUserdata* self = luaG_todeep( L, deep_test_id, 1);
75 return 0;
76}
77
78// ################################################################################################
79
80static luaL_Reg const deep_mt[] =
81{
82 { "__tostring", deep_tostring},
83 { "__gc", deep_gc},
84 { "set", deep_set},
85 { "setuv", deep_setuv},
86 { "getuv", deep_getuv},
87 { NULL, NULL }
88};
89
90// ################################################################################################
91
92static void* deep_test_id( lua_State* L, enum eDeepOp op_)
93{
94 switch( op_)
95 {
96 case eDO_new:
97 {
98 struct s_MyDeepUserdata* deep_test = (struct s_MyDeepUserdata*) malloc( sizeof(struct s_MyDeepUserdata));
99 deep_test->prelude.magic.value = DEEP_VERSION.value;
100 deep_test->val = 0;
101 return deep_test;
102 }
103
104 case eDO_delete:
105 {
106 struct s_MyDeepUserdata* deep_test = (struct s_MyDeepUserdata*) lua_touserdata( L, 1);
107 free( deep_test);
108 return NULL;
109 }
110
111 case eDO_metatable:
112 {
113 luaL_getmetatable( L, "deep"); // mt
114 return NULL;
115 }
116
117 case eDO_module:
118 return "deep_test";
119
120 default:
121 {
122 return NULL;
123 }
124 }
125}
126
127// ################################################################################################
128
129int luaD_new_deep( lua_State* L)
130{
131 int nuv = (int) luaL_optinteger( L, 1, 0);
132 // no additional parameter to luaG_newdeepuserdata!
133 lua_settop( L, 0);
134 return luaG_newdeepuserdata( L, deep_test_id, nuv);
135}
136
137// ################################################################################################
138// ################################################################################################
139
140struct s_MyClonableUserdata
141{
142 lua_Integer val;
143};
144
145// ################################################################################################
146
147static int clonable_set( lua_State* L)
148{
149 struct s_MyClonableUserdata* self = (struct s_MyClonableUserdata*) lua_touserdata( L, 1);
150 lua_Integer i = lua_tointeger( L, 2);
151 self->val = i;
152 return 0;
153}
154
155// ################################################################################################
156
157static int clonable_setuv( lua_State* L)
158{
159 struct s_MyClonableUserdata* self = (struct s_MyClonableUserdata*) lua_touserdata( L, 1);
160 int uv = (int) luaL_optinteger( L, 2, 1);
161 lua_settop( L, 3);
162 lua_pushboolean( L, lua_setiuservalue( L, 1, uv) != 0);
163 return 1;
164}
165
166// ################################################################################################
167
168static int clonable_getuv( lua_State* L)
169{
170 struct s_MyClonableUserdata* self = (struct s_MyClonableUserdata*) lua_touserdata( L, 1);
171 int uv = (int) luaL_optinteger( L, 2, 1);
172 lua_getiuservalue( L, 1, uv);
173 return 1;
174}
175
176// ################################################################################################
177
178static int clonable_tostring(lua_State* L)
179{
180 struct s_MyClonableUserdata* self = (struct s_MyClonableUserdata*) lua_touserdata( L, 1);
181 lua_pushfstring( L, "%p:clonable(%d)", lua_topointer( L, 1), self->val);
182 return 1;
183}
184
185// ################################################################################################
186
187static int clonable_gc( lua_State* L)
188{
189 struct s_MyClonableUserdata* self = (struct s_MyClonableUserdata*) lua_touserdata( L, 1);
190 return 0;
191}
192
193// ################################################################################################
194
195// this is all we need to make a userdata lanes-clonable. no dependency on Lanes code.
196static int clonable_lanesclone( lua_State* L)
197{
198 switch( lua_gettop( L))
199 {
200 case 3:
201 {
202 struct s_MyClonableUserdata* self = lua_touserdata( L, 1);
203 struct s_MyClonableUserdata* from = lua_touserdata( L, 2);
204 size_t len = lua_tointeger( L, 3);
205 assert( len == sizeof(struct s_MyClonableUserdata));
206 *self = *from;
207 }
208 return 0;
209
210 default:
211 (void) luaL_error( L, "Lanes called clonable_lanesclone with unexpected parameters");
212 }
213 return 0;
214}
215
216// ################################################################################################
217
218static luaL_Reg const clonable_mt[] =
219{
220 { "__tostring", clonable_tostring},
221 { "__gc", clonable_gc},
222 { "__lanesclone", clonable_lanesclone},
223 { "set", clonable_set},
224 { "setuv", clonable_setuv},
225 { "getuv", clonable_getuv},
226 { NULL, NULL }
227};
228
229// ################################################################################################
230
231int luaD_new_clonable( lua_State* L)
232{
233 int nuv = (int) luaL_optinteger( L, 1, 1);
234 lua_newuserdatauv( L, sizeof( struct s_MyClonableUserdata), nuv);
235 luaL_setmetatable( L, "clonable");
236 return 1;
237}
238
239// ################################################################################################
240// ################################################################################################
241
242static luaL_Reg const deep_module[] =
243{
244 { "new_deep", luaD_new_deep},
245 { "new_clonable", luaD_new_clonable},
246 { NULL, NULL}
247};
248
249// ################################################################################################
250
251extern int __declspec(dllexport) luaopen_deep_test(lua_State* L)
252{
253 luaL_newlib( L, deep_module); // M
254
255 // preregister the metatables for the types we can instantiate so that Lanes can know about them
256 if( luaL_newmetatable( L, "clonable")) // M mt
257 {
258 luaL_setfuncs( L, clonable_mt, 0);
259 lua_pushvalue(L, -1); // M mt mt
260 lua_setfield(L, -2, "__index"); // M mt
261 }
262 lua_setfield(L, -2, "__clonableMT"); // M
263
264 if( luaL_newmetatable( L, "deep")) // mt
265 {
266 luaL_setfuncs( L, deep_mt, 0);
267 lua_pushvalue(L, -1); // mt mt
268 lua_setfield(L, -2, "__index"); // mt
269 }
270 lua_setfield(L, -2, "__deepMT"); // M
271
272 return 1;
273}
diff --git a/deep_test/deep_test.cpp b/deep_test/deep_test.cpp
new file mode 100644
index 0000000..3467939
--- /dev/null
+++ b/deep_test/deep_test.cpp
@@ -0,0 +1,259 @@
1#include "lanes/src/deep.h"
2#include "lanes/src/compat.h"
3
4#include <malloc.h>
5#include <memory.h>
6#include <assert.h>
7
8// ################################################################################################
9
10// a lanes-deep userdata. needs DeepPrelude and luaG_newdeepuserdata from Lanes code.
11struct MyDeepUserdata : public DeepPrelude // Deep userdata MUST start with a DeepPrelude
12{
13 lua_Integer val{ 0 };
14};
15
16// ################################################################################################
17
18[[nodiscard]] static void* deep_test_id(lua_State* L, DeepOp op_)
19{
20 switch( op_)
21 {
22 case DeepOp::New:
23 {
24 MyDeepUserdata* deep_test = new MyDeepUserdata;
25 return deep_test;
26 }
27
28 case DeepOp::Delete:
29 {
30 MyDeepUserdata* deep_test = static_cast<MyDeepUserdata*>(lua_touserdata( L, 1));
31 delete deep_test;
32 return nullptr;
33 }
34
35 case DeepOp::Metatable:
36 {
37 luaL_getmetatable( L, "deep"); // mt
38 return nullptr;
39 }
40
41 case DeepOp::Module:
42 return (void*)"deep_test";
43
44 default:
45 {
46 return nullptr;
47 }
48 }
49}
50
51// ################################################################################################
52
53[[nodiscard]] static int deep_set(lua_State* L)
54{
55 MyDeepUserdata* self = static_cast<MyDeepUserdata*>(luaG_todeep(L, deep_test_id, 1));
56 lua_Integer i = lua_tointeger( L, 2);
57 self->val = i;
58 return 0;
59}
60
61// ################################################################################################
62
63// won't actually do anything as deep userdata don't have uservalue slots
64[[nodiscard]] static int deep_setuv(lua_State* L)
65{
66 MyDeepUserdata* self = static_cast<MyDeepUserdata*>(luaG_todeep(L, deep_test_id, 1));
67 int uv = (int) luaL_optinteger(L, 2, 1);
68 lua_settop( L, 3);
69 lua_pushboolean( L, lua_setiuservalue( L, 1, uv) != 0);
70 return 1;
71}
72
73// ################################################################################################
74
75// won't actually do anything as deep userdata don't have uservalue slots
76[[nodiscard]] static int deep_getuv(lua_State* L)
77{
78 MyDeepUserdata* self = static_cast<MyDeepUserdata*>(luaG_todeep(L, deep_test_id, 1));
79 int uv = (int) luaL_optinteger(L, 2, 1);
80 lua_getiuservalue( L, 1, uv);
81 return 1;
82}
83
84// ################################################################################################
85
86[[nodiscard]] static int deep_tostring(lua_State* L)
87{
88 MyDeepUserdata* self = static_cast<MyDeepUserdata*>(luaG_todeep(L, deep_test_id, 1));
89 lua_pushfstring(L, "%p:deep(%d)", lua_topointer(L, 1), self->val);
90 return 1;
91}
92
93// ################################################################################################
94
95[[nodiscard]] static int deep_gc(lua_State* L)
96{
97 MyDeepUserdata* self = static_cast<MyDeepUserdata*>(luaG_todeep(L, deep_test_id, 1));
98 return 0;
99}
100
101// ################################################################################################
102
103static luaL_Reg const deep_mt[] =
104{
105 { "__tostring", deep_tostring},
106 { "__gc", deep_gc},
107 { "set", deep_set},
108 { "setuv", deep_setuv},
109 { "getuv", deep_getuv},
110 { nullptr, nullptr }
111};
112
113// ################################################################################################
114
115int luaD_new_deep( lua_State* L)
116{
117 int const nuv{ static_cast<int>(luaL_optinteger(L, 1, 0)) };
118 // no additional parameter to luaG_newdeepuserdata!
119 lua_settop(L, 0);
120 return luaG_newdeepuserdata(Dest{ L }, deep_test_id, nuv);
121}
122
123// ################################################################################################
124// ################################################################################################
125
126struct MyClonableUserdata
127{
128 lua_Integer val;
129};
130
131// ################################################################################################
132
133[[nodiscard]] static int clonable_set(lua_State* L)
134{
135 MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1));
136 lua_Integer i = lua_tointeger(L, 2);
137 self->val = i;
138 return 0;
139}
140
141// ################################################################################################
142
143[[nodiscard]] static int clonable_setuv(lua_State* L)
144{
145 MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1));
146 int uv = (int) luaL_optinteger(L, 2, 1);
147 lua_settop( L, 3);
148 lua_pushboolean( L, lua_setiuservalue( L, 1, uv) != 0);
149 return 1;
150}
151
152// ################################################################################################
153
154[[nodiscard]] static int clonable_getuv(lua_State* L)
155{
156 MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1));
157 int uv = (int) luaL_optinteger(L, 2, 1);
158 lua_getiuservalue( L, 1, uv);
159 return 1;
160}
161
162// ################################################################################################
163
164[[nodiscard]] static int clonable_tostring(lua_State* L)
165{
166 MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1));
167 lua_pushfstring(L, "%p:clonable(%d)", lua_topointer(L, 1), self->val);
168 return 1;
169}
170
171// ################################################################################################
172
173[[nodiscard]] static int clonable_gc(lua_State* L)
174{
175 MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1));
176 return 0;
177}
178
179// ################################################################################################
180
181// this is all we need to make a userdata lanes-clonable. no dependency on Lanes code.
182[[nodiscard]] static int clonable_lanesclone(lua_State* L)
183{
184 switch( lua_gettop( L))
185 {
186 case 3:
187 {
188 MyClonableUserdata* self = static_cast<MyClonableUserdata*>(lua_touserdata(L, 1));
189 MyClonableUserdata* from = static_cast<MyClonableUserdata*>(lua_touserdata(L, 2));
190 size_t len = lua_tointeger( L, 3);
191 assert( len == sizeof(MyClonableUserdata));
192 *self = *from;
193 }
194 return 0;
195
196 default:
197 (void) luaL_error( L, "Lanes called clonable_lanesclone with unexpected parameters");
198 }
199 return 0;
200}
201
202// ################################################################################################
203
204static luaL_Reg const clonable_mt[] =
205{
206 { "__tostring", clonable_tostring},
207 { "__gc", clonable_gc},
208 { "__lanesclone", clonable_lanesclone},
209 { "set", clonable_set},
210 { "setuv", clonable_setuv},
211 { "getuv", clonable_getuv},
212 { nullptr, nullptr }
213};
214
215// ################################################################################################
216
217int luaD_new_clonable( lua_State* L)
218{
219 int const nuv{ static_cast<int>(luaL_optinteger(L, 1, 1)) };
220 lua_newuserdatauv( L, sizeof(MyClonableUserdata), nuv);
221 luaL_setmetatable( L, "clonable");
222 return 1;
223}
224
225// ################################################################################################
226// ################################################################################################
227
228static luaL_Reg const deep_module[] =
229{
230 { "new_deep", luaD_new_deep},
231 { "new_clonable", luaD_new_clonable},
232 { nullptr, nullptr }
233};
234
235// ################################################################################################
236
237LANES_API int luaopen_deep_test(lua_State* L)
238{
239 luaL_newlib( L, deep_module); // M
240
241 // preregister the metatables for the types we can instantiate so that Lanes can know about them
242 if( luaL_newmetatable( L, "clonable")) // M mt
243 {
244 luaL_setfuncs( L, clonable_mt, 0);
245 lua_pushvalue(L, -1); // M mt mt
246 lua_setfield(L, -2, "__index"); // M mt
247 }
248 lua_setfield(L, -2, "__clonableMT"); // M
249
250 if( luaL_newmetatable( L, "deep")) // mt
251 {
252 luaL_setfuncs( L, deep_mt, 0);
253 lua_pushvalue(L, -1); // mt mt
254 lua_setfield(L, -2, "__index"); // mt
255 }
256 lua_setfield(L, -2, "__deepMT"); // M
257
258 return 1;
259}