void dt_lua_register_type_callback_type_typeid(lua_State* L,const char* type_name,lua_CFunction index, lua_CFunction newindex,const char* struct_type_name) { luaL_getmetatable(L,type_name); // gets the metatable since it's supposed to exist luaL_getsubtable(L,-1,"__get"); luaL_getsubtable(L,-2,"__set"); if(!index && !newindex) { index = lautoc_struct_index; newindex = lautoc_struct_newindex; } const char* member = luaA_struct_next_member_name_typeid(L,luaA_type_find(struct_type_name),LUAA_INVALID_MEMBER_NAME); while(member != LUAA_INVALID_MEMBER_NAME) { lua_pushnumber(L,luaA_type_find(struct_type_name)); lua_pushcclosure(L,index,1); lua_setfield(L,-3,member); if(newindex) { lua_pushnumber(L,luaA_type_find(struct_type_name)); lua_pushcclosure(L,newindex,1); lua_setfield(L,-2,member); } member = luaA_struct_next_member_name_typeid(L,luaA_type_find(struct_type_name),member); } lua_pop(L,3); }
void dt_lua_lib_register(lua_State *L, dt_lib_module_t *module) { dt_lua_module_entry_new_singleton(L, "lib", module->plugin_name, module); int my_type = dt_lua_module_entry_get_type(L, "lib", module->plugin_name); dt_lua_type_register_parent_type(L, my_type, luaA_type_find(L, "dt_lib_module_t")); lua_pushcfunction(L, lib_tostring); dt_lua_type_setmetafield_type(L,my_type,"__tostring"); };
static gboolean alien_job_dispatch (GSource* source, GSourceFunc callback, gpointer user_data) { gpointer message; message = g_async_queue_try_pop (darktable.lua_state.alien_job_queue); if (message == NULL) { return TRUE; } async_call_data* data = (async_call_data*)message; dt_lua_lock(); lua_State* L= darktable.lua_state.state; lua_State *new_thread = lua_newthread(L); int reference = save_thread(L); lua_pushlightuserdata(new_thread,data->cb); lua_pushlightuserdata(new_thread,data->cb_data); lua_pushinteger(new_thread,data->nresults); lua_pushcfunction(new_thread,data->pusher); GList* cur_elt = data->extra; while(cur_elt) { GList * type_type_elt = cur_elt; cur_elt = g_list_next(cur_elt); GList * type_elt = cur_elt; cur_elt = g_list_next(cur_elt); GList * data_elt = cur_elt; cur_elt = g_list_next(cur_elt); switch(GPOINTER_TO_INT(type_type_elt->data)) { case LUA_ASYNC_TYPEID_WITH_FREE: // skip the destructor cur_elt = g_list_next(cur_elt); // do not break case LUA_ASYNC_TYPEID: luaA_push_type(new_thread,GPOINTER_TO_INT(type_elt->data),data_elt->data); break; case LUA_ASYNC_TYPENAME_WITH_FREE: // skip the destructor cur_elt = g_list_next(cur_elt); // do not break case LUA_ASYNC_TYPENAME: luaA_push_type(new_thread,luaA_type_find(L,type_elt->data),&data_elt->data); break; case LUA_ASYNC_DONE: default: // should never happen g_assert(false); break; } } run_async_thread(L,reference); dt_lua_unlock(); alien_job_destroy(data); return G_SOURCE_CONTINUE; }
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); };
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 }
static int32_t async_callback_job(dt_job_t *job) { dt_lua_lock(); lua_State* L= darktable.lua_state.state; async_call_data* data = (async_call_data*)dt_control_job_get_params(job); lua_pushcfunction(L,data->pusher); int nargs =0; GList* cur_elt = data->extra; while(cur_elt) { GList * type_type_elt = cur_elt; cur_elt = g_list_next(cur_elt); GList * type_elt = cur_elt; cur_elt = g_list_next(cur_elt); GList * data_elt = cur_elt; cur_elt = g_list_next(cur_elt); switch(GPOINTER_TO_INT(type_type_elt->data)) { case LUA_ASYNC_TYPEID_WITH_FREE: // skip the destructor cur_elt = g_list_next(cur_elt); // do not break case LUA_ASYNC_TYPEID: luaA_push_type(L,GPOINTER_TO_INT(type_elt->data),data_elt->data); break; case LUA_ASYNC_TYPENAME_WITH_FREE: // skip the destructor cur_elt = g_list_next(cur_elt); // do not break case LUA_ASYNC_TYPENAME: luaA_push_type(L,luaA_type_find(L,type_elt->data),&data_elt->data); break; case LUA_ASYNC_DONE: default: // should never happen g_assert(false); break; } nargs++; } dt_lua_do_chunk_silent(L,nargs,0); dt_lua_redraw_screen(); dt_lua_unlock(); return 0; }
void dt_lua_widget_trigger_callback_glist(lua_State*L,lua_widget object,const char* name,GList*extra) { luaA_push_type(L,object->type->associated_type,&object); lua_getuservalue(L,-1); lua_getfield(L,-1,name); if(! lua_isnil(L,-1)) { lua_pushvalue(L,-3); GList* cur_elt = extra; int nargs = 1; while(cur_elt) { const char* next_type = cur_elt->data; cur_elt = g_list_next(cur_elt); luaA_push_type(L,luaA_type_find(L,next_type),&cur_elt->data); nargs++; cur_elt = g_list_next(cur_elt); } dt_lua_do_chunk(L,nargs,0); } dt_lua_redraw_screen(); g_list_free(extra); lua_pop(L,2); }