From 28717b4d65dc2e4080d5c7bde799fb4b87ef9a9d Mon Sep 17 00:00:00 2001 From: orwell96 Date: Wed, 3 May 2017 16:31:13 +0200 Subject: [PATCH] Performance improvements: Don't clear paths unless absolutely necessary instead delete path elements that are too far from the train one-by-one Also when switching a switch or changing rails, only clear train paths of trains that are nearby. --- advtrains.zip | Bin 4992868 -> 4993627 bytes advtrains/advtrains/atc.lua | 2 +- advtrains/advtrains/init.lua | 38 ++++++- advtrains/advtrains/tracks.lua | 4 +- advtrains/advtrains/trainlogic.lua | 106 +++++++++++++----- .../advtrains_luaautomation/active_common.lua | 2 +- 6 files changed, 118 insertions(+), 34 deletions(-) diff --git a/advtrains.zip b/advtrains.zip index 2144e2888f765e588ea9440db5a3cb4214ae2ba0..957cfb46192aedfb303782d5692122ab6aea0d1c 100644 GIT binary patch delta 22624 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 delta 21616 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 diff --git a/advtrains/advtrains/atc.lua b/advtrains/advtrains/atc.lua index ed631a3..5f1f64d 100644 --- a/advtrains/advtrains/atc.lua +++ b/advtrains/advtrains/atc.lua @@ -93,7 +93,7 @@ advtrains.register_tracks("default", { after_place_node=apn_func, after_dig_node=function(pos) return advtrains.pcall(function() - advtrains.invalidate_all_paths() + advtrains.invalidate_all_paths(pos) advtrains.ndb.clear(pos) local pts=minetest.pos_to_string(pos) atc.controllers[pts]=nil diff --git a/advtrains/advtrains/init.lua b/advtrains/advtrains/init.lua index 022fcee..3fc16ed 100644 --- a/advtrains/advtrains/init.lua +++ b/advtrains/advtrains/init.lua @@ -37,7 +37,7 @@ advtrains.modpath = minetest.get_modpath("advtrains") function advtrains.print_concat_table(a) local str="" local stra="" - for i=1,50 do + for i=1,10 do t=a[i] if t==nil then stra=stra.."nil " @@ -67,9 +67,12 @@ end atprint=function() end if minetest.setting_getbool("advtrains_debug") then atprint=function(t, ...) + local context=advtrains.atprint_context_tid + if not context then context="" end + --if context~="4527" then return end local text=advtrains.print_concat_table({t, ...}) - minetest.log("action", "[advtrains]"..text) - minetest.chat_send_all("[advtrains]"..text) + minetest.log("action", "[advtrains]"..context..">"..text) + minetest.chat_send_all("[advtrains]"..context..">"..text) end end atwarn=function(t, ...) @@ -171,7 +174,8 @@ end advtrains.avt_save = function() --atprint("saving") - advtrains.invalidate_all_paths() + --No more invalidating. + --Instead, remove path a.s.o from the saved table manually -- update wagon saves for _,wagon in pairs(minetest.luaentities) do @@ -195,10 +199,34 @@ advtrains.avt_save = function() end end + local tmp_trains={} + for id, train in pairs(advtrains.trains) do + --first, deep_copy the train + local v=advtrains.merge_tables(train) + --then invalidate + if v.index then + v.restore_add_index=v.index-math.floor(v.index+0.5) + end + v.path=nil + v.path_dist=nil + v.index=nil + v.end_index=nil + v.min_index_on_track=nil + v.max_index_on_track=nil + v.path_extent_min=nil + v.path_extent_max=nil + + v.detector_old_index=nil + v.detector_old_end_index=nil + + --then save it + tmp_trains[id]=v + end + --versions: -- 1 - Initial new save format. local save_tbl={ - trains = advtrains.trains, + trains = tmp_trains, wagon_save = advtrains.wagon_save, ptmap = advtrains.player_to_train_mapping, atc = advtrains.atc.save_data(), diff --git a/advtrains/advtrains/tracks.lua b/advtrains/advtrains/tracks.lua index 86c87ba..b390c6a 100644 --- a/advtrains/advtrains/tracks.lua +++ b/advtrains/advtrains/tracks.lua @@ -263,13 +263,13 @@ function advtrains.register_tracks(tracktype, def, preset) local rcswitchfunc=function(pos, node, player) if minetest.check_player_privs(player:get_player_name(), {train_operator=true}) then advtrains.ndb.swap_node(pos, {name=def.nodename_prefix.."_"..suffix_target, param2=node.param2}) - advtrains.invalidate_all_paths() + advtrains.invalidate_all_paths(pos) end end local switchfunc=function(pos, node, newstate) if newstate~=is_state then advtrains.ndb.swap_node(pos, {name=def.nodename_prefix.."_"..suffix_target, param2=node.param2}) - advtrains.invalidate_all_paths() + advtrains.invalidate_all_paths(pos) end end local mesec diff --git a/advtrains/advtrains/trainlogic.lua b/advtrains/advtrains/trainlogic.lua index 7dad80c..e62c864 100644 --- a/advtrains/advtrains/trainlogic.lua +++ b/advtrains/advtrains/trainlogic.lua @@ -55,12 +55,16 @@ advtrains.mainloop_trainlogic=function(dtime) local t=os.clock() advtrains.detector.on_node={} for k,v in pairs(advtrains.trains) do + advtrains.atprint_context_tid=sid(k) advtrains.train_step_a(k, v, dtime) end for k,v in pairs(advtrains.trains) do + advtrains.atprint_context_tid=sid(k) advtrains.train_step_b(k, v, dtime) end + advtrains.atprint_context_tid=nil + atprintbm("trainsteps", t) endstep() end @@ -140,7 +144,7 @@ function advtrains.train_step_a(id, train, dtime) end --- 2. prepare initial path and index if needed --- if not train.index then train.index=0 end - if not train.path or #train.path<2 then + if not train.path then if not train.last_pos then --no chance to recover atprint("train hasn't saved last-pos, removing train.") @@ -224,36 +228,43 @@ function advtrains.train_step_a(id, train, dtime) train.tarvelocity=0 end + --- 3a. this can be useful for debugs/warnings and is used for check_trainpartload --- + local t_info, train_pos=sid(id), train.path[math.floor(train.index)] + if train_pos then + t_info=t_info.." @"..minetest.pos_to_string(train_pos) + end + --apply off-track handling: local front_off_track=train.max_index_on_track and train.index>train.max_index_on_track local back_off_track=train.min_index_on_track and train.end_index1 then train.tarvelocity=1 - atwarn("Train",sid(id)," is off track at both ends. Clipping velocity to 1") + atwarn("Train",t_info,"is off track at both ends. Clipping velocity to 1") pprint=true end elseif front_off_track then--allow movement only backward if train.movedir==1 and train.tarvelocity>0 then train.tarvelocity=0 - atwarn("Train",sid(id)," is off track. Trying to drive further out. Velocity clipped to 0") + atwarn("Train",t_info,"is off track. Trying to drive further out. Velocity clipped to 0") pprint=true end if train.movedir==-1 and train.tarvelocity>1 then train.tarvelocity=1 - atwarn("Train",sid(id)," is off track. Velocity clipped to 1") + atwarn("Train",t_info,"is off track. Velocity clipped to 1") pprint=true end elseif back_off_track then--allow movement only forward if train.movedir==-1 and train.tarvelocity>0 then train.tarvelocity=0 - atwarn("Train",sid(id)," is off track. Trying to drive further out. Velocity clipped to 0") + atwarn("Train",t_info,"is off track. Trying to drive further out. Velocity clipped to 0") pprint=true end if train.movedir==1 and train.tarvelocity>1 then train.tarvelocity=1 - atwarn("Train",sid(id)," is off track. Velocity clipped to 1") + atwarn("Train",t_info,"is off track. Velocity clipped to 1") pprint=true end end @@ -322,7 +333,7 @@ function advtrains.train_step_a(id, train, dtime) --why this is an extra function, see under 3. advtrains.pathpredict(id, train, true) - --make pos/yaw available for possible recover calls + --- 5a. make pos/yaw available for possible recover calls --- if train.max_index_on_trackdelete_max then + atprint(sid(id),"clearing path max ",train.path_extent_max," to ",delete_max) + train.path_dist[delete_max]=nil + for i=delete_max+1,train.path_extent_max do + train.path[i]=nil + train.path_dist[i]=nil + end + train.path_extent_max=delete_max + train.max_index_on_track=math.min(train.max_index_on_track, delete_max) + end + --- 6. update node coverage --- -- when paths get cleared, the old indices set above will be up-to-date and represent the state in which the last run of this code was made @@ -406,7 +447,7 @@ function advtrains.train_step_a(id, train, dtime) train.check_trainpartload=(train.check_trainpartload or 0)-dtime local node_range=(math.max((minetest.setting_get("active_block_range") or 0),1)*16) if train.check_trainpartload<=0 then - local ori_pos=advtrains.get_real_index_position(path, train.index) --not much to calculate + local ori_pos=train_pos --see 3a. --atprint("[train "..id.."] at "..minetest.pos_to_string(vector.round(ori_pos))) local should_check=false @@ -429,6 +470,7 @@ end --about regular: Used by 1. to ensure path gets generated far enough, since end index is not known at this time. function advtrains.pathpredict(id, train, regular) + --TODO duplicate code under 5b. local path_pregen=10 local gen_front= path_pregen @@ -440,7 +482,7 @@ function advtrains.pathpredict(id, train, regular) local maxn=train.path_extent_max or 0 while maxn < gen_front do--pregenerate - --atprint("maxn conway for ",maxn,minetest.pos_to_string(path[maxn]),maxn-1,minetest.pos_to_string(path[maxn-1])) + atprint("maxn conway for ",maxn,minetest.pos_to_string(train.path[maxn]),maxn-1,minetest.pos_to_string(train.path[maxn-1])) local conway=advtrains.conway(train.path[maxn], train.path[maxn-1], train.drives_on) if conway then train.path[maxn+1]=conway @@ -458,7 +500,7 @@ function advtrains.pathpredict(id, train, regular) local minn=train.path_extent_min or -1 while minn > gen_back do - --atprint("minn conway for ",minn,minetest.pos_to_string(path[minn]),minn+1,minetest.pos_to_string(path[minn+1])) + atprint("minn conway for ",minn,minetest.pos_to_string(train.path[minn]),minn+1,minetest.pos_to_string(train.path[minn+1])) local conway=advtrains.conway(train.path[minn], train.path[minn+1], train.drives_on) if conway then train.path[minn-1]=conway @@ -858,23 +900,37 @@ function advtrains.get_train_at_pos(pos) return advtrains.detector.on_node[ph] end -function advtrains.invalidate_all_paths() - --atprint("invalidating all paths") +function advtrains.invalidate_all_paths(pos) + --if a position is given, only invalidate inside a radius to save performance + local inv_radius=50 + atprint("invalidating all paths") for k,v in pairs(advtrains.trains) do - if v.index then - v.restore_add_index=v.index-math.floor(v.index+0.5) + local exec=true + if pos and v.path and v.index and v.end_index then + --start and end pos of the train + local cmp1=v.path[math.floor(v.index)] + local cmp2=v.path[math.floor(v.end_index)] + if vector.distance(pos, cmp1)>inv_radius and vector.distance(pos, cmp2)>inv_radius then + exec=false + end + end + if exec then + --TODO duplicate code in init.lua avt_save()! + if v.index then + v.restore_add_index=v.index-math.floor(v.index+0.5) + end + v.path=nil + v.path_dist=nil + v.index=nil + v.end_index=nil + v.min_index_on_track=nil + v.max_index_on_track=nil + v.path_extent_min=nil + v.path_extent_max=nil + + v.detector_old_index=nil + v.detector_old_end_index=nil end - v.path=nil - v.path_dist=nil - v.index=nil - v.end_index=nil - v.min_index_on_track=nil - v.max_index_on_track=nil - v.path_extent_min=nil - v.path_extent_max=nil - - v.detector_old_index=nil - v.detector_old_end_index=nil end end diff --git a/advtrains/advtrains_luaautomation/active_common.lua b/advtrains/advtrains_luaautomation/active_common.lua index e17af91..8c910c6 100644 --- a/advtrains/advtrains_luaautomation/active_common.lua +++ b/advtrains/advtrains_luaautomation/active_common.lua @@ -49,7 +49,7 @@ function ac.getform(pos, meta_p) end function ac.after_dig_node(pos, node, player) - advtrains.invalidate_all_paths() + advtrains.invalidate_all_paths(pos) advtrains.ndb.clear(pos) local ph=minetest.pos_to_string(pos) ac.nodes[ph]=nil