mirror of
https://github.com/minetest-mods/digtron.git
synced 2024-07-15 03:49:28 +02:00
rearrange context cache to play nice with players using multiple digtrons
This commit is contained in:
parent
b568fffdc8
commit
d79b22673b
148
controller.lua
148
controller.lua
@ -552,89 +552,102 @@ local update_controls = function(digtron_id, pos, player_name, facedir, fields)
|
|||||||
return refresh
|
return refresh
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------------------------
|
||||||
|
-- Inventory tab formspec
|
||||||
|
|
||||||
|
local inv_tab = function(digtron_id, inv_tab_context, player_context)
|
||||||
|
local inv_list = inv_tab_context.listname
|
||||||
|
local pages = inv_tab_context.pages
|
||||||
|
local current_page = player_context.inv_page[inv_list]
|
||||||
|
local starting_index = (current_page - 1) * 8 * 4
|
||||||
|
local paging_controls = ""
|
||||||
|
if pages > 1 then
|
||||||
|
paging_controls = "button[0,0;1,1;page_back;<<]"
|
||||||
|
.. "label[1.125,0.25;"..S("Page @1/@2", current_page, pages) .. "]"
|
||||||
|
.. "button[2,0;1,1;page_forward;>>]"
|
||||||
|
end
|
||||||
|
|
||||||
|
return "size[8,9]"
|
||||||
|
.. position_and_anchor
|
||||||
|
.. "container[0,0]"
|
||||||
|
.. "list[detached:" .. digtron_id .. ";"..inv_list..";0,0;8,4;"..starting_index.."]"
|
||||||
|
.. "container_end[]"
|
||||||
|
.. "container[2.5,4]" .. paging_controls .. "container_end[]"
|
||||||
|
.. "container[0,5]list[current_player;main;0,0;8,1;]list[current_player;main;0,1.25;8,3;8]container_end[]"
|
||||||
|
.. "listring[current_player;main]"
|
||||||
|
.. "listring[detached:" .. digtron_id .. ";"..inv_list.."]"
|
||||||
|
end
|
||||||
|
|
||||||
------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
-- This allows us to know which digtron the player has a formspec open for without
|
-- This allows us to know which digtron the player has a formspec open for without
|
||||||
-- sending the digtron_id over the network
|
-- sending the digtron_id over the network
|
||||||
local player_interacting_with_digtron_id = {}
|
local player_interacting_with_digtron_id = {}
|
||||||
-- Call this when the player opens a formspec to initialize these values
|
local get_context = function(digtron_id, player_name)
|
||||||
local player_opening_formspec = function(digtron_id, player_name)
|
local digtron_context = player_interacting_with_digtron_id[digtron_id] or {players={}}
|
||||||
local context = player_interacting_with_digtron_id[player_name] or {}
|
local player_context = digtron_context.players[player_name] or {current_tab = 1}
|
||||||
context.digtron_id = digtron_id
|
digtron_context.players[player_name] = player_context
|
||||||
context.open = true
|
player_interacting_with_digtron_id[digtron_id] = digtron_context
|
||||||
player_interacting_with_digtron_id[player_name] = context
|
return player_context, digtron_context
|
||||||
end
|
end
|
||||||
|
local get_context_for_player = function(player_name)
|
||||||
|
for digtron_id, digtron_context in pairs(player_interacting_with_digtron_id) do
|
||||||
|
local player_context = digtron_context.players[player_name]
|
||||||
|
if player_context and player_context.open then
|
||||||
|
return player_context, digtron_context, digtron_id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- TODO: dispose of cached digtron context when a digtron is disposed
|
||||||
|
|
||||||
local get_controller_assembled_formspec = function(digtron_id, player_name)
|
local get_controller_assembled_formspec = function(digtron_id, player_name)
|
||||||
local context = player_interacting_with_digtron_id[player_name]
|
local player_context, digtron_context = get_context(digtron_id, player_name)
|
||||||
if context == nil or context.digtron_id ~= digtron_id then
|
|
||||||
minetest.log("error", "[Digtron] get_controller_assembled_formspec was called for Digtron "
|
|
||||||
..digtron_id .. " by " .. player_name .. " but there was no context recorded or the context was"
|
|
||||||
.." for the wrong digtron. This shouldn't be possible.")
|
|
||||||
return ""
|
|
||||||
end
|
|
||||||
|
|
||||||
local inv = digtron.get_inventory(digtron_id) -- ensures the detatched inventory exists and is populated
|
local inv = digtron.get_inventory(digtron_id) -- ensures the detatched inventory exists and is populated
|
||||||
|
|
||||||
-- TODO: will probably want a centralized cache for most of this, right now there's tons of redundancy
|
if digtron_context.tabs == nil then
|
||||||
if context.tabs == nil then
|
digtron_context.tabs = {}
|
||||||
context.tabs = {}
|
|
||||||
local lists = inv:get_lists()
|
local lists = inv:get_lists()
|
||||||
for listname, contents in pairs(lists) do
|
for listname, contents in pairs(lists) do
|
||||||
table.insert(context.tabs, {
|
table.insert(digtron_context.tabs, {
|
||||||
tab_type = "inventory",
|
tab_type = "inventory",
|
||||||
listname = listname,
|
listname = listname,
|
||||||
size = #contents,
|
size = #contents,
|
||||||
pages = math.floor(#contents/(8*4)) + 1,
|
pages = math.floor(#contents/(8*4)) + 1})
|
||||||
current_page = 1})
|
end
|
||||||
|
end
|
||||||
|
if player_context.inv_page == nil then
|
||||||
|
player_context.inv_page = {}
|
||||||
|
local lists = inv:get_lists()
|
||||||
|
for listname, contents in pairs(lists) do
|
||||||
|
player_context.inv_page[listname] = player_context.inv_page[listname] or 1
|
||||||
end
|
end
|
||||||
context.current_tab = 1
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local tabs = "tabheader[0,0;tab_header;"..S("Controls")..","..S("Sequence")
|
local tabs = "tabheader[0,0;tab_header;"..S("Controls")..","..S("Sequence")
|
||||||
for _, tab in ipairs(context.tabs) do
|
for _, tab in ipairs(digtron_context.tabs) do
|
||||||
tabs = tabs .. "," .. listname_to_title[tab.listname] or tab.listname
|
tabs = tabs .. "," .. listname_to_title[tab.listname] or tab.listname
|
||||||
end
|
end
|
||||||
tabs = tabs .. ";" .. context.current_tab .. "]"
|
tabs = tabs .. ";" .. player_context.current_tab .. "]"
|
||||||
|
|
||||||
local inv_tab = function(inv_tab_context)
|
if player_context.current_tab == 1 then
|
||||||
local inv_list = inv_tab_context.listname
|
|
||||||
local pages = inv_tab_context.pages
|
|
||||||
local current_page = inv_tab_context.current_page
|
|
||||||
local starting_index = (current_page - 1) * 8 * 4
|
|
||||||
local paging_controls = ""
|
|
||||||
if pages > 1 then
|
|
||||||
paging_controls = "button[0,0;1,1;page_back;<<]"
|
|
||||||
.. "label[1.125,0.25;"..S("Page @1/@2", current_page, pages) .. "]"
|
|
||||||
.. "button[2,0;1,1;page_forward;>>]"
|
|
||||||
end
|
|
||||||
|
|
||||||
return "size[8,9]"
|
|
||||||
.. position_and_anchor
|
|
||||||
.. "container[0,0]"
|
|
||||||
.. "list[detached:" .. digtron_id .. ";"..inv_list..";0,0;8,4;"..starting_index.."]"
|
|
||||||
.. "container_end[]"
|
|
||||||
.. "container[2.5,4]" .. paging_controls .. "container_end[]"
|
|
||||||
.. "container[0,5]list[current_player;main;0,0;8,1;]list[current_player;main;0,1.25;8,3;8]container_end[]"
|
|
||||||
.. "listring[current_player;main]"
|
|
||||||
.. "listring[detached:" .. digtron_id .. ";"..inv_list.."]"
|
|
||||||
end
|
|
||||||
|
|
||||||
if context.current_tab == 1 then
|
|
||||||
return controls_tab(digtron_id) .. tabs
|
return controls_tab(digtron_id) .. tabs
|
||||||
elseif context.current_tab == 2 then
|
elseif player_context.current_tab == 2 then
|
||||||
return sequence_tab(digtron_id) .. tabs
|
return sequence_tab(digtron_id) .. tabs
|
||||||
else
|
else
|
||||||
local inv_tab_context = context.tabs[context.current_tab - 2]
|
local inv_tab_context = digtron_context.tabs[player_context.current_tab - 2]
|
||||||
return inv_tab(inv_tab_context) .. tabs
|
return inv_tab(digtron_id, inv_tab_context, player_context) .. tabs
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- For now, only refresh the UI if it's open to tab 2 (the sequencer). Other tabs
|
-- For now, only refresh the UI if it's open to tab 2 (the sequencer). Other tabs
|
||||||
-- don't have things that are changed "on the fly" by Digtron operation.
|
-- don't have things that are changed "on the fly" by Digtron operation.
|
||||||
refresh_open_formspec = function(digtron_id)
|
refresh_open_formspec = function(digtron_id)
|
||||||
for player_name, context in pairs(player_interacting_with_digtron_id) do
|
local digtron_context = player_interacting_with_digtron_id[digtron_id]
|
||||||
if context.open and context.digtron_id == digtron_id and context.current_tab == 2 then
|
if digtron_context == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
for player_name, player_context in pairs(digtron_context.players) do
|
||||||
|
if player_context.open and player_context.current_tab == 2 then
|
||||||
minetest.show_formspec(player_name,
|
minetest.show_formspec(player_name,
|
||||||
"digtron:controller_assembled",
|
"digtron:controller_assembled",
|
||||||
get_controller_assembled_formspec(digtron_id, player_name))
|
get_controller_assembled_formspec(digtron_id, player_name))
|
||||||
@ -650,16 +663,11 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
local player_name = player:get_player_name()
|
local player_name = player:get_player_name()
|
||||||
|
|
||||||
-- Get and validate various values
|
-- Get and validate various values
|
||||||
local context = player_interacting_with_digtron_id[player_name]
|
local player_context, digtron_context, digtron_id = get_context_for_player(player_name)
|
||||||
if context == nil then
|
if player_context == nil then
|
||||||
minetest.log("error", "[Digtron] player_interacting_with_digtron_id context not found for " .. player_name)
|
minetest.log("error", "[Digtron] player_interacting_with_digtron_id context not found for " .. player_name)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local digtron_id = context.digtron_id
|
|
||||||
if digtron_id == nil then
|
|
||||||
minetest.log("error", "[Digtron] player_interacting_with_digtron_id context had no digtron id for " .. player_name)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local pos = digtron.get_pos(digtron_id)
|
local pos = digtron.get_pos(digtron_id)
|
||||||
if pos == nil then
|
if pos == nil then
|
||||||
minetest.log("error", "[Digtron] controller was unable to look up a position for digtron id for " .. digtron_id)
|
minetest.log("error", "[Digtron] controller was unable to look up a position for digtron id for " .. digtron_id)
|
||||||
@ -673,12 +681,12 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local current_tab = context.current_tab
|
local current_tab = player_context.current_tab
|
||||||
local refresh = false
|
local refresh = false
|
||||||
if fields.tab_header then
|
if fields.tab_header then
|
||||||
local new_tab = tonumber(fields.tab_header)
|
local new_tab = tonumber(fields.tab_header)
|
||||||
if new_tab <= #(context.tabs) + 2 then
|
if new_tab <= #(digtron_context.tabs) + 2 then
|
||||||
context.current_tab = new_tab
|
player_context.current_tab = new_tab
|
||||||
refresh = true
|
refresh = true
|
||||||
else
|
else
|
||||||
minetest.log("error", "[Digtron] digtron:controller_assembled formspec returned the out-of-range tab index "
|
minetest.log("error", "[Digtron] digtron:controller_assembled formspec returned the out-of-range tab index "
|
||||||
@ -695,23 +703,24 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
update_sequence(digtron_id, fields, player_name)
|
update_sequence(digtron_id, fields, player_name)
|
||||||
refresh = true
|
refresh = true
|
||||||
else -- inventory tabs
|
else -- inventory tabs
|
||||||
local tab_context = context.tabs[current_tab - 2]
|
local tab_context = digtron_context.tabs[current_tab - 2]
|
||||||
|
local current_page = player_context.inv_page[tab_context.listname]
|
||||||
if fields.page_forward then
|
if fields.page_forward then
|
||||||
if tab_context.current_page < tab_context.pages then
|
if current_page < tab_context.pages then
|
||||||
tab_context.current_page = tab_context.current_page + 1
|
player_context.inv_page[tab_context.listname] = current_page + 1
|
||||||
refresh = true
|
refresh = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if fields.page_back then
|
if fields.page_back then
|
||||||
if tab_context.current_page > 1 then
|
if current_page > 1 then
|
||||||
tab_context.current_page = tab_context.current_page - 1
|
player_context.inv_page[tab_context.listname] = current_page - 1
|
||||||
refresh = true
|
refresh = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if fields.quit then
|
if fields.quit then
|
||||||
context.open = false
|
player_context.open = false
|
||||||
end
|
end
|
||||||
|
|
||||||
if refresh then
|
if refresh then
|
||||||
@ -946,7 +955,8 @@ minetest.register_node("digtron:controller", combine_defs(base_def, {
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
player_opening_formspec(digtron_id, player_name)
|
local player_context = get_context(digtron_id, player_name)
|
||||||
|
player_context.open = true
|
||||||
minetest.show_formspec(player_name,
|
minetest.show_formspec(player_name,
|
||||||
"digtron:controller_assembled",
|
"digtron:controller_assembled",
|
||||||
get_controller_assembled_formspec(digtron_id, player_name))
|
get_controller_assembled_formspec(digtron_id, player_name))
|
||||||
|
Loading…
Reference in New Issue
Block a user