From: sapier Date: Mon, 15 Jul 2013 21:02:18 +0000 (+0200) Subject: filterlist api cleanup X-Git-Url: http://81.2.79.47:8989/gitweb/?a=commitdiff_plain;h=8a1658ec3e2d95b3646d5244120a07b8fd5c9158;p=zefram%2Fminetest%2Fminetest_engine.git filterlist api cleanup --- diff --git a/builtin/filterlist.lua b/builtin/filterlist.lua new file mode 100644 index 00000000..391accee --- /dev/null +++ b/builtin/filterlist.lua @@ -0,0 +1,239 @@ +-------------------------------------------------------------------------------- +-- Generic implementation of a filter/sortable list -- +-------------------------------------------------------------------------------- +filterlist = {} + +-------------------------------------------------------------------------------- +function filterlist.refresh(this) + this.m_raw_list = this.m_raw_list_fct(this.m_fetch_param) + filterlist.process(this) +end + +-------------------------------------------------------------------------------- +function filterlist.create(raw_fct,compare_fct,uid_match_fct,filter_fct,fetch_param) + + assert((raw_fct ~= nil) and (type(raw_fct) == "function")) + assert((compare_fct ~= nil) and (type(compare_fct) == "function")) + + local this = {} + + this.m_raw_list_fct = raw_fct + this.m_compare_fct = compare_fct + this.m_filter_fct = filter_fct + this.m_uid_match_fct = uid_match_fct + + this.m_filtercriteria = nil + this.m_fetch_param = fetch_param + + this.m_sortmode = "none" + this.m_sort_list = {} + + this.m_processed_list = nil + this.m_raw_list = this.m_raw_list_fct(this.m_fetch_param) + + filterlist.process(this) + + return this +end + +-------------------------------------------------------------------------------- +function filterlist.add_sort_mechanism(this,name,fct) + this.m_sort_list[name] = fct +end + +-------------------------------------------------------------------------------- +function filterlist.set_filtercriteria(this,criteria) + if criteria == this.m_filtercriteria and + type(criteria) ~= "table" then + return + end + this.m_filtercriteria = criteria + filterlist.process(this) +end + +-------------------------------------------------------------------------------- +function filterlist.get_filtercriteria(this) + return this.m_filtercriteria +end + +-------------------------------------------------------------------------------- +--supported sort mode "alphabetic|none" +function filterlist.set_sortmode(this,mode) + if (mode == this.m_sortmode) then + return + end + this.m_sortmode = mode + filterlist.process(this) +end + +-------------------------------------------------------------------------------- +function filterlist.get_list(this) + return this.m_processed_list +end + +-------------------------------------------------------------------------------- +function filterlist.get_raw_list(this) + return this.m_raw_list +end + +-------------------------------------------------------------------------------- +function filterlist.get_raw_element(this,idx) + if type(idx) ~= "number" then + idx = tonumber(idx) + end + + if idx ~= nil and idx > 0 and idx < #this.m_raw_list then + return this.m_raw_list[idx] + end + + return nil +end + +-------------------------------------------------------------------------------- +function filterlist.get_raw_index(this,listindex) + assert(this.m_processed_list ~= nil) + + if listindex ~= nil and listindex > 0 and + listindex <= #this.m_processed_list then + local entry = this.m_processed_list[listindex] + + for i,v in ipairs(this.m_raw_list) do + + if this.m_compare_fct(v,entry) then + return i + end + end + end + + return 0 +end + +-------------------------------------------------------------------------------- +function filterlist.get_current_index(this,listindex) + assert(this.m_processed_list ~= nil) + + if listindex ~= nil and listindex > 0 and + listindex <= #this.m_raw_list then + local entry = this.m_raw_list[listindex] + + for i,v in ipairs(this.m_processed_list) do + + if this.m_compare_fct(v,entry) then + return i + end + end + end + + return 0 +end + +-------------------------------------------------------------------------------- +function filterlist.process(this) + assert(this.m_raw_list ~= nil) + + if this.m_sortmode == "none" and + this.m_filtercriteria == nil then + this.m_processed_list = this.m_raw_list + return + end + + this.m_processed_list = {} + + for k,v in pairs(this.m_raw_list) do + if this.m_filtercriteria == nil or + this.m_filter_fct(v,this.m_filtercriteria) then + table.insert(this.m_processed_list,v) + end + end + + if this.m_sortmode == "none" then + return + end + + if this.m_sort_list[this.m_sortmode] ~= nil and + type(this.m_sort_list[this.m_sortmode]) == "function" then + + this.m_sort_list[this.m_sortmode](this) + end +end + +-------------------------------------------------------------------------------- +function filterlist.size(this) + if this.m_processed_list == nil then + return 0 + end + + return #this.m_processed_list +end + +-------------------------------------------------------------------------------- +function filterlist.uid_exists_raw(this,uid) + for i,v in ipairs(this.m_raw_list) do + if this.m_uid_match_fct(v,uid) then + return true + end + end + return false +end + +-------------------------------------------------------------------------------- +function filterlist.raw_index_by_uid(this, uid) + local elementcount = 0 + local elementidx = 0 + for i,v in ipairs(this.m_raw_list) do + if this.m_uid_match_fct(v,uid) then + elementcount = elementcount +1 + elementidx = i + end + end + + + -- If there are more elements than one with same name uid can't decide which + -- one is meant. This shouldn't be possible but just for sure. + if elementcount > 1 then + elementidx=0 + end + + return elementidx +end + +-------------------------------------------------------------------------------- +-- COMMON helper functions -- +-------------------------------------------------------------------------------- + +-------------------------------------------------------------------------------- +function compare_worlds(world1,world2) + + if world1.path ~= world2.path then + return false + end + + if world1.name ~= world2.name then + return false + end + + if world1.gameid ~= world2.gameid then + return false + end + + return true +end + +-------------------------------------------------------------------------------- +function sort_worlds_alphabetic(this) + + table.sort(this.m_processed_list, function(a, b) + local n1 = a.name + local n2 = b.name + local count = math.min(#n1, #n2) + + for i=1,count do + if n1:sub(i, i):lower() < n2:sub(i, i):lower() then + return true + elseif n1:sub(i, i):lower() > n2:sub(i, i):lower() then + return false + end + end + return (#n1 <= #n2) + end) +end diff --git a/builtin/mainmenu.lua b/builtin/mainmenu.lua index 726ccf7d..be065458 100644 --- a/builtin/mainmenu.lua +++ b/builtin/mainmenu.lua @@ -7,7 +7,7 @@ mt_color_blue = "#0000DD" mt_color_green = "#00DD00" mt_color_dark_green = "#003300" -dofile(scriptpath .. DIR_DELIM .. "mainmenu_worldlist.lua") +dofile(scriptpath .. DIR_DELIM .. "filterlist.lua") dofile(scriptpath .. DIR_DELIM .. "modmgr.lua") dofile(scriptpath .. DIR_DELIM .. "modstore.lua") dofile(scriptpath .. DIR_DELIM .. "gamemgr.lua") @@ -430,7 +430,7 @@ function menu.handle_key_up_down(fields,textlist,settingname) if oldidx > 1 then local newidx = oldidx -1 engine.setting_set(settingname, - filterlist.get_engine_index(worldlist,newidx)) + filterlist.get_raw_index(worldlist,newidx)) end end @@ -440,7 +440,7 @@ function menu.handle_key_up_down(fields,textlist,settingname) if oldidx < filterlist.size(worldlist) then local newidx = oldidx + 1 engine.setting_set(settingname, - filterlist.get_engine_index(worldlist,newidx)) + filterlist.get_raw_index(worldlist,newidx)) end end end @@ -618,7 +618,7 @@ function tabbuilder.handle_create_world_buttons(fields) filterlist.refresh(worldlist) engine.setting_set("mainmenu_last_selected_world", - filterlist.engine_index_by_uid(worldlist,worldname)) + filterlist.raw_index_by_uid(worldlist,worldname)) end else gamedata.errormessage = "No worldname given or no game selected" @@ -789,7 +789,7 @@ function tabbuilder.handle_server_buttons(fields) end if event.typ == "CHG" then engine.setting_set("mainmenu_last_selected_world", - filterlist.get_engine_index(worldlist,engine.get_textlist_index("srv_worlds"))) + filterlist.get_raw_index(worldlist,engine.get_textlist_index("srv_worlds"))) end end @@ -816,7 +816,7 @@ function tabbuilder.handle_server_buttons(fields) gamedata.password = fields["te_passwd"] gamedata.port = fields["te_serverport"] gamedata.address = "" - gamedata.selected_world = filterlist.get_engine_index(worldlist,selected) + gamedata.selected_world = filterlist.get_raw_index(worldlist,selected) menu.update_last_game(gamedata.selected_world) engine.start() @@ -837,7 +837,7 @@ function tabbuilder.handle_server_buttons(fields) if world ~= nil and world.name ~= nil and world.name ~= "" then - menu.world_to_del = filterlist.get_engine_index(worldlist,selected) + menu.world_to_del = filterlist.get_raw_index(worldlist,selected) tabbuilder.current_tab = "dialog_delete_world" tabbuilder.is_dialog = true tabbuilder.show_buttons = false @@ -850,7 +850,7 @@ function tabbuilder.handle_server_buttons(fields) if fields["world_configure"] ~= nil then selected = engine.get_textlist_index("srv_worlds") if selected > 0 then - modmgr.world_config_selected_world = filterlist.get_engine_index(worldlist,selected) + modmgr.world_config_selected_world = filterlist.get_raw_index(worldlist,selected) if modmgr.init_worldconfig() then tabbuilder.current_tab = "dialog_configure_world" tabbuilder.is_dialog = true @@ -930,7 +930,7 @@ function tabbuilder.handle_singleplayer_buttons(fields) if event.typ == "CHG" then engine.setting_set("mainmenu_last_selected_world", - filterlist.get_engine_index(worldlist,engine.get_textlist_index("sp_worlds"))) + filterlist.get_raw_index(worldlist,engine.get_textlist_index("sp_worlds"))) end end @@ -949,7 +949,7 @@ function tabbuilder.handle_singleplayer_buttons(fields) fields["key_enter"] then local selected = engine.get_textlist_index("sp_worlds") if selected > 0 then - gamedata.selected_world = filterlist.get_engine_index(worldlist,selected) + gamedata.selected_world = filterlist.get_raw_index(worldlist,selected) gamedata.singleplayer = true menu.update_last_game(gamedata.selected_world) @@ -972,7 +972,7 @@ function tabbuilder.handle_singleplayer_buttons(fields) if world ~= nil and world.name ~= nil and world.name ~= "" then - menu.world_to_del = filterlist.get_engine_index(worldlist,selected) + menu.world_to_del = filterlist.get_raw_index(worldlist,selected) tabbuilder.current_tab = "dialog_delete_world" tabbuilder.is_dialog = true tabbuilder.show_buttons = false @@ -985,7 +985,7 @@ function tabbuilder.handle_singleplayer_buttons(fields) if fields["world_configure"] ~= nil then selected = engine.get_textlist_index("sp_worlds") if selected > 0 then - modmgr.world_config_selected_world = filterlist.get_engine_index(worldlist,selected) + modmgr.world_config_selected_world = filterlist.get_raw_index(worldlist,selected) if modmgr.init_worldconfig() then tabbuilder.current_tab = "dialog_configure_world" tabbuilder.is_dialog = true diff --git a/builtin/mainmenu_worldlist.lua b/builtin/mainmenu_worldlist.lua deleted file mode 100644 index a0428dc8..00000000 --- a/builtin/mainmenu_worldlist.lua +++ /dev/null @@ -1,239 +0,0 @@ --------------------------------------------------------------------------------- --- Generic implementation of a filter/sortable list -- --------------------------------------------------------------------------------- -filterlist = {} - --------------------------------------------------------------------------------- -function filterlist.refresh(this) - this.m_raw_list = this.m_raw_list_fct(this.m_fetch_param) - filterlist.process(this) -end - --------------------------------------------------------------------------------- -function filterlist.create(raw_fct,compare_fct,uid_match_fct,filter_fct,fetch_param) - - assert((raw_fct ~= nil) and (type(raw_fct) == "function")) - assert((compare_fct ~= nil) and (type(compare_fct) == "function")) - - local this = {} - - this.m_raw_list_fct = raw_fct - this.m_compare_fct = compare_fct - this.m_filter_fct = filter_fct - this.m_uid_match_fct = uid_match_fct - - this.m_filtercriteria = nil - this.m_fetch_param = fetch_param - - this.m_sortmode = "none" - this.m_sort_list = {} - - this.m_processed_list = nil - this.m_raw_list = this.m_raw_list_fct(this.m_fetch_param) - - filterlist.process(this) - - return this -end - --------------------------------------------------------------------------------- -function filterlist.add_sort_mechanism(this,name,fct) - this.m_sort_list[name] = fct -end - --------------------------------------------------------------------------------- -function filterlist.set_filtercriteria(this,criteria) - if criteria == this.m_filtercriteria and - type(criteria) ~= "table" then - return - end - this.m_filtercriteria = criteria - filterlist.process(this) -end - --------------------------------------------------------------------------------- -function filterlist.get_filtercriteria(this) - return this.m_filtercriteria -end - --------------------------------------------------------------------------------- ---supported sort mode "alphabetic|none" -function filterlist.set_sortmode(this,mode) - if (mode == this.m_sortmode) then - return - end - this.m_sortmode = mode - filterlist.process(this) -end - --------------------------------------------------------------------------------- -function filterlist.get_list(this) - return this.m_processed_list -end - --------------------------------------------------------------------------------- -function filterlist.get_raw_list(this) - return this.m_raw_list -end - --------------------------------------------------------------------------------- -function filterlist.get_raw_element(this,idx) - if type(idx) ~= "number" then - idx = tonumber(idx) - end - - if idx ~= nil and idx > 0 and idx < #this.m_raw_list then - return this.m_raw_list[idx] - end - - return nil -end - --------------------------------------------------------------------------------- -function filterlist.get_engine_index(this,listindex) - assert(this.m_processed_list ~= nil) - - if listindex ~= nil and listindex > 0 and - listindex <= #this.m_processed_list then - local entry = this.m_processed_list[listindex] - - for i,v in ipairs(this.m_raw_list) do - - if this.m_compare_fct(v,entry) then - return i - end - end - end - - return 0 -end - --------------------------------------------------------------------------------- -function filterlist.get_current_index(this,listindex) - assert(this.m_processed_list ~= nil) - - if listindex ~= nil and listindex > 0 and - listindex <= #this.m_raw_list then - local entry = this.m_raw_list[listindex] - - for i,v in ipairs(this.m_processed_list) do - - if this.m_compare_fct(v,entry) then - return i - end - end - end - - return 0 -end - --------------------------------------------------------------------------------- -function filterlist.process(this) - assert(this.m_raw_list ~= nil) - - if this.m_sortmode == "none" and - this.m_filtercriteria == nil then - this.m_processed_list = this.m_raw_list - return - end - - this.m_processed_list = {} - - for k,v in pairs(this.m_raw_list) do - if this.m_filtercriteria == nil or - this.m_filter_fct(v,this.m_filtercriteria) then - table.insert(this.m_processed_list,v) - end - end - - if this.m_sortmode == "none" then - return - end - - if this.m_sort_list[this.m_sortmode] ~= nil and - type(this.m_sort_list[this.m_sortmode]) == "function" then - - this.m_sort_list[this.m_sortmode](this) - end -end - --------------------------------------------------------------------------------- -function filterlist.size(this) - if this.m_processed_list == nil then - return 0 - end - - return #this.m_processed_list -end - --------------------------------------------------------------------------------- -function filterlist.uid_exists_raw(this,uid) - for i,v in ipairs(this.m_raw_list) do - if this.m_uid_match_fct(v,uid) then - return true - end - end - return false -end - --------------------------------------------------------------------------------- -function filterlist.engine_index_by_uid(this, uid) - local elementcount = 0 - local elementidx = 0 - for i,v in ipairs(this.m_raw_list) do - if this.m_uid_match_fct(v,uid) then - elementcount = elementcount +1 - elementidx = i - end - end - - - -- If there are more elements than one with same name uid can't decide which - -- one is meant. This shouldn't be possible but just for sure. - if elementcount > 1 then - elementidx=0 - end - - return elementidx -end - --------------------------------------------------------------------------------- --- COMMON helper functions -- --------------------------------------------------------------------------------- - --------------------------------------------------------------------------------- -function compare_worlds(world1,world2) - - if world1.path ~= world2.path then - return false - end - - if world1.name ~= world2.name then - return false - end - - if world1.gameid ~= world2.gameid then - return false - end - - return true -end - --------------------------------------------------------------------------------- -function sort_worlds_alphabetic(this) - - table.sort(this.m_processed_list, function(a, b) - local n1 = a.name - local n2 = b.name - local count = math.min(#n1, #n2) - - for i=1,count do - if n1:sub(i, i):lower() < n2:sub(i, i):lower() then - return true - elseif n1:sub(i, i):lower() > n2:sub(i, i):lower() then - return false - end - end - return (#n1 <= #n2) - end) -end diff --git a/builtin/modmgr.lua b/builtin/modmgr.lua index de14076b..a0118750 100644 --- a/builtin/modmgr.lua +++ b/builtin/modmgr.lua @@ -973,7 +973,7 @@ function modmgr.mod_exists(basename) modmgr.refresh_globals() end - if filterlist.engine_index_by_uid(modmgr.global_mods,basename) > 0 then + if filterlist.raw_index_by_uid(modmgr.global_mods,basename) > 0 then return true end