static int int_pushfunc(lua_State *L, luaA_Type type_id, const void *cin) { luaL_getmetatable(L, luaA_typename(L, type_id)); luaL_getsubtable(L, -1, "__values"); int singleton = *(int *)cin; lua_pushnumber(L, singleton); lua_gettable(L, -2); if(lua_isnoneornil(L, -1)) { lua_pop(L, 1); int *udata = lua_newuserdata(L, sizeof(int)); *udata = singleton; luaL_setmetatable(L, luaA_typename(L, type_id)); lua_pushinteger(L, singleton); // warning : no uservalue lua_pushvalue(L, -2); lua_settable(L, -4); if(luaL_getmetafield(L, -1, "__init")) { lua_pushvalue(L, -2); // the new alocated object lua_pushlightuserdata(L, (void *)cin); // forced to cast.. lua_call(L, 2, 0); } } lua_remove(L, -2); //__values lua_remove(L, -2); // metatable return 1; }
static void init_metatable(lua_State *L, luaA_Type type_id) { luaL_newmetatable(L, luaA_typename(L, type_id)); lua_pushstring(L, luaA_typename(L, type_id)); lua_setfield(L, -2, "__luaA_TypeName"); lua_pushnumber(L, type_id); lua_setfield(L, -2, "__luaA_Type"); lua_pushvalue(L, -1); lua_pushcclosure(L, autotype_next, 1); lua_setfield(L, -2, "__next"); lua_pushvalue(L, -1); lua_pushcclosure(L, autotype_pairs, 1); lua_setfield(L, -2, "__pairs"); lua_pushvalue(L, -1); lua_pushcclosure(L, autotype_index, 1); lua_setfield(L, -2, "__index"); lua_pushvalue(L, -1); lua_pushcclosure(L, autotype_newindex, 1); lua_setfield(L, -2, "__newindex"); lua_newtable(L); lua_setfield(L, -2, "__get"); lua_newtable(L); lua_setfield(L, -2, "__set"); // leave metatable on top of stack }
void dt_lua_type_setmetafield_type(lua_State*L,luaA_Type type_id,const char* method_name) { // These metafields should never be overridden by user code if( !strcmp(method_name,"__index") || !strcmp(method_name,"__newindex") || !strcmp(method_name,"__number_index") || !strcmp(method_name,"__number_newindex") || !strcmp(method_name,"__pairs") || !strcmp(method_name,"__ipairs") || !strcmp(method_name,"__next") || !strcmp(method_name,"__inext") || !strcmp(method_name,"__get") || !strcmp(method_name,"__set") || !strcmp(method_name,"__len") || !strcmp(method_name,"__luaA_Type") || !strcmp(method_name,"__luaA_TypeName") || !strcmp(method_name,"__luaA_ParentMetatable") || !strcmp(method_name,"__init") || !strcmp(method_name,"__values") || !strcmp(method_name,"__singleton") || !strcmp(method_name,"__pusher") || !strcmp(method_name,"__getter") || !strcmp(method_name,"__mode") || 0) { luaL_error(L,"non-core lua code is not allowed to change meta-field %s\n",method_name); } else if(!strcmp(method_name,"__tostring")) { luaL_getmetatable(L, luaA_typename(L, type_id)); lua_pushvalue(L,-2); lua_setfield(L, -2, "__real_tostring"); lua_pop(L, 2); // pop the metatable and the value return; // whitelist for specific types } else if( // if you add a type here, make sure it handles inheritence of metamethods itself // typically, set the metamethod not for the parent type but just after inheritence ( !strcmp(method_name,"__associated_object")&& dt_lua_typeisa_type(L,type_id,luaA_type_find(L,"dt_imageio_module_format_t"))) || ( !strcmp(method_name,"__associated_object")&& dt_lua_typeisa_type(L,type_id,luaA_type_find(L,"dt_imageio_module_storage_t"))) || ( !strcmp(method_name,"__gc")&& dt_lua_typeisa_type(L,type_id,luaA_type_find(L,"dt_style_t"))) || ( !strcmp(method_name,"__gc")&& dt_lua_typeisa_type(L,type_id,luaA_type_find(L,"dt_style_item_t"))) || ( !strcmp(method_name,"__gc")&& dt_lua_typeisa_type(L,type_id,luaA_type_find(L,"lua_widget"))) || ( !strcmp(method_name,"__call")&& dt_lua_typeisa_type(L,type_id,luaA_type_find(L,"lua_widget"))) || ( !strcmp(method_name,"__gtk_signals")&& dt_lua_typeisa_type(L,type_id,luaA_type_find(L,"lua_widget"))) || 0) { // Nothign to be done } else { luaL_error(L,"metafield not handled :%s for type %s\n",method_name,luaA_typename(L,type_id)); } luaL_getmetatable(L, luaA_typename(L, type_id)); lua_pushvalue(L,-2); lua_setfield(L, -2, method_name); lua_pop(L, 2); // pop the metatable and the value }
void dt_lua_type_register_parent_type(lua_State *L, luaA_Type type_id, luaA_Type parent_type_id) { luaL_getmetatable(L, luaA_typename(L, type_id)); // gets the metatable since it's supposed to exist luaL_getmetatable(L, luaA_typename(L, parent_type_id)); // gets the metatable since it's supposed to exist lua_pushvalue(L, -1); lua_setfield(L, -3, "__luaA_ParentMetatable"); lua_getfield(L, -2, "__get"); lua_getfield(L, -2, "__get"); lua_pushnil(L); /* first key */ while(lua_next(L, -2) != 0) { lua_getfield(L,-4,lua_tostring(L,-2)); if(lua_isnil(L,-1)) { lua_pop(L,1); lua_setfield(L, -4, lua_tostring(L,-2)); } else { lua_pop(L,2); } } lua_pop(L, 2); lua_getfield(L, -2, "__set"); lua_getfield(L, -2, "__set"); lua_pushnil(L); /* first key */ while(lua_next(L, -2) != 0) { lua_getfield(L,-4,lua_tostring(L,-2)); if(lua_isnil(L,-1)) { lua_pop(L,1); lua_setfield(L, -4, lua_tostring(L,-2)); } else { lua_pop(L,2); } } lua_pop(L, 2); lua_pushnil(L); /* first key */ while(lua_next(L, -2) != 0) { lua_getfield(L,-4,lua_tostring(L,-2)); if(lua_isnil(L,-1)) { lua_pop(L,1); lua_setfield(L, -4, lua_tostring(L,-2)); } else { lua_pop(L,2); } } lua_pop(L, 2); }
static void gpointer_tofunc(lua_State *L, luaA_Type type_id, void *cout, int index) { if(!dt_lua_isa_type(L,index,type_id)) { char error_msg[256]; snprintf(error_msg,sizeof(error_msg),"%s expected",luaA_typename(L,type_id)); luaL_argerror(L,index,error_msg); } gpointer* udata = lua_touserdata(L,index); memcpy(cout, udata, sizeof(gpointer)); if(!*udata) { luaL_error(L,"Attempting to access of type %s after its destruction\n",luaA_typename(L,type_id)); } }
void dt_lua_type_setmetafield_type(lua_State*L,luaA_Type type_id,const char* method_name) { luaL_getmetatable(L, luaA_typename(L, type_id)); lua_pushvalue(L,-2); lua_setfield(L, -2, method_name); lua_pop(L, 2); // pop the metatable and the value }
static int gpointer_pushfunc(lua_State *L, luaA_Type type_id, const void *cin) { gpointer singleton = *(gpointer *)cin; if(!singleton) { lua_pushnil(L); return 1; } luaL_getsubtable(L, LUA_REGISTRYINDEX, "dt_lua_gpointer_values"); lua_pushlightuserdata(L, singleton); lua_gettable(L, -2); if(lua_isnoneornil(L, -1)) { lua_pop(L, 1); gpointer *udata = lua_newuserdata(L, sizeof(gpointer)); lua_newtable(L); lua_setuservalue(L, -2); *udata = singleton; luaL_setmetatable(L, luaA_typename(L, type_id)); lua_pushlightuserdata(L, singleton); lua_pushvalue(L, -2); lua_settable(L, -4); if(luaL_getmetafield(L, -1, "__init")) { lua_pushvalue(L, -2); // the new alocated object lua_pushlightuserdata(L, (void *)cin); // forced to cast.. lua_call(L, 2, 0); } } lua_remove(L, -2); //dt_lua_gpointer_values return 1; }
/** Enhanced type() function which recognize awesome objects. * \param L The Lua VM state. * \return The number of arguments pushed on the stack. */ static int luaAe_type(lua_State *L) { luaL_checkany(L, 1); lua_pushstring(L, luaA_typename(L, 1)); return 1; }
void dt_lua_type_register_const_type(lua_State *L, luaA_Type type_id, const char *name) { luaL_getmetatable(L, luaA_typename(L, type_id)); // gets the metatable since it's supposed to exist luaL_getsubtable(L, -1, "__get"); lua_pushvalue(L, -3); lua_setfield(L, -2, name); lua_pop(L, 3); }
static void int_tofunc(lua_State *L, luaA_Type type_id, void *cout, int index) { if(!dt_lua_isa_type(L,index,type_id)) { char error_msg[256]; snprintf(error_msg,sizeof(error_msg),"%s expected",luaA_typename(L,type_id)); luaL_argerror(L,index,error_msg); } void* udata = lua_touserdata(L,index); memcpy(cout, udata, sizeof(int)); }
void dt_lua_type_setmetafield_type(lua_State*L,luaA_Type type_id,const char* method_name) { // These metafields should never be overridden by user code if( !strcmp(method_name,"__index") || !strcmp(method_name,"__newindex") || !strcmp(method_name,"__number_index") || !strcmp(method_name,"__number_newindex") || !strcmp(method_name,"__pairs") || !strcmp(method_name,"__ipairs") || !strcmp(method_name,"__next") || !strcmp(method_name,"__inext") || !strcmp(method_name,"__get") || !strcmp(method_name,"__set") || !strcmp(method_name,"__len") || !strcmp(method_name,"__luaA_Type") || !strcmp(method_name,"__luaA_TypeName") || !strcmp(method_name,"__luaA_ParentMetatable") || !strcmp(method_name,"__init") || !strcmp(method_name,"__values") || !strcmp(method_name,"__singleton") || !strcmp(method_name,"__pusher") || !strcmp(method_name,"__getter") || !strcmp(method_name,"__mode") || 0) { luaL_error(L,"non-core lua code is not allowed to change meta-field %s\n",method_name); } else if(!strcmp(method_name,"__tostring")) { luaL_getmetatable(L, luaA_typename(L, type_id)); lua_pushvalue(L,-2); lua_setfield(L, -2, "__real_tostring"); lua_pop(L, 2); // pop the metatable and the value return; } else { //printf("metafield not handled :%s\n",method_name); } luaL_getmetatable(L, luaA_typename(L, type_id)); lua_pushvalue(L,-2); lua_setfield(L, -2, method_name); lua_pop(L, 2); // pop the metatable and the value }
void dt_lua_widget_register_gtk_callback_type(lua_State *L,luaA_Type type_id,const char* signal_name, const char* lua_name,GCallback callback) { lua_pushstring(L,signal_name); lua_pushcclosure(L,gtk_signal_member,1); dt_lua_type_register_type(L, type_id, lua_name); luaL_newmetatable(L, luaA_typename(L, type_id)); lua_getfield(L,-1,"__gtk_signals"); lua_pushlightuserdata(L,callback); lua_setfield(L,-2,signal_name); lua_pop(L,2); }
void dt_lua_register_format_type(lua_State* L, dt_imageio_module_format_t* module, luaA_Type type_id) { dt_lua_type_register_parent_type(L,type_id,luaA_type_find(L,"dt_imageio_module_format_t")); luaL_getmetatable(L,luaA_typename(L,type_id)); lua_pushlightuserdata(L,module); lua_setfield(L,-2,"__associated_object"); lua_pop(L,1); // pop the metatable // add to the table lua_pushlightuserdata(L,module); lua_pushcclosure(L,get_format_params,1); dt_lua_register_module_entry(L,-1,"format",module->plugin_name); lua_pop(L,1); };
gboolean dt_lua_typeisa_type(lua_State *L, luaA_Type obj_type, luaA_Type type_id) { if(obj_type == type_id) return true; luaL_getmetatable(L, luaA_typename(L, obj_type)); lua_getfield(L, -1, "__luaA_ParentMetatable"); if(lua_isnil(L, -1)) { lua_pop(L, 2); return false; } lua_getfield(L, -1, "__luaA_Type"); int parent_type = luaL_checkinteger(L, -1); lua_pop(L, 3); return dt_lua_typeisa_type(L, parent_type, type_id); }
void dt_lua_type_gpointer_alias_type(lua_State*L,luaA_Type type_id,void* pointer,void* alias) { luaL_getsubtable(L, LUA_REGISTRYINDEX, "dt_lua_gpointer_values"); lua_pushlightuserdata(L, pointer); lua_gettable(L, -2); if(lua_isnoneornil(L, -1)) { luaL_error(L,"Adding an alias to an unknown object for type %s",luaA_typename(L,type_id)); } lua_pushlightuserdata(L,alias); lua_insert(L,-2); lua_settable(L,-3); lua_pop(L,1); }
void dt_lua_type_register_number_const_type(lua_State *L, luaA_Type type_id) { luaL_getmetatable(L, luaA_typename(L, type_id)); // gets the metatable since it's supposed to exist lua_pushvalue(L, -2); lua_setfield(L, -2, "__number_index"); if(!lua_isnil(L, -3)) { lua_pushvalue(L, -3); lua_setfield(L, -2, "__len"); lua_pushcfunction(L, autotype_ipairs); lua_setfield(L, -2, "__ipairs"); lua_pushcfunction(L, autotype_inext); lua_setfield(L, -2, "__inext"); } lua_pop(L, 3); }
static int full_pushfunc(lua_State *L, luaA_Type type_id, const void *cin) { size_t type_size = luaA_typesize(L, type_id); void *udata = lua_newuserdata(L, type_size); lua_newtable(L); lua_setuservalue(L, -2); if(cin) { memcpy(udata, cin, type_size); } else { memset(udata, 0, type_size); } luaL_setmetatable(L, luaA_typename(L, type_id)); if(luaL_getmetafield(L, -1, "__init")) { lua_pushvalue(L, -2); // the new alocated object lua_pushlightuserdata(L, (void *)cin); // forced to cast.. lua_call(L, 2, 0); } return 1; }