Replace worldlist by generic filterlist implementation

This commit is contained in:
sapier 2013-07-14 13:19:37 +02:00 committed by PilzAdam
parent 5c7ecdb7c5
commit 868f35e27a
2 changed files with 178 additions and 127 deletions

@ -10,6 +10,7 @@ dofile(scriptpath .. DIR_DELIM .. "gamemgr.lua")
local menu = {} local menu = {}
local tabbuilder = {} local tabbuilder = {}
local menubar = {} local menubar = {}
local worldlist = nil
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function render_favourite(spec,render_details) function render_favourite(spec,render_details)
@ -166,7 +167,7 @@ function menu.update_gametype()
local gamedetails = menu.lastgame() local gamedetails = menu.lastgame()
engine.set_topleft_text(gamedetails.name) engine.set_topleft_text(gamedetails.name)
worldlist.set_gamefilter(gamedetails.id) filterlist.set_filtercriteria(worldlist,gamedetails.id)
--background --background
local background_set = false local background_set = false
@ -208,7 +209,7 @@ end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function menu.reset_gametype() function menu.reset_gametype()
worldlist.set_gamefilter(nil) filterlist.set_filtercriteria(worldlist,nil)
menu.game_last_check = nil menu.game_last_check = nil
local path_background_texture = menu.basetexturedir .. "menu_background.png" local path_background_texture = menu.basetexturedir .. "menu_background.png"
@ -246,6 +247,27 @@ end
function init_globals() function init_globals()
--init gamedata --init gamedata
gamedata.worldindex = 0 gamedata.worldindex = 0
worldlist = filterlist.create(
engine.get_worlds,
compare_worlds,
function(element,uid)
if element.name == uid then
return true
end
return false
end, --unique id compare fct
function(element,gameid)
if element.gameid == gameid then
return true
end
return false
end --filter fct
)
filterlist.add_sort_mechanism(worldlist,"alphabetic",sort_worlds_alphabetic)
filterlist.set_sortmode(worldlist,"alphabetic")
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@ -309,7 +331,7 @@ end
function menu.render_world_list() function menu.render_world_list()
local retval = "" local retval = ""
local current_worldlist = worldlist.get_list() local current_worldlist = filterlist.get_list(worldlist)
for i,v in ipairs(current_worldlist) do for i,v in ipairs(current_worldlist) do
if retval ~= "" then if retval ~= "" then
@ -371,7 +393,7 @@ end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function menu.update_last_game() function menu.update_last_game()
local current_world = worldlist.get_raw_world( local current_world = filterlist.get_raw_element(worldlist,
engine.setting_get("mainmenu_last_selected_world") engine.setting_get("mainmenu_last_selected_world")
) )
@ -397,17 +419,17 @@ function menu.handle_key_up_down(fields,textlist,settingname)
if oldidx > 1 then if oldidx > 1 then
local newidx = oldidx -1 local newidx = oldidx -1
engine.setting_set(settingname, engine.setting_set(settingname,
worldlist.get_engine_index(newidx)) filterlist.get_engine_index(worldlist,newidx))
end end
end end
if fields["key_down"] then if fields["key_down"] then
local oldidx = engine.get_textlist_index(textlist) local oldidx = engine.get_textlist_index(textlist)
if oldidx < worldlist.size() then if oldidx < filterlist.size(worldlist) then
local newidx = oldidx + 1 local newidx = oldidx + 1
engine.setting_set(settingname, engine.setting_set(settingname,
worldlist.get_engine_index(newidx)) filterlist.get_engine_index(worldlist,newidx))
end end
end end
end end
@ -508,7 +530,7 @@ end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function tabbuilder.dialog_delete_world() function tabbuilder.dialog_delete_world()
return "label[2,2;Delete World \"" .. worldlist.get_raw_list()[menu.world_to_del].name .. "\"?]".. return "label[2,2;Delete World \"" .. filterlist.get_raw_list(worldlist)[menu.world_to_del].name .. "\"?]"..
"button[3.5,4.2;2.6,0.5;world_delete_confirm;Yes]" .. "button[3.5,4.2;2.6,0.5;world_delete_confirm;Yes]" ..
"button[6,4.2;2.8,0.5;world_delete_cancel;No]" "button[6,4.2;2.8,0.5;world_delete_cancel;No]"
end end
@ -570,7 +592,7 @@ function tabbuilder.handle_create_world_buttons(fields)
local message = nil local message = nil
if not worldlist.exists(worldname) then if not filterlist.uid_exists(worldlist,worldname) then
engine.setting_set("mg_name",fields["dd_mapgen"]) engine.setting_set("mg_name",fields["dd_mapgen"])
message = engine.create_world(worldname,gameindex) message = engine.create_world(worldname,gameindex)
else else
@ -583,9 +605,9 @@ function tabbuilder.handle_create_world_buttons(fields)
menu.last_game = gameindex menu.last_game = gameindex
engine.setting_set("main_menu_last_game_idx",gameindex) engine.setting_set("main_menu_last_game_idx",gameindex)
worldlist.refresh() filterlist.refresh(worldlist)
engine.setting_set("mainmenu_last_selected_world", engine.setting_set("mainmenu_last_selected_world",
worldlist.engine_index_by_name(worldname)) filterlist.engine_index_by_uid(worldlist,worldname))
end end
else else
gamedata.errormessage = "No worldname given or no game selected" gamedata.errormessage = "No worldname given or no game selected"
@ -608,10 +630,10 @@ function tabbuilder.handle_delete_world_buttons(fields)
if fields["world_delete_confirm"] then if fields["world_delete_confirm"] then
if menu.world_to_del > 0 and if menu.world_to_del > 0 and
menu.world_to_del <= #worldlist.get_raw_list() then menu.world_to_del <= #filterlist.get_raw_list(worldlist) then
engine.delete_world(menu.world_to_del) engine.delete_world(menu.world_to_del)
menu.world_to_del = 0 menu.world_to_del = 0
worldlist.refresh() filterlist.refresh(worldlist)
end end
end end
@ -756,7 +778,7 @@ function tabbuilder.handle_server_buttons(fields)
end end
if event.typ == "CHG" then if event.typ == "CHG" then
engine.setting_set("mainmenu_last_selected_world", engine.setting_set("mainmenu_last_selected_world",
worldlist.get_engine_index(engine.get_textlist_index("srv_worlds"))) filterlist.get_engine_index(worldlist,engine.get_textlist_index("srv_worlds")))
end end
end end
@ -783,7 +805,7 @@ function tabbuilder.handle_server_buttons(fields)
gamedata.password = fields["te_passwd"] gamedata.password = fields["te_passwd"]
gamedata.port = fields["te_serverport"] gamedata.port = fields["te_serverport"]
gamedata.address = "" gamedata.address = ""
gamedata.selected_world = worldlist.get_engine_index(selected) gamedata.selected_world = filterlist.get_engine_index(worldlist,selected)
menu.update_last_game(gamedata.selected_world) menu.update_last_game(gamedata.selected_world)
engine.start() engine.start()
@ -799,12 +821,12 @@ function tabbuilder.handle_server_buttons(fields)
if fields["world_delete"] ~= nil then if fields["world_delete"] ~= nil then
local selected = engine.get_textlist_index("srv_worlds") local selected = engine.get_textlist_index("srv_worlds")
if selected > 0 and if selected > 0 and
selected <= worldlist.size() then selected <= filterlist.size(worldlist) then
local world = worldlist.get_list()[selected] local world = filterlist.get_list(worldlist)[selected]
if world ~= nil and if world ~= nil and
world.name ~= nil and world.name ~= nil and
world.name ~= "" then world.name ~= "" then
menu.world_to_del = worldlist.get_engine_index(selected) menu.world_to_del = filterlist.get_engine_index(worldlist,selected)
tabbuilder.current_tab = "dialog_delete_world" tabbuilder.current_tab = "dialog_delete_world"
tabbuilder.is_dialog = true tabbuilder.is_dialog = true
tabbuilder.show_buttons = false tabbuilder.show_buttons = false
@ -817,7 +839,7 @@ function tabbuilder.handle_server_buttons(fields)
if fields["world_configure"] ~= nil then if fields["world_configure"] ~= nil then
selected = engine.get_textlist_index("srv_worlds") selected = engine.get_textlist_index("srv_worlds")
if selected > 0 then if selected > 0 then
modmgr.world_config_selected_world = worldlist.get_engine_index(selected) modmgr.world_config_selected_world = filterlist.get_engine_index(worldlist,selected)
if modmgr.init_worldconfig() then if modmgr.init_worldconfig() then
tabbuilder.current_tab = "dialog_configure_world" tabbuilder.current_tab = "dialog_configure_world"
tabbuilder.is_dialog = true tabbuilder.is_dialog = true
@ -897,7 +919,7 @@ function tabbuilder.handle_singleplayer_buttons(fields)
if event.typ == "CHG" then if event.typ == "CHG" then
engine.setting_set("mainmenu_last_selected_world", engine.setting_set("mainmenu_last_selected_world",
worldlist.get_engine_index(engine.get_textlist_index("sp_worlds"))) filterlist.get_engine_index(worldlist,engine.get_textlist_index("sp_worlds")))
end end
end end
@ -916,7 +938,7 @@ function tabbuilder.handle_singleplayer_buttons(fields)
fields["key_enter"] then fields["key_enter"] then
local selected = engine.get_textlist_index("sp_worlds") local selected = engine.get_textlist_index("sp_worlds")
if selected > 0 then if selected > 0 then
gamedata.selected_world = worldlist.get_engine_index(selected) gamedata.selected_world = filterlist.get_engine_index(worldlist,selected)
gamedata.singleplayer = true gamedata.singleplayer = true
menu.update_last_game(gamedata.selected_world) menu.update_last_game(gamedata.selected_world)
@ -934,12 +956,12 @@ function tabbuilder.handle_singleplayer_buttons(fields)
if fields["world_delete"] ~= nil then if fields["world_delete"] ~= nil then
local selected = engine.get_textlist_index("sp_worlds") local selected = engine.get_textlist_index("sp_worlds")
if selected > 0 and if selected > 0 and
selected <= worldlist.size() then selected <= filterlist.size(worldlist) then
local world = worldlist.get_list()[selected] local world = filterlist.get_list(worldlist)[selected]
if world ~= nil and if world ~= nil and
world.name ~= nil and world.name ~= nil and
world.name ~= "" then world.name ~= "" then
menu.world_to_del = worldlist.get_engine_index(selected) menu.world_to_del = filterlist.get_engine_index(worldlist,selected)
tabbuilder.current_tab = "dialog_delete_world" tabbuilder.current_tab = "dialog_delete_world"
tabbuilder.is_dialog = true tabbuilder.is_dialog = true
tabbuilder.show_buttons = false tabbuilder.show_buttons = false
@ -952,7 +974,7 @@ function tabbuilder.handle_singleplayer_buttons(fields)
if fields["world_configure"] ~= nil then if fields["world_configure"] ~= nil then
selected = engine.get_textlist_index("sp_worlds") selected = engine.get_textlist_index("sp_worlds")
if selected > 0 then if selected > 0 then
modmgr.world_config_selected_world = worldlist.get_engine_index(selected) modmgr.world_config_selected_world = filterlist.get_engine_index(worldlist,selected)
if modmgr.init_worldconfig() then if modmgr.init_worldconfig() then
tabbuilder.current_tab = "dialog_configure_world" tabbuilder.current_tab = "dialog_configure_world"
tabbuilder.is_dialog = true tabbuilder.is_dialog = true
@ -1102,7 +1124,7 @@ end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function tabbuilder.tab_server() function tabbuilder.tab_server()
local index = worldlist.get_current_index( local index = filterlist.get_current_index(worldlist,
tonumber(engine.setting_get("mainmenu_last_selected_world")) tonumber(engine.setting_get("mainmenu_last_selected_world"))
) )
@ -1154,7 +1176,7 @@ end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function tabbuilder.tab_singleplayer() function tabbuilder.tab_singleplayer()
local index = worldlist.get_current_index( local index = filterlist.get_current_index(worldlist,
tonumber(engine.setting_get("mainmenu_last_selected_world")) tonumber(engine.setting_get("mainmenu_last_selected_world"))
) )
@ -1300,6 +1322,7 @@ engine.event_handler = function(event)
tabbuilder.is_dialog = false tabbuilder.is_dialog = false
tabbuilder.show_buttons = true tabbuilder.show_buttons = true
tabbuilder.current_tab = engine.setting_get("main_menu_tab") tabbuilder.current_tab = engine.setting_get("main_menu_tab")
menu.update_gametype()
update_menu() update_menu()
else else
engine.close() engine.close()
@ -1313,7 +1336,6 @@ end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
init_globals() init_globals()
worldlist.init()
menu.init() menu.init()
tabbuilder.init() tabbuilder.init()
menubar.refresh() menubar.refresh()

@ -1,80 +1,105 @@
worldlist = {} --------------------------------------------------------------------------------
-- Generic implementation of a filter/sortable list --
--------------------------------------------------------------------------------
filterlist = {}
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function worldlist.refresh() function filterlist.refresh(this)
worldlist.m_raw_worldlist = engine.get_worlds() this.m_raw_list = this.m_raw_list_fct()
worldlist.process() filterlist.process(this)
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function worldlist.init() function filterlist.create(raw_fct,compare_fct,uid_match_fct,filter_fct)
worldlist.m_gamefilter = nil
worldlist.m_sortmode = "alphabetic"
worldlist.m_processed_worldlist = nil assert((raw_fct ~= nil) and (type(raw_fct) == "function"))
worldlist.m_raw_worldlist = engine.get_worlds() assert((compare_fct ~= nil) and (type(compare_fct) == "function"))
worldlist.process() 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_sortmode = "none"
this.m_sort_list = {}
this.m_processed_list = nil
this.m_raw_list = this.m_raw_list_fct()
filterlist.process(this)
return this
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function worldlist.set_gamefilter(gameid) function filterlist.add_sort_mechanism(this,name,fct)
if gameid == worldlist.m_gamefilter then this.m_sort_list[name] = fct
end
--------------------------------------------------------------------------------
function filterlist.set_filtercriteria(this,criteria)
if criteria == this.m_filtercriteria then
return return
end end
worldlist.m_gamefilter = gameid this.m_filtercriteria = criteria
worldlist.process() filterlist.process(this)
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function worldlist.get_gamefilter() function filterlist.get_filtercriteria(this)
return worldlist.m_gamefilter return this.m_filtercriteria
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
--supported sort mode "alphabetic|none" --supported sort mode "alphabetic|none"
function worldlist.set_sortmode(mode) function filterlist.set_sortmode(this,mode)
if (mode == worldlist.m_sortmode) then if (mode == this.m_sortmode) then
return return
end end
worldlist.m_sortmode = mode this.m_sortmode = mode
worldlist.process() filterlist.process(this)
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function worldlist.get_list() function filterlist.get_list(this)
return worldlist.m_processed_worldlist return this.m_processed_list
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function worldlist.get_raw_list() function filterlist.get_raw_list(this)
return worldlist.m_raw_worldlist return this.m_raw_list
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function worldlist.get_raw_world(idx) function filterlist.get_raw_element(this,idx)
if type(idx) ~= "number" then if type(idx) ~= "number" then
idx = tonumber(idx) idx = tonumber(idx)
end end
if idx ~= nil and idx > 0 and idx < #worldlist.m_raw_worldlist then if idx ~= nil and idx > 0 and idx < #this.m_raw_list then
return worldlist.m_raw_worldlist[idx] return this.m_raw_list[idx]
end end
return nil return nil
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function worldlist.get_engine_index(worldlistindex) function filterlist.get_engine_index(this,listindex)
assert(worldlist.m_processed_worldlist ~= nil) assert(this.m_processed_list ~= nil)
if worldlistindex ~= nil and worldlistindex > 0 and if listindex ~= nil and listindex > 0 and
worldlistindex <= #worldlist.m_processed_worldlist then listindex <= #this.m_processed_list then
local entry = worldlist.m_processed_worldlist[worldlistindex] local entry = this.m_processed_list[listindex]
for i,v in ipairs(worldlist.m_raw_worldlist) do for i,v in ipairs(this.m_raw_list) do
if worldlist.compare(v,entry) then if this.m_compare_fct(v,entry) then
return i return i
end end
end end
@ -84,16 +109,16 @@ function worldlist.get_engine_index(worldlistindex)
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function worldlist.get_current_index(worldlistindex) function filterlist.get_current_index(this,listindex)
assert(worldlist.m_processed_worldlist ~= nil) assert(this.m_processed_list ~= nil)
if worldlistindex ~= nil and worldlistindex > 0 and if listindex ~= nil and listindex > 0 and
worldlistindex <= #worldlist.m_raw_worldlist then listindex <= #this.m_raw_list then
local entry = worldlist.m_raw_worldlist[worldlistindex] local entry = this.m_raw_list[listindex]
for i,v in ipairs(worldlist.m_processed_worldlist) do for i,v in ipairs(this.m_processed_list) do
if worldlist.compare(v,entry) then if this.m_compare_fct(v,entry) then
return i return i
end end
end end
@ -103,37 +128,82 @@ function worldlist.get_current_index(worldlistindex)
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function worldlist.process() function filterlist.process(this)
assert(worldlist.m_raw_worldlist ~= nil) assert(this.m_raw_list ~= nil)
if worldlist.m_sortmode == "none" and if this.m_sortmode == "none" and
worldlist.m_gamefilter == nil then this.m_filtercriteria == nil then
worldlist.m_processed_worldlist = worldlist.m_raw_worldlist this.m_processed_list = this.m_raw_list
return return
end end
worldlist.m_processed_worldlist = {} this.m_processed_list = {}
for i,v in ipairs(worldlist.m_raw_worldlist) do for i,v in ipairs(this.m_raw_list) do
if worldlist.m_gamefilter == nil or if this.m_filtercriteria == nil or
v.gameid == worldlist.m_gamefilter then this.m_filter_fct(v,this.m_filtercriteria) then
table.insert(worldlist.m_processed_worldlist,v) table.insert(this.m_processed_list,v)
end end
end end
if worldlist.m_sortmode == "none" then if this.m_sortmode == "none" then
return return
end end
if worldlist.m_sortmode == "alphabetic" then if this.m_sort_list[this.m_sortmode] ~= nil and
worldlist.sort_alphabetic() type(this.m_sort_list[this.m_sortmode]) == "function" then
end
this.m_sort_list[this.m_sortmode](this)
end
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function worldlist.compare(world1,world2) 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 if world1.path ~= world2.path then
return false return false
@ -151,50 +221,9 @@ function worldlist.compare(world1,world2)
end end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function worldlist.size() function sort_worlds_alphabetic(this)
if worldlist.m_processed_worldlist == nil then
return 0
end
return #worldlist.m_processed_worldlist table.sort(this.m_processed_list, function(a, b)
end
--------------------------------------------------------------------------------
function worldlist.exists(worldname)
for i,v in ipairs(worldlist.m_raw_worldlist) do
if v.name == worldname then
return true
end
end
return false
end
--------------------------------------------------------------------------------
function worldlist.engine_index_by_name(worldname)
local worldcount = 0
local worldidx = 0
for i,v in ipairs(worldlist.m_raw_worldlist) do
if v.name == worldname then
worldcount = worldcount +1
worldidx = i
end
end
-- If there are more worlds than one with same name we can't decide which
-- one is meant. This shouldn't be possible but just for sure.
if worldcount > 1 then
worldidx=0
end
return worldidx
end
--------------------------------------------------------------------------------
function worldlist.sort_alphabetic()
table.sort(worldlist.m_processed_worldlist, function(a, b)
local n1 = a.name local n1 = a.name
local n2 = b.name local n2 = b.name
local count = math.min(#n1, #n2) local count = math.min(#n1, #n2)