local menu = {}
local tabbuilder = {}
local menubar = {}
+local worldlist = nil
--------------------------------------------------------------------------------
function render_favourite(spec,render_details)
local gamedetails = menu.lastgame()
engine.set_topleft_text(gamedetails.name)
- worldlist.set_gamefilter(gamedetails.id)
+ filterlist.set_filtercriteria(worldlist,gamedetails.id)
--background
local background_set = false
--------------------------------------------------------------------------------
function menu.reset_gametype()
- worldlist.set_gamefilter(nil)
+ filterlist.set_filtercriteria(worldlist,nil)
menu.game_last_check = nil
local path_background_texture = menu.basetexturedir .. "menu_background.png"
function init_globals()
--init gamedata
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
--------------------------------------------------------------------------------
function menu.render_world_list()
local retval = ""
- local current_worldlist = worldlist.get_list()
+ local current_worldlist = filterlist.get_list(worldlist)
for i,v in ipairs(current_worldlist) do
if retval ~= "" then
--------------------------------------------------------------------------------
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")
)
if oldidx > 1 then
local newidx = oldidx -1
engine.setting_set(settingname,
- worldlist.get_engine_index(newidx))
+ filterlist.get_engine_index(worldlist,newidx))
end
end
if fields["key_down"] then
local oldidx = engine.get_textlist_index(textlist)
- if oldidx < worldlist.size() then
+ if oldidx < filterlist.size(worldlist) then
local newidx = oldidx + 1
engine.setting_set(settingname,
- worldlist.get_engine_index(newidx))
+ filterlist.get_engine_index(worldlist,newidx))
end
end
end
--------------------------------------------------------------------------------
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[6,4.2;2.8,0.5;world_delete_cancel;No]"
end
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"])
message = engine.create_world(worldname,gameindex)
else
menu.last_game = gameindex
engine.setting_set("main_menu_last_game_idx",gameindex)
- worldlist.refresh()
+ filterlist.refresh(worldlist)
engine.setting_set("mainmenu_last_selected_world",
- worldlist.engine_index_by_name(worldname))
+ filterlist.engine_index_by_uid(worldlist,worldname))
end
else
gamedata.errormessage = "No worldname given or no game selected"
if fields["world_delete_confirm"] then
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)
menu.world_to_del = 0
- worldlist.refresh()
+ filterlist.refresh(worldlist)
end
end
end
if event.typ == "CHG" then
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
gamedata.password = fields["te_passwd"]
gamedata.port = fields["te_serverport"]
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)
engine.start()
if fields["world_delete"] ~= nil then
local selected = engine.get_textlist_index("srv_worlds")
if selected > 0 and
- selected <= worldlist.size() then
- local world = worldlist.get_list()[selected]
+ selected <= filterlist.size(worldlist) then
+ local world = filterlist.get_list(worldlist)[selected]
if world ~= nil and
world.name ~= nil and
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.is_dialog = true
tabbuilder.show_buttons = false
if fields["world_configure"] ~= nil then
selected = engine.get_textlist_index("srv_worlds")
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
tabbuilder.current_tab = "dialog_configure_world"
tabbuilder.is_dialog = true
if event.typ == "CHG" then
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
fields["key_enter"] then
local selected = engine.get_textlist_index("sp_worlds")
if selected > 0 then
- gamedata.selected_world = worldlist.get_engine_index(selected)
+ gamedata.selected_world = filterlist.get_engine_index(worldlist,selected)
gamedata.singleplayer = true
menu.update_last_game(gamedata.selected_world)
if fields["world_delete"] ~= nil then
local selected = engine.get_textlist_index("sp_worlds")
if selected > 0 and
- selected <= worldlist.size() then
- local world = worldlist.get_list()[selected]
+ selected <= filterlist.size(worldlist) then
+ local world = filterlist.get_list(worldlist)[selected]
if world ~= nil and
world.name ~= nil and
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.is_dialog = true
tabbuilder.show_buttons = false
if fields["world_configure"] ~= nil then
selected = engine.get_textlist_index("sp_worlds")
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
tabbuilder.current_tab = "dialog_configure_world"
tabbuilder.is_dialog = true
--------------------------------------------------------------------------------
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"))
)
--------------------------------------------------------------------------------
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"))
)
tabbuilder.is_dialog = false
tabbuilder.show_buttons = true
tabbuilder.current_tab = engine.setting_get("main_menu_tab")
+ menu.update_gametype()
update_menu()
else
engine.close()
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
init_globals()
-worldlist.init()
menu.init()
tabbuilder.init()
menubar.refresh()
-worldlist = {}
+--------------------------------------------------------------------------------
+-- Generic implementation of a filter/sortable list --
+--------------------------------------------------------------------------------
+filterlist = {}
--------------------------------------------------------------------------------
-function worldlist.refresh()
- worldlist.m_raw_worldlist = engine.get_worlds()
- worldlist.process()
+function filterlist.refresh(this)
+ this.m_raw_list = this.m_raw_list_fct()
+ filterlist.process(this)
end
--------------------------------------------------------------------------------
-function worldlist.init()
- worldlist.m_gamefilter = nil
- worldlist.m_sortmode = "alphabetic"
+function filterlist.create(raw_fct,compare_fct,uid_match_fct,filter_fct)
+
+ 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_sortmode = "none"
+ this.m_sort_list = {}
+
+
- worldlist.m_processed_worldlist = nil
- worldlist.m_raw_worldlist = engine.get_worlds()
+ this.m_processed_list = nil
+ this.m_raw_list = this.m_raw_list_fct()
- worldlist.process()
+ filterlist.process(this)
+
+ return this
end
--------------------------------------------------------------------------------
-function worldlist.set_gamefilter(gameid)
- if gameid == worldlist.m_gamefilter then
+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 then
return
end
- worldlist.m_gamefilter = gameid
- worldlist.process()
+ this.m_filtercriteria = criteria
+ filterlist.process(this)
end
--------------------------------------------------------------------------------
-function worldlist.get_gamefilter()
- return worldlist.m_gamefilter
+function filterlist.get_filtercriteria(this)
+ return this.m_filtercriteria
end
--------------------------------------------------------------------------------
--supported sort mode "alphabetic|none"
-function worldlist.set_sortmode(mode)
- if (mode == worldlist.m_sortmode) then
+function filterlist.set_sortmode(this,mode)
+ if (mode == this.m_sortmode) then
return
end
- worldlist.m_sortmode = mode
- worldlist.process()
+ this.m_sortmode = mode
+ filterlist.process(this)
end
--------------------------------------------------------------------------------
-function worldlist.get_list()
- return worldlist.m_processed_worldlist
+function filterlist.get_list(this)
+ return this.m_processed_list
end
--------------------------------------------------------------------------------
-function worldlist.get_raw_list()
- return worldlist.m_raw_worldlist
+function filterlist.get_raw_list(this)
+ return this.m_raw_list
end
--------------------------------------------------------------------------------
-function worldlist.get_raw_world(idx)
+function filterlist.get_raw_element(this,idx)
if type(idx) ~= "number" then
idx = tonumber(idx)
end
- if idx ~= nil and idx > 0 and idx < #worldlist.m_raw_worldlist then
- return worldlist.m_raw_worldlist[idx]
+ if idx ~= nil and idx > 0 and idx < #this.m_raw_list then
+ return this.m_raw_list[idx]
end
return nil
end
--------------------------------------------------------------------------------
-function worldlist.get_engine_index(worldlistindex)
- assert(worldlist.m_processed_worldlist ~= nil)
+function filterlist.get_engine_index(this,listindex)
+ assert(this.m_processed_list ~= nil)
- if worldlistindex ~= nil and worldlistindex > 0 and
- worldlistindex <= #worldlist.m_processed_worldlist then
- local entry = worldlist.m_processed_worldlist[worldlistindex]
+ 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(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
end
end
end
--------------------------------------------------------------------------------
-function worldlist.get_current_index(worldlistindex)
- assert(worldlist.m_processed_worldlist ~= nil)
+function filterlist.get_current_index(this,listindex)
+ assert(this.m_processed_list ~= nil)
- if worldlistindex ~= nil and worldlistindex > 0 and
- worldlistindex <= #worldlist.m_raw_worldlist then
- local entry = worldlist.m_raw_worldlist[worldlistindex]
+ 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(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
end
end
end
--------------------------------------------------------------------------------
-function worldlist.process()
- assert(worldlist.m_raw_worldlist ~= nil)
+function filterlist.process(this)
+ assert(this.m_raw_list ~= nil)
- if worldlist.m_sortmode == "none" and
- worldlist.m_gamefilter == nil then
- worldlist.m_processed_worldlist = worldlist.m_raw_worldlist
+ if this.m_sortmode == "none" and
+ this.m_filtercriteria == nil then
+ this.m_processed_list = this.m_raw_list
return
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
- v.gameid == worldlist.m_gamefilter then
- table.insert(worldlist.m_processed_worldlist,v)
+ 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 worldlist.m_sortmode == "none" then
+ if this.m_sortmode == "none" then
return
end
- if worldlist.m_sortmode == "alphabetic" then
- worldlist.sort_alphabetic()
- end
-
-end
-
---------------------------------------------------------------------------------
-function worldlist.compare(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
+ 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
-
- return true
end
--------------------------------------------------------------------------------
-function worldlist.size()
- if worldlist.m_processed_worldlist == nil then
+function filterlist.size(this)
+ if this.m_processed_list == nil then
return 0
end
- return #worldlist.m_processed_worldlist
+ return #this.m_processed_list
end
--------------------------------------------------------------------------------
-function worldlist.exists(worldname)
- for i,v in ipairs(worldlist.m_raw_worldlist) do
- if v.name == worldname then
+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 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
+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 worlds than one with same name we can't decide which
+ -- 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 worldcount > 1 then
- worldidx=0
+ 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 worldidx
+ return true
end
--------------------------------------------------------------------------------
-function worldlist.sort_alphabetic()
+function sort_worlds_alphabetic(this)
- table.sort(worldlist.m_processed_worldlist, function(a, b)
+ table.sort(this.m_processed_list, function(a, b)
local n1 = a.name
local n2 = b.name
local count = math.min(#n1, #n2)