Add player iteration methods to builtin, optimization of many mods

master
stujones11 2019-06-30 21:42:14 +01:00 committed by MoNTE48
parent 118b648d37
commit ed2e0ada40
4 changed files with 112 additions and 13 deletions

View File

@ -556,6 +556,99 @@ core.registered_on_protection_violation, core.register_on_protection_violation =
core.registered_on_item_eats, core.register_on_item_eat = make_registration()
core.registered_on_punchplayers, core.register_on_punchplayer = make_registration()
-- Player step iterration
players_per_step = core.settings:get("players_per_globalstep")
players_per_step = players_per_step and tonumber(players_per_step) or 20
local player_iter = nil
local player_iter_forced = nil
local playerstep_iter = nil
local playerstep_funcs = {}
local playerstep_funcs_forced = {}
local playernames = {}
local playernames_forced = {}
core.register_playerstep = function(func, force)
local funcs = force and playerstep_funcs_forced or playerstep_funcs
funcs[#funcs + 1] = func
end
local function table_iter(t)
local i = 0
local n = table.getn(t)
return function ()
i = i + 1
if i <= n then
return t[i]
end
end
end
function core.get_player_iter()
local names = {}
for player in table_iter(core.get_connected_players()) do
local name = player:get_player_name()
if name then
names[#names + 1] = name
end
end
return table_iter(names)
end
local function get_playerstep_func()
if playerstep_iter == nil then
playerstep_iter = table_iter(playerstep_funcs)
playernames = {}
for _ = 1, players_per_step do
if player_iter == nil then
player_iter = core.get_player_iter()
end
local name = player_iter()
if not name then
player_iter = nil
break
end
playernames[#playernames + 1] = name
end
end
local func = playerstep_iter()
playerstep_iter = func and playerstep_iter
return func or get_playerstep_func()
end
-- Run playerstep callbacks
core.register_globalstep(function(dtime)
-- Run forced callbacks
if #playerstep_funcs_forced ~= 0 then
playernames_forced = {}
for _ = 1, players_per_step do
if player_iter_forced == nil then
player_iter_forced = core.get_player_iter()
end
local name = player_iter_forced()
if not name then
player_iter_forced = nil
break
end
playernames_forced[#playernames_forced + 1] = name
end
for func in table_iter(playerstep_funcs_forced) do
if type(func) == "function" then
func(dtime, playernames_forced)
end
end
end
if #playerstep_funcs ~= 0 then
-- Run single step callbacks
local func = get_playerstep_func()
if type(func) == "function" then
func(dtime, playernames)
end
end
end)
--
-- Compatibility for on_mapgen_init()
--

View File

@ -185,16 +185,9 @@ core.register_on_joinplayer(function(player)
initialize_builtin_statbars(player)
end)
local time = 0
local update_time = 1
core.register_globalstep(function(dtime)
time = time + dtime
if time > update_time then
local players = core.get_connected_players()
for i = 1, #players do
local player = players[i]
minetest.register_playerstep(function(dtime, playernames)
for _, name in pairs(playernames) do
local player = minetest.get_player_by_name(name)
local player_name = player:get_player_name()
local wielded_item = player:get_wielded_item()
@ -224,6 +217,4 @@ core.register_globalstep(function(dtime)
hud.change_item(player, "itemname", {text = description})
end
end
time = 0
end
end)
end, minetest.is_singleplayer()) -- Force step in singlplayer mode only

View File

@ -2363,6 +2363,17 @@ Call these functions only at load time!
* `minetest.register_globalstep(func(dtime))`
* Called every server step, usually interval of 0.1s
* `minetest.register_playerstep(function(dtime, playernames), force)`
* Called one registration per step, see `force`
* `dtime` : Delta time since last callback, see `dedicated_server_step` setting
* `playernames` : Table of player names, see `players_per_globalstep` setting
* `force` : Boolean value (optional)
* Force this callback to run on every server step, default: `false`
* Note: This callback should not be rate limited or players may be missed!
* See the [fire] mod for an example of how this may be done reliably
* `minetest.get_player_iter()`
* Returns a player name iterrator, as used by `minetest.register_playerstep`
* See `builtin/game/register.lua` for example usage
* `minetest.register_on_shutdown(func())`
* Called before server shutdown
* **Warning**: If the server terminates abnormally (i.e. crashes), the registered

View File

@ -1115,6 +1115,10 @@
# type: float
# dedicated_server_step = 0.1
# Maxumim number of players to process per step, see `minetest.register_playerstep`
# type: int
# players_per_globalstep = 20
# Time in between active block management cycles
# type: float
# active_block_mgmt_interval = 2.0