~ubuntu-branches/debian/squeeze/freeciv/squeeze

« back to all changes in this revision

Viewing changes to dependencies/tolua/tolua_event.c

  • Committer: Bazaar Package Importer
  • Author(s): Clint Adams, Karl Goetz, Clint Adams
  • Date: 2010-02-23 22:09:02 UTC
  • mfrom: (1.2.13 upstream)
  • Revision ID: james.westby@ubuntu.com-20100223220902-kiyrmr9i4152cka5
Tags: 2.2.0-1
[ Karl Goetz ]
* Remove civserver files in /etc/ggzd/ (Closes: 523772, 517787)
* Adding ${misc:Depends} to all binary packages (lintian warnings)

[ Clint Adams ]
* New upstream version.
  - Drop data_dsc_use_bindir.diff (binary pathnames have changed).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* tolua: event functions
2
 
** Support code for Lua bindings.
3
 
** Written by Waldemar Celes
4
 
** TeCGraf/PUC-Rio
5
 
** Apr 2003
6
 
** $Id: tolua_event.c 10334 2005-04-26 22:08:24Z vas $
7
 
*/
8
 
 
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. 
13
 
*/
14
 
 
15
 
#include <stdio.h>
16
 
 
17
 
#include "tolua_event.h"
18
 
#include "tolua.h"
19
 
 
20
 
/* Store at peer
21
 
        * It stores, creating the corresponding table if needed,
22
 
        * the pair key/value in the corresponding peer table
23
 
*/
24
 
static void storeatpeer (lua_State* L, int u)
25
 
{
26
 
         /* stack: key value (to be stored) */
27
 
                lua_pushstring(L,"tolua_peer");
28
 
                lua_rawget(L,LUA_REGISTRYINDEX);        /* stack: k v peer */
29
 
                lua_pushvalue(L,u);
30
 
                lua_rawget(L,-2);                       /* stack: k v peer peer[u] */
31
 
                if (!lua_istable(L,-1))
32
 
                {
33
 
                        lua_pop(L,1);                          /* stack: k v peer */
34
 
                        lua_newtable(L);                       /* stack: k v peer table */
35
 
                        lua_pushvalue(L,1);
36
 
                        lua_pushvalue(L,-2);                   /* stack: k v peer table u table */
37
 
                        lua_rawset(L,-4);                      /* stack: k v peer peer[u]=table */
38
 
                }
39
 
                lua_insert(L,-4);                       /* put table before k */
40
 
                lua_pop(L,1);                           /* pop peer */
41
 
                lua_rawset(L,-3);                       /* store at table */
42
 
                lua_pop(L,1);                           /* pop peer[u] */
43
 
}
44
 
 
45
 
/* Module index function
46
 
*/
47
 
static int module_index_event (lua_State* L)
48
 
{
49
 
        lua_pushstring(L,".get");
50
 
        lua_rawget(L,-3);
51
 
        if (lua_istable(L,-1))
52
 
        {
53
 
                lua_pushvalue(L,2);  /* key */
54
 
                lua_rawget(L,-2);
55
 
                if (lua_iscfunction(L,-1))
56
 
                {
57
 
                        lua_call(L,0,1);
58
 
                        return 1;
59
 
                }
60
 
                else if (lua_istable(L,-1))
61
 
                        return 1;
62
 
        }
63
 
        /* call old index meta event */
64
 
        if (lua_getmetatable(L,1))
65
 
        {
66
 
                lua_pushstring(L,"__index");
67
 
                lua_rawget(L,-2);
68
 
                lua_pushvalue(L,1);
69
 
                lua_pushvalue(L,2);
70
 
                if (lua_isfunction(L,-1))
71
 
                {
72
 
                        lua_call(L,2,1);
73
 
                        return 1;
74
 
                }
75
 
                else if (lua_istable(L,-1))
76
 
                {
77
 
                        lua_gettable(L,-3);
78
 
                        return 1;
79
 
                }
80
 
        }
81
 
        lua_pushnil(L);
82
 
        return 1;
83
 
}
84
 
 
85
 
/* Module newindex function
86
 
*/
87
 
static int module_newindex_event (lua_State* L)
88
 
{
89
 
        lua_pushstring(L,".set");
90
 
        lua_rawget(L,-4);
91
 
        if (lua_istable(L,-1))
92
 
        {
93
 
                lua_pushvalue(L,2);  /* key */
94
 
                lua_rawget(L,-2);
95
 
                if (lua_iscfunction(L,-1))
96
 
                {
97
 
                        lua_pushvalue(L,1); /* only to be compatible with non-static vars */
98
 
                        lua_pushvalue(L,3); /* value */
99
 
                        lua_call(L,2,0);
100
 
                        return 0;
101
 
                }
102
 
        }
103
 
        /* call old newindex meta event */
104
 
        if (lua_getmetatable(L,1) && lua_getmetatable(L,-1))
105
 
        {
106
 
                lua_pushstring(L,"__newindex");
107
 
                lua_rawget(L,-2);
108
 
                if (lua_isfunction(L,-1))
109
 
                {
110
 
                 lua_pushvalue(L,1);
111
 
                 lua_pushvalue(L,2);
112
 
                 lua_pushvalue(L,3);
113
 
                        lua_call(L,3,0);
114
 
                }
115
 
        }
116
 
        lua_settop(L,3);
117
 
        lua_rawset(L,-3);
118
 
        return 0;
119
 
}
120
 
 
121
 
/* Class index function
122
 
        * If the object is a userdata (ie, an object), it searches the field in 
123
 
        * the alternative table stored in the corresponding "peer" table.
124
 
*/
125
 
static int class_index_event (lua_State* L)
126
 
{
127
 
 int t = lua_type(L,1);
128
 
        if (t == LUA_TUSERDATA)
129
 
        {
130
 
                /* Access alternative table */
131
 
                lua_pushstring(L,"tolua_peer");
132
 
                lua_rawget(L,LUA_REGISTRYINDEX);        /* stack: obj key peer */
133
 
                lua_pushvalue(L,1);
134
 
                lua_rawget(L,-2);                       /* stack: obj key peer peer[u] */
135
 
                if (lua_istable(L,-1))
136
 
                {
137
 
                        lua_pushvalue(L,2);  /* key */
138
 
                        lua_rawget(L,-2);                      /* stack: obj key peer peer[u] value */
139
 
                        if (!lua_isnil(L,-1))
140
 
                                return 1;
141
 
                }
142
 
                lua_settop(L,2);                        /* stack: obj key */
143
 
                /* Try metatables */
144
 
                lua_pushvalue(L,1);                     /* stack: obj key obj */
145
 
                while (lua_getmetatable(L,-1))
146
 
                {                                       /* stack: obj key obj mt */
147
 
                        lua_remove(L,-2);                      /* stack: obj key mt */
148
 
                        if (lua_isnumber(L,2))                 /* check if key is a numeric value */
149
 
                        {
150
 
                                /* try operator[] */
151
 
                                lua_pushstring(L,".geti");    
152
 
                                lua_rawget(L,-2);                      /* stack: obj key mt func */
153
 
                                if (lua_isfunction(L,-1))
154
 
                                {
155
 
                                        lua_pushvalue(L,1);
156
 
                                        lua_pushvalue(L,2);
157
 
                                        lua_call(L,2,1);
158
 
                                        return 1;
159
 
                                }
160
 
   }
161
 
                        else
162
 
                        {
163
 
                         lua_pushvalue(L,2);                    /* stack: obj key mt key */
164
 
                                lua_rawget(L,-2);                      /* stack: obj key mt value */
165
 
                                if (!lua_isnil(L,-1))
166
 
                                        return 1;
167
 
                                else
168
 
                                        lua_pop(L,1);
169
 
                                /* try C/C++ variable */
170
 
                                lua_pushstring(L,".get");    
171
 
                                lua_rawget(L,-2);                      /* stack: obj key mt tget */
172
 
                                if (lua_istable(L,-1))
173
 
                                {
174
 
                                        lua_pushvalue(L,2);
175
 
                                        lua_rawget(L,-2);                      /* stack: obj key mt value */
176
 
                                        if (lua_iscfunction(L,-1))
177
 
                                        {
178
 
                                                lua_pushvalue(L,1);
179
 
                                                lua_pushvalue(L,2); 
180
 
                                                lua_call(L,2,1);
181
 
                                                return 1;
182
 
                                        }
183
 
                                        else if (lua_istable(L,-1))
184
 
                                        {
185
 
                                                /* deal with array: create table to be returned and cache it in peer */
186
 
                                                void* u = *((void**)lua_touserdata(L,1));
187
 
                                                lua_newtable(L);                /* stack: obj key mt value table */
188
 
                                                lua_pushstring(L,".self");
189
 
                                                lua_pushlightuserdata(L,u);
190
 
                                                lua_rawset(L,-3);               /* store usertype in ".self" */
191
 
                                                lua_insert(L,-2);               /* stack: obj key mt table value */
192
 
                                                lua_setmetatable(L,-2);         /* set stored value as metatable */
193
 
                                                lua_pushvalue(L,-1);            /* stack: obj key met table table */
194
 
                                                lua_pushvalue(L,2);             /* stack: obj key mt table table key */
195
 
                                                lua_insert(L,-2);               /*  stack: obj key mt table key table */
196
 
                                                storeatpeer(L,1);               /* stack: obj key mt table */
197
 
                                                return 1;
198
 
                                        }
199
 
                                }
200
 
                        }
201
 
                        lua_settop(L,3);
202
 
                }
203
 
                lua_pushnil(L);
204
 
                return 1;
205
 
        }
206
 
        else if (t== LUA_TTABLE)
207
 
        {
208
 
                module_index_event(L);
209
 
                return 1;
210
 
        }
211
 
        lua_pushnil(L);
212
 
        return 1;
213
 
}
214
 
 
215
 
/* Newindex function
216
 
        * It first searches for a C/C++ varaible to be set.
217
 
        * Then, it either stores it in the alternative peer table (in the case it is
218
 
        * an object) or in the own table (that represents the class or module).
219
 
*/
220
 
static int class_newindex_event (lua_State* L)
221
 
{
222
 
 int t = lua_type(L,1);
223
 
        if (t == LUA_TUSERDATA)
224
 
        {
225
 
         /* Try accessing a C/C++ variable to be set */
226
 
                lua_getmetatable(L,1);
227
 
                while (lua_istable(L,-1))                /* stack: t k v mt */
228
 
                {
229
 
                        if (lua_isnumber(L,2))                 /* check if key is a numeric value */
230
 
                        {
231
 
                                /* try operator[] */
232
 
                                lua_pushstring(L,".seti");    
233
 
                                lua_rawget(L,-2);                      /* stack: obj key mt func */
234
 
                                if (lua_isfunction(L,-1))
235
 
                                {
236
 
                                        lua_pushvalue(L,1);
237
 
                                        lua_pushvalue(L,2);
238
 
                                        lua_pushvalue(L,3);
239
 
                                        lua_call(L,3,0);
240
 
                                        return 0;
241
 
                                }
242
 
   }
243
 
                        else
244
 
                        {
245
 
                                lua_pushstring(L,".set");
246
 
                                lua_rawget(L,-2);                      /* stack: t k v mt tset */
247
 
                                if (lua_istable(L,-1))
248
 
                                {
249
 
                                        lua_pushvalue(L,2);
250
 
                                        lua_rawget(L,-2);                     /* stack: t k v mt tset func */
251
 
                                        if (lua_iscfunction(L,-1))
252
 
                                        {
253
 
                                                lua_pushvalue(L,1);
254
 
                                                lua_pushvalue(L,3); 
255
 
                                                lua_call(L,2,0);
256
 
                                                return 0;
257
 
                                        }
258
 
                                        lua_pop(L,1);                          /* stack: t k v mt tset */
259
 
                                }
260
 
                                lua_pop(L,1);                           /* stack: t k v mt */
261
 
                                if (!lua_getmetatable(L,-1))            /* stack: t k v mt mt */
262
 
                                        lua_pushnil(L);
263
 
                                lua_remove(L,-2);                       /* stack: t k v mt */
264
 
                        }
265
 
                }
266
 
         lua_settop(L,3);                          /* stack: t k v */
267
 
 
268
 
                /* then, store as a new field */
269
 
                storeatpeer(L,1);
270
 
        }
271
 
        else if (t== LUA_TTABLE)
272
 
        {
273
 
                module_newindex_event(L);
274
 
        }
275
 
        return 0;
276
 
}
277
 
 
278
 
static int do_operator (lua_State* L, const char* op)
279
 
{
280
 
        if (lua_isuserdata(L,1))
281
 
        {
282
 
                /* Try metatables */
283
 
                lua_pushvalue(L,1);                     /* stack: op1 op2 */
284
 
                while (lua_getmetatable(L,-1))
285
 
                {                                       /* stack: op1 op2 op1 mt */
286
 
                        lua_remove(L,-2);                      /* stack: op1 op2 mt */
287
 
                        lua_pushstring(L,op);                  /* stack: op1 op2 mt key */
288
 
                        lua_rawget(L,-2);                      /* stack: obj key mt func */
289
 
                        if (lua_isfunction(L,-1))
290
 
                        {
291
 
                                lua_pushvalue(L,1);
292
 
                                lua_pushvalue(L,2); 
293
 
                                lua_call(L,2,1);
294
 
                                return 1;
295
 
                        }
296
 
                        lua_settop(L,3);
297
 
                }
298
 
        }
299
 
        tolua_error(L,"Attempt to perform operation on an invalid operand",NULL);
300
 
        return 0;
301
 
}
302
 
 
303
 
static int class_add_event (lua_State* L)
304
 
{
305
 
        return do_operator(L,".add");
306
 
}
307
 
 
308
 
static int class_sub_event (lua_State* L)
309
 
{
310
 
        return do_operator(L,".sub");
311
 
}
312
 
 
313
 
static int class_mul_event (lua_State* L)
314
 
{
315
 
        return do_operator(L,".mul");
316
 
}
317
 
 
318
 
static int class_div_event (lua_State* L)
319
 
{
320
 
        return do_operator(L,".div");
321
 
}
322
 
 
323
 
static int class_lt_event (lua_State* L)
324
 
{
325
 
        return do_operator(L,".lt");
326
 
}
327
 
 
328
 
static int class_le_event (lua_State* L)
329
 
{
330
 
        return do_operator(L,".le");
331
 
}
332
 
 
333
 
static int class_eq_event (lua_State* L)
334
 
{
335
 
        return do_operator(L,".eq");
336
 
}
337
 
 
338
 
static int class_gc_event (lua_State* L)
339
 
{
340
 
        void* u = *((void**)lua_touserdata(L,1));
341
 
 lua_pushstring(L,"tolua_gc");
342
 
 lua_rawget(L,LUA_REGISTRYINDEX);
343
 
        lua_pushlightuserdata(L,u);
344
 
        lua_rawget(L,-2);
345
 
        if (lua_isfunction(L,-1))
346
 
        {
347
 
         lua_pushvalue(L,1);
348
 
                lua_call(L,1,0);
349
 
         lua_pushlightuserdata(L,u);
350
 
                lua_pushnil(L);
351
 
                lua_rawset(L,-3);
352
 
        }
353
 
        lua_pop(L,2);
354
 
        return 0;
355
 
}
356
 
 
357
 
/* Register module events
358
 
        * It expects the metatable on the top of the stack
359
 
*/
360
 
TOLUA_API void tolua_moduleevents (lua_State* L)
361
 
{
362
 
        lua_pushstring(L,"__index");
363
 
        lua_pushcfunction(L,module_index_event);
364
 
        lua_rawset(L,-3);
365
 
        lua_pushstring(L,"__newindex");
366
 
        lua_pushcfunction(L,module_newindex_event);
367
 
        lua_rawset(L,-3);
368
 
}
369
 
 
370
 
/* Check if the object on the top has a module metatable
371
 
*/
372
 
TOLUA_API int tolua_ismodulemetatable (lua_State* L)
373
 
{
374
 
        int r = 0;
375
 
        if (lua_getmetatable(L,-1))
376
 
        {
377
 
                lua_pushstring(L,"__index");
378
 
                lua_rawget(L,-2);
379
 
                r = (lua_tocfunction(L,-1) == module_index_event);
380
 
                lua_pop(L,2);
381
 
        }
382
 
        return r;
383
 
}
384
 
 
385
 
/* Register class events
386
 
        * It expects the metatable on the top of the stack
387
 
*/
388
 
TOLUA_API void tolua_classevents (lua_State* L)
389
 
{
390
 
        lua_pushstring(L,"__index");
391
 
        lua_pushcfunction(L,class_index_event);
392
 
        lua_rawset(L,-3);
393
 
        lua_pushstring(L,"__newindex");
394
 
        lua_pushcfunction(L,class_newindex_event);
395
 
        lua_rawset(L,-3);
396
 
 
397
 
        lua_pushstring(L,"__add");
398
 
        lua_pushcfunction(L,class_add_event);
399
 
        lua_rawset(L,-3);
400
 
        lua_pushstring(L,"__sub");
401
 
        lua_pushcfunction(L,class_sub_event);
402
 
        lua_rawset(L,-3);
403
 
        lua_pushstring(L,"__mul");
404
 
        lua_pushcfunction(L,class_mul_event);
405
 
        lua_rawset(L,-3);
406
 
        lua_pushstring(L,"__div");
407
 
        lua_pushcfunction(L,class_div_event);
408
 
        lua_rawset(L,-3);
409
 
 
410
 
        lua_pushstring(L,"__lt");
411
 
        lua_pushcfunction(L,class_lt_event);
412
 
        lua_rawset(L,-3);
413
 
        lua_pushstring(L,"__le");
414
 
        lua_pushcfunction(L,class_le_event);
415
 
        lua_rawset(L,-3);
416
 
        lua_pushstring(L,"__eq");
417
 
        lua_pushcfunction(L,class_eq_event);
418
 
        lua_rawset(L,-3);
419
 
 
420
 
        lua_pushstring(L,"__gc");
421
 
        lua_pushcfunction(L,class_gc_event);
422
 
        lua_rawset(L,-3);
423
 
}
424