summaryrefslogtreecommitdiff
path: root/src/lua/tolua_lb.c
blob: 5fd4c337caae4c00583476ce6495eaa97bdedb3e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/* tolua
** Support code for Lua bindings.
** Written by Waldemar Celes
** TeCGraf/PUC-Rio
** Jul 1998
** $Id: tolua_lb.c,v 1.2 2001/11/26 23:00:27 darkgod Exp $
*/

/* This code is free software; you can redistribute it and/or modify it. 
** The software provided hereunder is on an "as is" basis, and 
** the author has no obligation to provide maintenance, support, updates,
** enhancements, or modifications. 
*/

#include "tolua.h"
#include "tolua_rg.h"
#include "tolua_tm.h"
#include "tolua_tt.h"


int tolua_open (lua_State* L)
{
 int tolua_tolua_open (lua_State* L);
 /* check if alread opened */
 toluaI_getregistry(L,"TOLUA");
 if (lua_isnil(L,-1))
 {
  lua_pushnumber(L,1);
  toluaI_setregistry(L,"TOLUA");
  toluaI_tt_init(L);
  toluaI_tm_init(L);
  lua_getglobal(L,"foreach");
  toluaI_setregistry(L,"tolua_orig_foreach");
  tolua_tolua_open(L);	/* opens tolua own binding */
 }
 lua_pop(L,1);
 return 1;
}

void tolua_using (lua_State* L, int module)
{
 toluaI_tm_using(L,module);
}

void tolua_class (lua_State* L, int derived, int base)
{
 int tag = lua_newtag(L);    /* new tag of instances of that class */
 toluaI_tm_setclass(L,derived);
 toluaI_tm_linstance(L,tag,derived);
 lua_pushvalue(L,derived);
 lua_pushstring(L,".base");
 lua_pushvalue(L,base);
 lua_rawset(L,-3); 
 lua_pushstring(L,".itag");
 lua_pushnumber(L,tag);
 lua_rawset(L,-3);
 lua_pop(L,1);
}

void tolua_instance (lua_State* L, int instance, int classobj)
{
 int tag;
 lua_pushvalue(L,classobj);
 lua_pushstring(L,".itag");
 lua_gettable(L,-2);
 tag = (int) lua_tonumber(L,-1);
 lua_pop(L,2);  /* number and table */
 if (tag==0)
  tolua_error(L,"unregistered 'classobj' in function 'tolua_instance'.");
 lua_pushvalue(L,instance);
 lua_settag(L,tag);
 lua_pop(L,1);
}

static int filter (lua_State* L)
{
 int n = 1; /* name */
 int v = 2; /* value */
 int f = lua_gettop(L); /* function */
 /* do not pass string fields starting with a dot */
 if (!lua_isstring(L,n) || *lua_tostring(L,n)!='.')
 {
  lua_pushvalue(L,f);
  lua_pushvalue(L,n);
  lua_pushvalue(L,v);
  lua_call(L,2,1);
 }
 else
  lua_pushnil(L);
 return 1;
}

void tolua_foreach (lua_State* L, int lo, int f)
{
 if (toluaI_tt_isusertype(L,lo))
 {
  toluaI_tm_pushmate(L,lo);
  if (lua_isnil(L,-1))
   return;    /* no field in mate table */
  else
   lo = lua_gettop(L);
 }
 toluaI_getregistry(L,"tolua_orig_foreach");
 lua_pushvalue(L,lo);
 lua_pushvalue(L,f);
 lua_pushcclosure(L,filter,1);
 lua_call(L,2,1);
}

const char* tolua_type (lua_State* L, int lo)
{
 return toluaI_tt_getobjtype(L,lo);
}

int tolua_tag (lua_State* L, char* type)
{
 return toluaI_tt_gettag(L,type);
}

int tolua_base (lua_State* L, int lo)
{
 if (toluaI_tt_isusertype(L,lo))
 {
  toluaI_tm_pushclass(L,lo);
  return lua_gettop(L);
 }
 else if (lua_istable(L,lo))
 {
  lua_pushvalue(L,lo); 
  lua_pushstring(L,".base");
  lua_rawget(L,-2);
  return -1;
 }
 else
  return 0;
}

int tolua_cast (lua_State* L, int lo, char* type)
{
 if (lua_isuserdata(L,lo))
 {
  tolua_pushusertype(L,lua_touserdata(L,lo),toluaI_tt_gettag(L,type));
  return -1;
 }
 else
  return 0;
}

void tolua_takeownership (lua_State* L, int lo)
{
 if (toluaI_tt_isusertype(L,lo))
 {
  /* force garbage collection to avoid C to reuse a to-be-collected address */
  lua_setgcthreshold(L,0);
  tolua_doclone(L,lua_touserdata(L,lo),lua_tag(L,lo));  
 }
 else
  tolua_error(L,"cannot take ownership of specified obejct.");
}