1
/* tolua: functions to map features
2
** Support code for Lua bindings.
3
** Written by Waldemar Celes
6
** $Id: tolua_map.c 14589 2008-04-15 21:40:53Z cazfi $
9
/* This code is free software; you can redistribute it and/or modify it.
10
** The software provided hereunder is on an "as is" basis, and
11
** the author has no obligation to provide maintenance, support, updates,
12
** enhancements, or modifications.
16
#include "tolua_event.h"
25
static lua_State* __tolua_current_state_=NULL;
27
/* Call method to self object from C
30
TOLUA_API int tolua_callmethod(lua_State* L,void* self,const char* type,const char* func,int nargs,int nresults){
31
tolua_pushusertype(L,self,type);
32
lua_pushstring(L,func);
34
if(!lua_isfunction(L,-1)){lua_pop(L,1);return 0;} * method is nil *
35
lua_insert(L,-2-nargs);
36
lua_insert(L,-1-nargs);
37
lua_call(L,nargs+1,nresults);
41
TOLUA_API lua_State* tolua_state(){ /* Get current state */
42
return __tolua_current_state_;
44
TOLUA_API void tolua_setstate(lua_State* L){ /* Set current state */
45
__tolua_current_state_=L;
49
* Create and register new metatable
51
static int tolua_newmetatable (lua_State* L, char* name){
52
int r = luaL_newmetatable(L,name);
54
#ifdef LUA_VERSION_NUM /* only lua 5.1 */
57
lua_pushstring(L, name);
58
lua_settable(L, LUA_REGISTRYINDEX); /* reg[mt] = type_name */
62
if (r) tolua_classevents(L); /* set meta events */
68
* It sets 'name' as being also a 'base', mapping all super classes of 'base' in 'name'
70
static void mapsuper (lua_State* L, const char* name, const char* base) {
71
/* push registry.super */
72
lua_pushstring(L,"tolua_super");
73
lua_rawget(L,LUA_REGISTRYINDEX); /* stack: super */
74
luaL_getmetatable(L,name); /* stack: super mt */
75
lua_rawget(L,-2); /* stack: super table */
76
if (lua_isnil(L,-1)) {
79
lua_newtable(L); /* stack: super table */
80
luaL_getmetatable(L,name); /* stack: super table mt */
81
lua_pushvalue(L,-2); /* stack: super table mt table */
82
lua_rawset(L,-4); /* stack: super table */
85
/* set base as super class */
86
lua_pushstring(L,base);
88
lua_rawset(L,-3); /* stack: super table */
90
/* set all super class of base as super class of name */
91
luaL_getmetatable(L,base); /* stack: super table base_mt */
92
lua_rawget(L,-3); /* stack: super table base_table */
93
if (lua_istable(L,-1)) {
94
/* traverse base table */
95
lua_pushnil(L); /* first key */
96
while (lua_next(L,-2) != 0) {
97
/* stack: ... base_table key value */
98
lua_pushvalue(L,-2); /* stack: ... base_table key value key */
99
lua_insert(L,-2); /* stack: ... base_table key key value */
100
lua_rawset(L,-5); /* stack: ... base_table key */
103
lua_pop(L,3); /* stack: <empty> */
106
/* creates a 'tolua_ubox' table for base clases, and
107
// expects the metatable and base metatable on the stack */
108
static void set_ubox(lua_State* L) {
110
if (!lua_isnil(L, -1)) {
111
lua_pushstring(L, "tolua_ubox");
116
/* mt basemt base_ubox */
117
if (!lua_isnil(L,-1)) {
118
lua_pushstring(L, "tolua_ubox");
120
/* mt basemt key ubox */
122
/* (mt with ubox) basemt */
126
lua_pushstring(L,"tolua_ubox"); lua_newtable(L);
127
/* make weak value metatable for ubox table to allow userdata to be
129
lua_newtable(L); lua_pushliteral(L, "__mode"); lua_pushliteral(L, "v"); lua_rawset(L, -3); /* stack: string ubox mt */
130
lua_setmetatable(L, -2); /* stack:mt basemt string ubox */
136
* It sets 'name' as derived from 'base' by setting 'base' as metatable of 'name'
138
static void mapinheritance (lua_State* L, const char* name, const char* base){
139
/* set metatable inheritance */
140
luaL_getmetatable(L,name);
142
if (base && *base) luaL_getmetatable(L,base); else {
144
if (lua_getmetatable(L, -1)) { /* already has a mt, we don't overwrite it */
148
luaL_getmetatable(L,"tolua_commonclass");
153
lua_setmetatable(L,-2);
159
static int tolua_bnd_type (lua_State* L){
160
tolua_typename(L,lua_gettop(L));
166
static int tolua_bnd_takeownership (lua_State* L){
168
if (lua_isuserdata(L,1)) {
169
if (lua_getmetatable(L,1)) { /* if metatable? */
170
lua_pop(L,1); /* clear metatable off stack */
171
/* force garbage collection to avoid C to reuse a to-be-collected address */
172
#ifdef LUA_VERSION_NUM
173
lua_gc(L, LUA_GCCOLLECT, 0);
175
lua_setgcthreshold(L,0);
177
success = tolua_register_gc(L,1);
180
lua_pushboolean(L,success!=0);
186
static int tolua_bnd_releaseownership (lua_State* L){
188
if (lua_isuserdata(L,1)) {
189
void* u = *((void**)lua_touserdata(L,1));
190
/* force garbage collection to avoid releasing a to-be-collected address */
191
#ifdef LUA_VERSION_NUM
192
lua_gc(L, LUA_GCCOLLECT, 0);
194
lua_setgcthreshold(L,0);
196
lua_pushstring(L,"tolua_gc");
197
lua_rawget(L,LUA_REGISTRYINDEX);
198
lua_pushlightuserdata(L,u);
200
lua_getmetatable(L,1);
201
if (lua_rawequal(L,-1,-2)) { /* check that we are releasing the correct type */
202
lua_pushlightuserdata(L,u);
208
lua_pushboolean(L,done!=0);
214
static int tolua_bnd_cast (lua_State* L){
217
void* v = tolua_tousertype(L,1,NULL);
218
const char* s = tolua_tostring(L,2,NULL);
220
tolua_pushusertype(L,v,s);
228
if (lua_islightuserdata(L, 1)) {
229
v = tolua_touserdata(L, 1, NULL);
231
v = tolua_tousertype(L, 1, 0);
234
s = tolua_tostring(L,2,NULL);
235
if (v && s) tolua_pushusertype(L,v,s);
242
static int tolua_bnd_inherit (lua_State* L) {
244
/* stack: lua object, c object */
245
lua_pushstring(L, ".c_instance");
246
lua_pushvalue(L, -2);
248
/* l_obj[".c_instance"] = c_obj */
253
#ifdef LUA_VERSION_NUM /* lua 5.1 */
254
static int tolua_bnd_setpeer(lua_State* L) {
255
/* stack: userdata, table */
256
if (!lua_isuserdata(L, -2)) {
257
lua_pushstring(L, "Invalid argument #1 to setpeer: userdata expected.");
261
if (lua_isnil(L, -1)) {
263
lua_pushvalue(L, TOLUA_NOPEER);
270
static int tolua_bnd_getpeer(lua_State* L) {
271
/* stack: userdata */
273
if (lua_rawequal(L, -1, TOLUA_NOPEER)) {
282
* toluaxx proxy technique
287
TOLUA_API void tolua_proxystack(lua_State* L){
289
lua_pushstring(L,"tolua_proxy"); /* stack: "tolua_proxy" */
290
lua_rawget(L,LUA_REGISTRYINDEX); /* stack: ?proxy_stack_table? */
291
if(!lua_istable(L,-1)){ /* check if ?proxy_stack_table? is not table */
292
lua_remove(L,-1); /* stack: */
293
lua_pushnil(L); /* stack: nil */
296
/* stack: proxy_stack_table */
299
TOLUA_API int tolua_proxytop(lua_State* L){
300
int __tolua_proxy_top_;
302
__top_=lua_gettop(L); /* stack: */
303
lua_pushstring(L,"tolua_proxy"); /* stack: "tolua_proxy" */
304
lua_rawget(L,LUA_REGISTRYINDEX); /* stack: ?proxy_stack_table? */
305
if(lua_istable(L,-1)){ /* check if ?proxy_stack_table? is table */
306
lua_pushnumber(L,0); /* stack: proxy_stack_table 0 */
307
lua_rawget(L,-2); /* stack: proxy_stack_table ?proxy_stack_top? */
308
if(lua_isnumber(L,-1)){ /* check if ?proxy_stack_top? is number */
309
__tolua_proxy_top_=lua_tonumber(L,-1);
310
}else __tolua_proxy_top_=-2;
311
}else __tolua_proxy_top_=-1;
312
lua_settop(L,__top_);
313
return __tolua_proxy_top_;
316
TOLUA_API int tolua_proxypush(lua_State* L){
317
int __tolua_proxy_top_;
319
/* get proxy stack table */ /* stack: */
320
lua_pushstring(L,"tolua_proxy"); /* stack: "tolua_proxy" */
321
lua_rawget(L,LUA_REGISTRYINDEX); /* stack: ?proxy_stack_table? */
322
if(!lua_istable(L,-1)){ /* check if ?proxy_stack_table? is not table */
323
lua_remove(L,-1); /* stack: */
327
/* get stack level top counter */ /* stack: proxy_stack_table */
328
lua_pushnumber(L,0); /* stack: proxy_stack_table 0 */
329
lua_rawget(L,-2); /* stack: proxy_stack_table ?proxy_stack_top? */
330
if(!lua_isnumber(L,-1)){ /* check if ?proxy_stack_top? is not number */
331
lua_remove(L,-1); /* stack: proxy_stack_table */
332
lua_remove(L,-1); /* stack: */
335
__tolua_proxy_top_=lua_tonumber(L,-1);
336
lua_remove(L,-1); /* stack: proxy_stack_table */
338
/* decrement stack level top counter */
339
__tolua_proxy_top_=__tolua_proxy_top_+1;
340
lua_pushnumber(L,0); /* stack: proxy_stack_table 0 */
341
lua_pushnumber(L,__tolua_proxy_top_); /* stack: proxy_stack_table 0 new_proxy_stack_top */
342
lua_rawset(L,-3); /* stack: proxy_stack_table */
344
/* create a new proxy stack level */
345
lua_pushnumber(L,__tolua_proxy_top_); /* stack: proxy_stack_table new_proxy_stack_top */
346
lua_newtable(L); /* stack: proxy_stack_table new_proxy_stack_level */
347
lua_rawset(L,-3); /* stack: proxy_stack_table */
349
/* clear lua stack */
350
lua_remove(L,-1); /* stack: */
354
TOLUA_API int tolua_proxypop(lua_State* L){
355
int __tolua_proxy_top_;
357
/* get proxy stack table */ /* stack: */
358
lua_pushstring(L,"tolua_proxy"); /* stack: "tolua_proxy" */
359
lua_rawget(L,LUA_REGISTRYINDEX); /* stack: ?proxy_stack_table? */
360
if(!lua_istable(L,-1)){ /* check if ?proxy_stack_table? is not table */
361
lua_remove(L,-1); /* stack: */
365
/* get stack level top counter */ /* stack: proxy_stack_table */
366
lua_pushnumber(L,0); /* stack: proxy_stack_table 0 */
367
lua_rawget(L,-2); /* stack: proxy_stack_table ?proxy_stack_top? */
368
if(!lua_isnumber(L,-1)){ /* check if ?proxy_stack_top? is not number */
369
lua_remove(L,-1); /* stack: proxy_stack_table */
370
lua_remove(L,-1); /* stack: */
373
__tolua_proxy_top_=lua_tonumber(L,-1);
374
lua_remove(L,-1); /* stack: proxy_stack_table */
375
if(__tolua_proxy_top_<1){ /* check if proxy top counter is smaller one */
376
lua_remove(L,-1); /* stack: */
379
/* remove proxy stack level */
380
lua_pushnumber(L,__tolua_proxy_top_); /* stack: proxy_stack_table proxy_stack_top */
381
lua_pushnil(L); /* stack: proxy_stack_table */
382
lua_rawset(L,-3); /* stack: proxy_stack_table */
384
/* decrement stack level top counter */
385
__tolua_proxy_top_=__tolua_proxy_top_-1;
386
lua_pushnumber(L,0); /* stack: proxy_stack_table 0 */
387
lua_pushnumber(L,__tolua_proxy_top_); /* stack: proxy_stack_table 0 new_proxy_stack_top */
388
lua_rawset(L,-3); /* stack: proxy_stack_table */
390
/* clear lua stack */
391
lua_remove(L,-1); /* stack: */
395
TOLUA_API void tolua_proxylevel(lua_State* L, int level){
397
int __tolua_proxy_top_=tolua_proxytop(L);
398
if( level>+__tolua_proxy_top_ ||
399
level<-__tolua_proxy_top_ ||
400
level==0 ){ /* check if level exceded */
401
lua_pushnil(L); /* stack: nil */
404
lua_pushstring(L,"tolua_proxy"); /* stack: "tolua_proxy" */
405
lua_rawget(L,LUA_REGISTRYINDEX); /* stack: ?proxy_stack_table? */
406
if(!lua_istable(L,-1)){ /* check if ?proxy_stack_table? is not table */
407
lua_remove(L,-1); /* stack: */
408
lua_pushnil(L); /* stack: nil */
411
/* stack: proxy_stack_table */
412
level=level>0?level:__tolua_proxy_top_+level+1;
413
lua_pushnumber(L,level); /* stack: proxy_stack_table proxy_stack_level */
414
lua_rawget(L,-2); /* stack: proxy_stack_table ?proxy_level_table? */
415
lua_remove(L,-2); /* stack: ?proxy_level_table? */
416
if(!lua_istable(L,-1)){ /* check if ?proxy_level_table? is not table */
417
lua_remove(L,-1); /* stack: */
418
lua_pushnil(L); /* stack: nil */
421
return; /* stack: proxy_level_table */
424
TOLUA_API void tolua_getproxy(lua_State* L, int level){
426
tolua_proxylevel(L,level); /* stack: key ?proxy_level_table? */
427
if(!lua_istable(L,-1)){ /* check if ?proxy_level_table? is not table */
428
lua_remove(L,-1); /* stack: key */
429
lua_remove(L,-1); /* stack: */
430
lua_pushnil(L); /* stack: nil */
432
} /* stack: key proxy_level_table */
433
lua_insert(L,-2); /* stack: proxy_level_table key */
434
lua_rawget(L,-2); /* stack: proxy_level_table value */
435
lua_remove(L,-2); /* stack: value */
439
TOLUA_API void tolua_setproxy(lua_State* L, int level){
441
tolua_proxylevel(L,level); /* stack: key val ?proxy_level_table? */
442
if(!lua_istable(L,-1)){ /* check if ?proxy_level_table? is not table */
443
lua_remove(L,-1); /* stack: key val */
444
lua_remove(L,-1); /* stack: key */
445
lua_remove(L,-1); /* stack: */
447
} /* stack: key val proxy_level_table */
448
lua_insert(L,-3); /* stack: proxy_level_table key val */
449
lua_rawset(L,-3); /* stack: proxy_level_table */
450
lua_remove(L,-2); /* stack: */
454
/* local state = tolua.proxy.push() */
455
static int tolua_bnd_proxy_push(lua_State* L){
457
__ret_code_=tolua_proxypush(L);
458
lua_pushboolean(L,__ret_code_);
462
/* local state = tolua.proxy.pop() */
463
static int tolua_bnd_proxy_pop(lua_State* L){
465
__ret_code_=tolua_proxypop(L);
466
lua_pushboolean(L,__ret_code_);
470
/* local level_table = tolua.proxy.level(<level>) */
471
static int tolua_bnd_proxy_level(lua_State* L){
473
int __proxy_level_=TOLUA_PROXY_TOP;
474
if(lua_isnumber(L,1)){ /* check if level has been retrieved */
476
__proxy_level_=lua_tonumber(L,1);
477
lua_remove(L,1); /* stack: */
479
tolua_proxylevel(L,__proxy_level_);
483
/* local val = tolua.proxy.get(key<,level>) */
484
static int tolua_bnd_proxy_get(lua_State* L){
485
/* stack: key <level> */
486
int __proxy_level_=TOLUA_PROXY_TOP;
487
if(lua_gettop(L)<1 || lua_isnil(L,1)){ /* check if key hasn't been retrieved */
491
if(lua_isnumber(L,2)){ /* check if level has been retrieved */
492
/* stack: key level */
493
__proxy_level_=lua_tonumber(L,2);
494
lua_remove(L,2); /* stack: key */
496
tolua_getproxy(L,__proxy_level_); /* stack: val */
500
/* tolua.proxy.set(key,value<,level>) */
501
static int tolua_bnd_proxy_set(lua_State* L){
502
/* stack: key val <level> */
503
int __proxy_level_=TOLUA_PROXY_TOP;
504
if(lua_gettop(L)<1 || lua_isnil(L,1)){ /* check if key hasn't been retrieved */
507
if(lua_gettop(L)<2){ /* check if val hasn't been retrieved */
510
if(lua_isnumber(L,3)){ /* check if level has been retrieved */
511
/* stack: key val level */
512
__proxy_level_=lua_tonumber(L,3);
513
lua_remove(L,3); /* stack: key val */
514
} /* stack: key val */
515
tolua_setproxy(L,__proxy_level_); /* stack: */
519
/* local top = tolua.proxy.top() */
520
static int tolua_bnd_proxy_top(lua_State* L){
521
int __top_=tolua_proxytop(L);
522
lua_pushnumber(L,__top_);
526
/* static int class_gc_event (lua_State* L); */
528
TOLUA_API void tolua_open (lua_State* L){
529
int top = lua_gettop(L);
530
lua_pushstring(L,"tolua_opened");
531
lua_rawget(L,LUA_REGISTRYINDEX);
532
if (!lua_isboolean(L,-1)){
533
lua_pushstring(L,"tolua_opened"); lua_pushboolean(L,1); lua_rawset(L,LUA_REGISTRYINDEX);
535
#ifndef LUA_VERSION_NUM /* only prior to lua 5.1 */
536
/* create peer object table */
537
lua_pushstring(L, "tolua_peers"); lua_newtable(L);
538
/* make weak key metatable for peers indexed by userdata object */
539
lua_newtable(L); lua_pushliteral(L, "__mode"); lua_pushliteral(L, "k"); lua_rawset(L, -3); /* stack: string peers mt */
540
lua_setmetatable(L, -2); /* stack: string peers */
541
lua_rawset(L,LUA_REGISTRYINDEX);
544
/* create object ptr -> udata mapping table */
545
lua_pushstring(L,"tolua_ubox"); lua_newtable(L);
546
/* make weak value metatable for ubox table to allow userdata to be
548
lua_newtable(L); lua_pushliteral(L, "__mode"); lua_pushliteral(L, "v"); lua_rawset(L, -3);
549
/* stack: string ubox mt */
550
lua_setmetatable(L, -2); /* stack: string ubox */
551
lua_rawset(L,LUA_REGISTRYINDEX);
553
lua_pushstring(L,"tolua_super"); lua_newtable(L); lua_rawset(L,LUA_REGISTRYINDEX);
554
lua_pushstring(L,"tolua_gc"); lua_newtable(L); lua_rawset(L,LUA_REGISTRYINDEX);
555
lua_pushstring(L,"tolua_node"); lua_newtable(L); lua_rawset(L,LUA_REGISTRYINDEX);
557
/* create proxy table */
558
lua_pushstring(L,"tolua_proxy");
560
/* insert counter into proxy table */
564
/* register proxy table */
565
lua_rawset(L,LUA_REGISTRYINDEX);
567
/* create gc_event closure */
568
lua_pushstring(L, "tolua_gc_event");
569
lua_pushstring(L, "tolua_gc");
570
lua_rawget(L, LUA_REGISTRYINDEX);
571
lua_pushstring(L, "tolua_super");
572
lua_rawget(L, LUA_REGISTRYINDEX);
573
lua_pushcclosure(L, class_gc_event, 2);
574
lua_rawset(L, LUA_REGISTRYINDEX);
576
tolua_newmetatable(L,"tolua_commonclass");
578
tolua_module(L,NULL,0);
579
tolua_beginmodule(L,NULL);
580
tolua_module(L,"tolua",0);
581
tolua_beginmodule(L,"tolua");
582
tolua_function(L,"type",tolua_bnd_type);
583
tolua_function(L,"takeownership",tolua_bnd_takeownership);
584
tolua_function(L,"releaseownership",tolua_bnd_releaseownership);
585
tolua_function(L,"cast",tolua_bnd_cast);
586
tolua_function(L,"inherit", tolua_bnd_inherit);
587
#ifdef LUA_VERSION_NUM /* lua 5.1 */
588
tolua_function(L,"setpeer", tolua_bnd_setpeer);
589
tolua_function(L,"getpeer", tolua_bnd_getpeer);
592
tolua_module(L,"proxy",0);
593
tolua_beginmodule(L,"proxy");
594
tolua_function(L,"top", tolua_bnd_proxy_top);
595
tolua_function(L,"push", tolua_bnd_proxy_push);
596
tolua_function(L,"pop", tolua_bnd_proxy_pop);
597
tolua_function(L,"set", tolua_bnd_proxy_set);
598
tolua_function(L,"get", tolua_bnd_proxy_get);
599
tolua_function(L,"level",tolua_bnd_proxy_level);
611
TOLUA_API void* tolua_copy (lua_State* L, void* value, unsigned int size){
612
void* clone = (void*)malloc(size);
613
if (clone) memcpy(clone,value,size);
614
else tolua_error(L,"insuficient memory",NULL);
618
/* Default collect function
620
TOLUA_API int tolua_default_collect (lua_State* tolua_S){
621
void* self = tolua_tousertype(tolua_S,1,0);
628
TOLUA_API int tolua_register_gc (lua_State* L, int lo){
630
void *value = *(void **)lua_touserdata(L,lo);
631
lua_pushstring(L,"tolua_gc");
632
lua_rawget(L,LUA_REGISTRYINDEX);
633
lua_pushlightuserdata(L,value);
635
if (!lua_isnil(L,-1)){ /* make sure that object is not already owned */
638
lua_pushlightuserdata(L,value);
639
lua_getmetatable(L,lo);
646
/* Register a usertype
647
* It creates the correspoding metatable in the registry, for both 'type' and 'const type'.
648
* It maps 'const type' as being also a 'type'
650
TOLUA_API void tolua_usertype (lua_State* L, char* type)
652
char ctype[128] = "const ";
653
strncat(ctype,type,120);
655
/* create both metatables */
656
if (tolua_newmetatable(L,ctype) && tolua_newmetatable(L,type))
657
mapsuper(L,type,ctype); /* 'type' is also a 'const type' */
662
* It pushes the module (or class) table on the stack
664
TOLUA_API void tolua_beginmodule (lua_State* L, char* name)
668
lua_pushstring(L,name);
672
lua_pushvalue(L,LUA_GLOBALSINDEX);
676
* It pops the module (or class) from the stack
678
TOLUA_API void tolua_endmodule (lua_State* L)
684
* It creates a new module
687
TOLUA_API void tolua_module (lua_State* L, char* name, int hasvar)
692
lua_pushstring(L,name);
694
if (!lua_istable(L,-1)) /* check if module already exists */
698
lua_pushstring(L,name);
700
lua_rawset(L,-4); /* assing module into module */
706
lua_pushvalue(L,LUA_GLOBALSINDEX);
710
if (!tolua_ismodulemetatable(L)) /* check if it already has a module metatable */
712
/* create metatable to get/set C/C++ variable */
714
tolua_moduleevents(L);
715
if (lua_getmetatable(L,-2))
716
lua_setmetatable(L,-2); /* set old metatable as metatable of metatable */
717
lua_setmetatable(L,-2);
720
lua_pop(L,1); /* pop module */
723
TOLUA_API void tolua_module (lua_State* L, char* name, int hasvar)
728
lua_pushstring(L,name);
734
lua_pushvalue(L,LUA_GLOBALSINDEX);
738
/* create metatable to get/set C/C++ variable */
740
tolua_moduleevents(L);
741
if (lua_getmetatable(L,-2))
742
lua_setmetatable(L,-2); /* set old metatable as metatable of metatable */
743
lua_setmetatable(L,-2);
746
lua_rawset(L,-3); /* assing module into module */
748
lua_pop(L,1); /* pop global table */
752
static void push_collector(lua_State* L, const char* type, lua_CFunction col) {
754
/* push collector function, but only if it's not NULL, or if there's no
757
luaL_getmetatable(L,type);
758
lua_pushstring(L,".collector");
761
lua_pushvalue(L, -1);
763
if (!lua_isnil(L, -1)) {
770
lua_pushcfunction(L,col);
777
* It maps a C class, setting the appropriate inheritance and super classes.
779
TOLUA_API void tolua_cclass (lua_State* L, char* lname, char* name, char* base, lua_CFunction col)
781
char cname[128] = "const ";
782
char cbase[128] = "const ";
783
strncat(cname,name,120);
784
strncat(cbase,base,120);
786
mapinheritance(L,name,base);
787
mapinheritance(L,cname,name);
789
mapsuper(L,cname,cbase);
790
mapsuper(L,name,base);
792
lua_pushstring(L,lname);
794
push_collector(L, name, col);
796
luaL_getmetatable(L,name);
797
lua_pushstring(L,".collector");
798
lua_pushcfunction(L,col);
803
luaL_getmetatable(L,name);
804
lua_rawset(L,-3); /* assign class metatable to module */
806
/* now we also need to store the collector table for the const
807
instances of the class */
808
push_collector(L, cname, col);
810
luaL_getmetatable(L,cname);
811
lua_pushstring(L,".collector");
812
lua_pushcfunction(L,col);
821
* It adds additional base classes to a class (for multiple inheritance)
823
TOLUA_API void tolua_addbase(lua_State* L, char* name, char* base) {
825
char cname[128] = "const ";
826
char cbase[128] = "const ";
827
strncat(cname,name,120);
828
strncat(cbase,base,120);
830
mapsuper(L,cname,cbase);
831
mapsuper(L,name,base);
836
* It assigns a function into the current module (or class)
838
TOLUA_API void tolua_function (lua_State* L, char* name, lua_CFunction func){
839
lua_pushstring(L,name);
840
lua_pushcfunction(L,func);
844
/* sets the __call event for the class (expects the class' main table on top) */
845
/* never really worked :(
846
TOLUA_API void tolua_set_call_event(lua_State* L, lua_CFunction func, char* type) {
848
lua_getmetatable(L, -1);
849
//luaL_getmetatable(L, type);
850
lua_pushstring(L,"__call");
851
lua_pushcfunction(L,func);
857
/* Map constant number
858
* It assigns a constant number into the current module (or class)
860
TOLUA_API void tolua_constant (lua_State* L, char* name, double value){
861
lua_pushstring(L,name);
862
tolua_pushnumber(L,value);
868
* It assigns a variable into the current module (or class)
870
TOLUA_API void tolua_variable (lua_State* L, char* name, lua_CFunction get, lua_CFunction set){
872
lua_pushstring(L,".get");
874
if (!lua_istable(L,-1)) {
875
/* create .get table, leaving it at the top */
878
lua_pushstring(L,".get");
882
lua_pushstring(L,name);
883
lua_pushcfunction(L,get);
884
lua_rawset(L,-3); /* store variable */
885
lua_pop(L,1); /* pop .get table */
889
lua_pushstring(L,".set");
891
if (!lua_istable(L,-1)) {
892
/* create .set table, leaving it at the top */
895
lua_pushstring(L,".set");
899
lua_pushstring(L,name);
900
lua_pushcfunction(L,set);
901
lua_rawset(L,-3); /* store variable */
902
lua_pop(L,1); /* pop .set table */
906
/* Access const array
907
* It reports an error when trying to write into a const array
909
static int const_array (lua_State* L){
910
luaL_error(L,"value of const array cannot be changed");
915
* It assigns an array into the current module (or class)
917
TOLUA_API void tolua_array (lua_State* L, char* name, lua_CFunction get, lua_CFunction set){
918
lua_pushstring(L,".get");
920
if (!lua_istable(L,-1)) {
921
/* create .get table, leaving it at the top */
924
lua_pushstring(L,".get");
928
lua_pushstring(L,name);
930
lua_newtable(L); /* create array metatable */
932
lua_setmetatable(L,-2); /* set the own table as metatable (for modules) */
933
lua_pushstring(L,"__index");
934
lua_pushcfunction(L,get);
936
lua_pushstring(L,"__newindex");
937
lua_pushcfunction(L,set?set:const_array);
940
lua_rawset(L,-3); /* store variable */
941
lua_pop(L,1); /* pop .get table */
945
TOLUA_API void tolua_dobuffer(lua_State* L, char* B, unsigned int size, const char* name) {
946
#ifdef LUA_VERSION_NUM /* lua 5.1 */
947
if (! luaL_loadbuffer(L, B, size, name)) {
948
lua_pcall(L, 0, 0, 0);
951
lua_dobuffer(L, B, size, name);