UGDK
|
00001 00002 #ifndef MODULE_LUAPROXY_H_ 00003 #define MODULE_LUAPROXY_H_ 00004 00005 #include <ugdk/script/languages/lua/header.h> 00006 #include <ugdk/script/languages/lua/state.h> 00007 #include <ugdk/script/scriptmanager.h> 00008 #include <ugdk/script/virtualobj.h> 00009 #include <ugdk/script/virtualdata.h> 00010 00011 namespace ugdk { 00012 namespace script { 00013 namespace lua { 00014 00015 static int ClassGet(lua_State* L) { 00016 /* there should be 2 params passed in 00017 (1) userdata (not the meta table) 00018 (2) string name of the attribute 00019 */ 00020 assert(lua_isuserdata(L,-2) || lua_istable(L,-2)); /* just in case */ 00021 lua_getmetatable(L,-2); /* get the meta table */ 00022 assert(lua_istable(L,-1)); /* just in case */ 00023 SWIG_Lua_get_table(L,".get"); /* find the .get table */ 00024 assert(lua_istable(L,-1)); /* just in case */ 00025 /* look for the key in the .get table */ 00026 lua_pushvalue(L,2); /* key */ 00027 lua_rawget(L,-2); 00028 lua_remove(L,-2); /* stack tidy, remove .get table */ 00029 if (lua_iscfunction(L,-1)) 00030 { /* found it so call the fn & return its value */ 00031 lua_pushvalue(L,1); /* the userdata */ 00032 lua_call(L,1,1); /* 1 value in (userdata),1 out (result) */ 00033 lua_remove(L,-2); /* stack tidy, remove metatable */ 00034 return 1; 00035 } 00036 lua_pop(L,1); /* remove whatever was there */ 00037 /* ok, so try the .fn table */ 00038 SWIG_Lua_get_table(L,".fn"); /* find the .get table */ 00039 assert(lua_istable(L,-1)); /* just in case */ 00040 lua_pushvalue(L,2); /* key */ 00041 lua_rawget(L,-2); /* look for the fn */ 00042 lua_remove(L,-2); /* stack tidy, remove .fn table */ 00043 if (lua_isfunction(L,-1)) /* note: if its a C function or lua function */ 00044 { /* found it so return the fn & let lua call it */ 00045 lua_remove(L,-2); /* stack tidy, remove metatable */ 00046 return 1; 00047 } 00048 lua_pop(L,1); /* remove whatever was there */ 00049 /* NEW: looks for the __getitem() fn 00050 this is a user provided get fn */ 00051 SWIG_Lua_get_table(L,"__getitem"); /* find the __getitem fn */ 00052 if (lua_iscfunction(L,-1)) /* if its there */ 00053 { /* found it so call the fn & return its value */ 00054 lua_pushvalue(L,1); /* the userdata */ 00055 lua_pushvalue(L,2); /* the parameter */ 00056 lua_call(L,2,1); /* 2 value in (userdata),1 out (result) */ 00057 lua_remove(L,-2); /* stack tidy, remove metatable */ 00058 return 1; 00059 } 00060 return 0; /* sorry not known */ 00061 } 00062 00063 /* the class.set method, performs the lookup of class attributes */ 00064 static int ClassSet(lua_State* L) { 00065 /* there should be 3 params passed in 00066 (1) table (not the meta table) 00067 (2) string name of the attribute 00068 (3) any for the new value 00069 printf("SWIG_Lua_class_set %p(%s) '%s' %p(%s)\n", 00070 lua_topointer(L,1),lua_typename(L,lua_type(L,1)), 00071 lua_tostring(L,2), 00072 lua_topointer(L,3),lua_typename(L,lua_type(L,3)));*/ 00073 00074 assert(lua_isuserdata(L,1) || lua_istable(L,1)); /* just in case */ 00075 lua_getmetatable(L,1); /* get the meta table */ 00076 assert(lua_istable(L,-1)); /* just in case */ 00077 00078 SWIG_Lua_get_table(L,".set"); /* find the .set table */ 00079 if (lua_istable(L,-1)) 00080 { 00081 /* look for the key in the .set table */ 00082 lua_pushvalue(L,2); /* key */ 00083 lua_rawget(L,-2); 00084 if (lua_iscfunction(L,-1)) 00085 { /* found it so call the fn & return its value */ 00086 lua_pushvalue(L,1); /* userdata */ 00087 lua_pushvalue(L,3); /* value */ 00088 lua_call(L,2,0); 00089 return 0; 00090 } 00091 lua_pop(L,1); /* remove the value */ 00092 } 00093 lua_pop(L,1); /* remove the value .set table */ 00094 /* NEW: looks for the __setitem() fn 00095 this is a user provided set fn */ 00096 SWIG_Lua_get_table(L,"__setitem"); /* find the fn */ 00097 if (lua_iscfunction(L,-1)) /* if its there */ 00098 { /* found it so call the fn & return its value */ 00099 lua_pushvalue(L,1); /* the userdata */ 00100 lua_pushvalue(L,2); /* the parameter */ 00101 lua_pushvalue(L,3); /* the value */ 00102 lua_call(L,3,0); /* 3 values in ,0 out */ 00103 lua_remove(L,-2); /* stack tidy, remove metatable */ 00104 return 1; 00105 } 00106 // final case... just put it in the goddamn table, dude. 00107 lua_settop(L, 3); // go back to original stack 00108 if (lua_istable(L, 1)) 00109 lua_rawset(L, 1); 00110 return 0; 00111 } 00112 00113 static void ExportMetamethods (lua_State *L) { 00114 lua_getfield(L, LUA_GLOBALSINDEX, "UGDK_proxymethods"); 00115 if (lua_istable(L,-1)) // someone already made it 00116 return; 00117 lua_createtable(L, 0, 2); 00118 lua_pushcclosure(L, ClassGet, 0); 00119 lua_setfield(L, -2, "getter"); 00120 lua_pushcclosure(L, ClassSet, 0); 00121 lua_setfield(L, -2, "setter"); 00122 lua_setfield(L, LUA_GLOBALSINDEX, "UGDK_proxymethods"); 00123 } 00124 00125 } /* namespace lua */ 00126 } /* namespace script */ 00127 } /* namespace ugdk */ 00128 00129 #endif /* MODULE_LUAPROXY_H_ */