?? tolua_map.c
字號:
/* tolua: functions to map features** Support code for Lua bindings.** Written by Waldemar Celes** TeCGraf/PUC-Rio** Apr 2003** $Id: $*//* 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_event.h"#include "lauxlib.h"#include <string.h>#include <stdio.h>#include <stdlib.h>#include <math.h>/* Create metatable * Create and register new metatable*/static int tolua_newmetatable (lua_State* L, char* name){ int r = luaL_newmetatable(L,name); #ifdef LUA_VERSION_NUM /* only lua 5.1 */ if (r) { lua_pushvalue(L, -1); lua_pushstring(L, name); lua_settable(L, LUA_REGISTRYINDEX); /* reg[mt] = type_name */ }; #endif if (r) tolua_classevents(L); /* set meta events */ lua_pop(L,1); return r;}/* Map super classes * It sets 'name' as being also a 'base', mapping all super classes of 'base' in 'name'*/static void mapsuper (lua_State* L, const char* name, const char* base){ /* push registry.super */ lua_pushstring(L,"tolua_super"); lua_rawget(L,LUA_REGISTRYINDEX); /* stack: super */ luaL_getmetatable(L,name); /* stack: super mt */ lua_rawget(L,-2); /* stack: super table */ if (lua_isnil(L,-1)) { /* create table */ lua_pop(L,1); lua_newtable(L); /* stack: super table */ luaL_getmetatable(L,name); /* stack: super table mt */ lua_pushvalue(L,-2); /* stack: super table mt table */ lua_rawset(L,-4); /* stack: super table */ } /* set base as super class */ lua_pushstring(L,base); lua_pushboolean(L,1); lua_rawset(L,-3); /* stack: super table */ /* set all super class of base as super class of name */ luaL_getmetatable(L,base); /* stack: super table base_mt */ lua_rawget(L,-3); /* stack: super table base_table */ if (lua_istable(L,-1)) { /* traverse base table */ lua_pushnil(L); /* first key */ while (lua_next(L,-2) != 0) { /* stack: ... base_table key value */ lua_pushvalue(L,-2); /* stack: ... base_table key value key */ lua_insert(L,-2); /* stack: ... base_table key key value */ lua_rawset(L,-5); /* stack: ... base_table key */ } } lua_pop(L,3); /* stack: <empty> */}/* creates a 'tolua_ubox' table for base clases, and// expects the metatable and base metatable on the stack */static void set_ubox(lua_State* L) { /* mt basemt */ if (!lua_isnil(L, -1)) { lua_pushstring(L, "tolua_ubox"); lua_rawget(L,-2); } else { lua_pushnil(L); }; /* mt basemt base_ubox */ if (!lua_isnil(L,-1)) { lua_pushstring(L, "tolua_ubox"); lua_insert(L, -2); /* mt basemt key ubox */ lua_rawset(L,-4); /* (mt with ubox) basemt */ } else { /* mt basemt nil */ lua_pop(L, 1); lua_pushstring(L,"tolua_ubox"); lua_newtable(L); /* make weak value metatable for ubox table to allow userdata to be garbage-collected */ lua_newtable(L); lua_pushliteral(L, "__mode"); lua_pushliteral(L, "v"); lua_rawset(L, -3); /* stack: string ubox mt */ lua_setmetatable(L, -2); /* stack:mt basemt string ubox */ lua_rawset(L,-4); };};/* Map inheritance * It sets 'name' as derived from 'base' by setting 'base' as metatable of 'name'*/static void mapinheritance (lua_State* L, const char* name, const char* base){ /* set metatable inheritance */ luaL_getmetatable(L,name); if (base && *base) luaL_getmetatable(L,base); else { if (lua_getmetatable(L, -1)) { /* already has a mt, we don't overwrite it */ lua_pop(L, 2); return; }; luaL_getmetatable(L,"tolua_commonclass"); }; set_ubox(L); lua_setmetatable(L,-2); lua_pop(L,1);}/* Object type*/static int tolua_bnd_type (lua_State* L){ tolua_typename(L,lua_gettop(L)); return 1;}/* Take ownership*/static int tolua_bnd_takeownership (lua_State* L){ int success = 0; if (lua_isuserdata(L,1)) { if (lua_getmetatable(L,1)) /* if metatable? */ { lua_pop(L,1); /* clear metatable off stack */ /* force garbage collection to avoid C to reuse a to-be-collected address */ #ifdef LUA_VERSION_NUM lua_gc(L, LUA_GCCOLLECT, 0); #else lua_setgcthreshold(L,0); #endif success = tolua_register_gc(L,1); } } lua_pushboolean(L,success!=0); return 1;}/* Release ownership*/static int tolua_bnd_releaseownership (lua_State* L){ int done = 0; if (lua_isuserdata(L,1)) { void* u = *((void**)lua_touserdata(L,1)); /* force garbage collection to avoid releasing a to-be-collected address */ #ifdef LUA_VERSION_NUM lua_gc(L, LUA_GCCOLLECT, 0); #else lua_setgcthreshold(L,0); #endif lua_pushstring(L,"tolua_gc"); lua_rawget(L,LUA_REGISTRYINDEX); lua_pushlightuserdata(L,u); lua_rawget(L,-2); lua_getmetatable(L,1); if (lua_rawequal(L,-1,-2)) /* check that we are releasing the correct type */ { lua_pushlightuserdata(L,u); lua_pushnil(L); lua_rawset(L,-5); done = 1; } } lua_pushboolean(L,done!=0); return 1;}/* Type casting*/static int tolua_bnd_cast (lua_State* L){/* // old code void* v = tolua_tousertype(L,1,NULL); const char* s = tolua_tostring(L,2,NULL); if (v && s) tolua_pushusertype(L,v,s); else lua_pushnil(L); return 1;*/ void* v; const char* s; if (lua_islightuserdata(L, 1)) { v = tolua_touserdata(L, 1, NULL); } else { v = tolua_tousertype(L, 1, 0); }; s = tolua_tostring(L,2,NULL); if (v && s) tolua_pushusertype(L,v,s); else lua_pushnil(L); return 1;}/* Inheritance*/static int tolua_bnd_inherit (lua_State* L) { /* stack: lua object, c object */ lua_pushstring(L, ".c_instance"); lua_pushvalue(L, -2); lua_rawset(L, -4); /* l_obj[".c_instance"] = c_obj */ return 0;};#ifdef LUA_VERSION_NUM /* lua 5.1 */static int tolua_bnd_setpeer(lua_State* L) { /* stack: userdata, table */ if (!lua_isuserdata(L, -2)) { lua_pushstring(L, "Invalid argument #1 to setpeer: userdata expected."); lua_error(L); }; if (lua_isnil(L, -1)) { lua_pop(L, 1); lua_pushvalue(L, TOLUA_NOPEER); }; lua_setfenv(L, -2); return 0;};static int tolua_bnd_getpeer(lua_State* L) { /* stack: userdata */ lua_getfenv(L, -1); if (lua_rawequal(L, -1, TOLUA_NOPEER)) { lua_pop(L, 1); lua_pushnil(L); }; return 1;};#endif/* static int class_gc_event (lua_State* L); */TOLUA_API void tolua_open (lua_State* L){ int top = lua_gettop(L); lua_pushstring(L,"tolua_opened"); lua_rawget(L,LUA_REGISTRYINDEX); if (!lua_isboolean(L,-1)) { lua_pushstring(L,"tolua_opened"); lua_pushboolean(L,1); lua_rawset(L,LUA_REGISTRYINDEX); #ifndef LUA_VERSION_NUM /* only prior to lua 5.1 */ /* create peer object table */ lua_pushstring(L, "tolua_peers"); lua_newtable(L); /* make weak key metatable for peers indexed by userdata object */ lua_newtable(L); lua_pushliteral(L, "__mode"); lua_pushliteral(L, "k"); lua_rawset(L, -3); /* stack: string peers mt */ lua_setmetatable(L, -2); /* stack: string peers */ lua_rawset(L,LUA_REGISTRYINDEX); #endif /* create object ptr -> udata mapping table */ lua_pushstring(L,"tolua_ubox"); lua_newtable(L); /* make weak value metatable for ubox table to allow userdata to be garbage-collected */ lua_newtable(L); lua_pushliteral(L, "__mode"); lua_pushliteral(L, "v"); lua_rawset(L, -3); /* stack: string ubox mt */ lua_setmetatable(L, -2); /* stack: string ubox */ lua_rawset(L,LUA_REGISTRYINDEX); lua_pushstring(L,"tolua_super"); lua_newtable(L); lua_rawset(L,LUA_REGISTRYINDEX); lua_pushstring(L,"tolua_gc"); lua_newtable(L);lua_rawset(L,LUA_REGISTRYINDEX); /* create gc_event closure */ lua_pushstring(L, "tolua_gc_event"); lua_pushstring(L, "tolua_gc"); lua_rawget(L, LUA_REGISTRYINDEX); lua_pushstring(L, "tolua_super"); lua_rawget(L, LUA_REGISTRYINDEX); lua_pushcclosure(L, class_gc_event, 2); lua_rawset(L, LUA_REGISTRYINDEX); tolua_newmetatable(L,"tolua_commonclass"); tolua_module(L,NULL,0); tolua_beginmodule(L,NULL); tolua_module(L,"tolua",0); tolua_beginmodule(L,"tolua"); tolua_function(L,"type",tolua_bnd_type); tolua_function(L,"takeownership",tolua_bnd_takeownership); tolua_function(L,"releaseownership",tolua_bnd_releaseownership); tolua_function(L,"cast",tolua_bnd_cast); tolua_function(L,"inherit", tolua_bnd_inherit); #ifdef LUA_VERSION_NUM /* lua 5.1 */ tolua_function(L, "setpeer", tolua_bnd_setpeer); tolua_function(L, "getpeer", tolua_bnd_getpeer); #endif tolua_endmodule(L); tolua_endmodule(L); } lua_settop(L,top);}/* Copy a C object*/TOLUA_API void* tolua_copy (lua_State* L, void* value, unsigned int size){ void* clone = (void*)malloc(size); if (clone) memcpy(clone,value,size); else tolua_error(L,"insuficient memory",NULL);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -