87617c4eed
Added LibMapData and began transitioning map data needs to use LibMapData. Began changing the data collection, yet again. Once this goes beta, the new collection system will be in place... My hope is to allow QH to "learn" as you play, eliminating any need for data compilation, though I will still make attempts to compile said data into a full on db. Added some code that will eventually be usable to get data from LightHeaded. This is not yet implemented in full, but will be the preferred method of QH doesn't know about a quest. Order of preference will eventually be: 1) Learned data, 2) Internal DB, 3) LightHeaded, 4) WoW client. NOTE: THIS COMMIT IS ON THE WOW-DB-GET BRANCH. An alpha release will be up on the downloads page by 6:30 US EST on February 29, 2012 (tomorrow). I THINK I have covered all the changes in this, but I have done so much since my last commit, I cannot be sure.
541 lignes
19 Kio
Lua
541 lignes
19 Kio
Lua
|
|
local GetTime = QuestHelper_GetTime
|
|
|
|
QuestHelper_File["routing_controller.lua"] = "4.0.1.$svnversion$"
|
|
QuestHelper_Loadtime["routing_controller.lua"] = GetTime()
|
|
|
|
local debug_output = (QuestHelper_File["routing_controller.lua"] == "Development Version")
|
|
|
|
local Route_Core_Process = QH_Route_Core_Process
|
|
|
|
local Route_Core_NodeCount = QH_Route_Core_NodeCount
|
|
|
|
local Route_Core_Init = QH_Route_Core_Init
|
|
local Route_Core_SetStart = QH_Route_Core_SetStart
|
|
|
|
local Route_Core_ClusterAdd = QH_Route_Core_ClusterAdd
|
|
local Route_Core_ClusterRemove = QH_Route_Core_ClusterRemove
|
|
local Route_Core_ClusterRequires = QH_Route_Core_ClusterRequires
|
|
local Route_Core_DistanceClear = QH_Route_Core_DistanceClear
|
|
|
|
local Route_Core_IgnoreNode = QH_Route_Core_IgnoreNode
|
|
local Route_Core_UnignoreNode = QH_Route_Core_UnignoreNode
|
|
local Route_Core_IgnoreCluster = QH_Route_Core_IgnoreCluster
|
|
local Route_Core_UnignoreCluster = QH_Route_Core_UnignoreCluster
|
|
|
|
local Route_Core_GetClusterPriority = QH_Route_Core_GetClusterPriority
|
|
local Route_Core_SetClusterPriority = QH_Route_Core_SetClusterPriority
|
|
|
|
local Route_Core_TraverseNodes = QH_Route_Core_TraverseNodes
|
|
local Route_Core_TraverseClusters = QH_Route_Core_TraverseClusters
|
|
local Route_Core_IgnoredReasons_Cluster = QH_Route_Core_IgnoredReasons_Cluster
|
|
local Route_Core_IgnoredReasons_Node = QH_Route_Core_IgnoredReasons_Node
|
|
local Route_Core_Ignored_Cluster = QH_Route_Core_Ignored_Cluster
|
|
local Route_Core_Ignored_Cluster_Active = QH_Route_Core_Ignored_Cluster_Active
|
|
|
|
local Route_Core_EarlyExit = QH_Route_Core_EarlyExit
|
|
|
|
QH_Route_Core_Process = nil
|
|
QH_Route_Core_Init = nil
|
|
QH_Route_Core_SetStart = nil
|
|
QH_Route_Core_NodeObsoletes = nil
|
|
QH_Route_Core_NodeRequires = nil
|
|
QH_Route_Core_DistanceClear = nil
|
|
QH_Route_Core_IgnoreNode = nil
|
|
QH_Route_Core_UnignoreNode = nil
|
|
QH_Route_Core_IgnoreCluster = nil
|
|
QH_Route_Core_UnignoreCluster = nil
|
|
QH_Route_Core_GetClusterPriority = nil
|
|
QH_Route_Core_SetClusterPriority = nil
|
|
QH_Route_Core_TraverseNodes = nil
|
|
QH_Route_Core_TraverseClusters = nil
|
|
QH_Route_Core_IgnoredReasons_Cluster = nil
|
|
QH_Route_Core_IgnoredReasons_Node = nil
|
|
QH_Route_Core_Ignored_Cluster = nil
|
|
QH_Route_Core_Ignored_Cluster_Active = nil
|
|
QH_Route_Core_EarlyExit = nil
|
|
|
|
local pending = {}
|
|
local rescan_it_all = false
|
|
|
|
local weak_key = {__mode="k"}
|
|
|
|
local function new_pathcache_table(conservative)
|
|
return setmetatable(conservative and {} or QuestHelper:CreateTable("controller cache"), weak_key)
|
|
end
|
|
|
|
-- Every minute or two, we dump the inactive and move active to inactive. Every time we touch something, we put it in active.
|
|
local pathcache_active = new_pathcache_table()
|
|
local pathcache_inactive = new_pathcache_table()
|
|
|
|
local function pcs(tpcs)
|
|
local ct = 0
|
|
for _, v in pairs(tpcs) do
|
|
for _, t in pairs(v) do
|
|
ct = ct + 1
|
|
end
|
|
end
|
|
return ct
|
|
end
|
|
|
|
function QH_PrintPathcacheSize()
|
|
QuestHelper:TextOut(string.format("Active pathcache: %d", pcs(pathcache_active)))
|
|
QuestHelper:TextOut(string.format("Inactive pathcache: %d", pcs(pathcache_inactive)))
|
|
end
|
|
function QH_ClearPathcache(conservative)
|
|
local ps = pcs(pathcache_inactive)
|
|
pathcache_active = new_pathcache_table(conservative)
|
|
pathcache_inactive = new_pathcache_table(conservative)
|
|
return ps
|
|
end
|
|
|
|
local notification_funcs = {}
|
|
|
|
function QH_Route_RegisterNotification(func)
|
|
table.insert(notification_funcs, func)
|
|
end
|
|
|
|
local hits = 0
|
|
local misses = 0
|
|
|
|
local function GetCachedPath(loc1, loc2)
|
|
-- If it's in active, it's guaranteed to be in inactive.
|
|
if not pathcache_inactive[loc1] or not pathcache_inactive[loc1][loc2] then
|
|
-- Not in either, time to create
|
|
misses = misses + 1
|
|
local nrt = QH_Graph_Pathfind(loc1.loc, loc2.loc, false, true)
|
|
QuestHelper: Assert(nrt)
|
|
if not pathcache_active[loc1] then pathcache_active[loc1] = new_pathcache_table() end
|
|
if not pathcache_inactive[loc1] then pathcache_inactive[loc1] = new_pathcache_table() end
|
|
pathcache_active[loc1][loc2] = nrt
|
|
pathcache_inactive[loc1][loc2] = nrt
|
|
return nrt
|
|
else
|
|
hits = hits + 1
|
|
if not pathcache_active[loc1] then pathcache_active[loc1] = new_pathcache_table() end
|
|
pathcache_active[loc1][loc2] = pathcache_inactive[loc1][loc2]
|
|
return pathcache_active[loc1][loc2]
|
|
end
|
|
end
|
|
|
|
local last_path = nil
|
|
local cleanup_path = nil
|
|
|
|
local function ReplotPath(progress)
|
|
if not last_path then return end -- siiigh
|
|
|
|
local real_path = QuestHelper:CreateTable("path")
|
|
hits = 0
|
|
misses = 0
|
|
|
|
local distance = 0
|
|
for k, v in ipairs(last_path) do
|
|
QH_Timeslice_Yield()
|
|
--QuestHelper: Assert(not v.condense_type) -- no
|
|
v.distance = distance -- I'm not a huge fan of mutating things like this, but it is safe, and these nodes are technically designed to be modified during runtime anyway
|
|
table.insert(real_path, v)
|
|
|
|
if last_path[k + 1] then
|
|
local nrt = GetCachedPath(last_path[k], last_path[k + 1])
|
|
distance = distance + nrt.d
|
|
QuestHelper: Assert(nrt)
|
|
|
|
-- The "condense" is kind of weird - we're actually condensing descriptions, but we condense to the *last* item. Urgh.
|
|
local condense_start = nil
|
|
local condense_class = nil
|
|
local condense_to = nil
|
|
|
|
-- ugh this is just easier
|
|
local function condense_doit()
|
|
--print("start condense doit, was", real_path[condense_start].map_desc[1])
|
|
for i = condense_start, #real_path do
|
|
real_path[i].map_desc = condense_to
|
|
end
|
|
--print("end condense doit, now", real_path[condense_start].map_desc[1])
|
|
condense_start, condense_class, condense_to = nil, nil, nil
|
|
end
|
|
|
|
if #nrt > 0 then for _, wp in ipairs(nrt) do
|
|
QuestHelper: Assert(wp.c)
|
|
|
|
--print(wp.condense_class)
|
|
if condense_class and condense_class ~= wp.condense_class then condense_doit() end
|
|
|
|
local pathnode = QuestHelper:CreateTable("pathnode")
|
|
pathnode.loc = QuestHelper:CreateTable("pathnode.loc")
|
|
pathnode.loc.x = wp.x
|
|
pathnode.loc.y = wp.y
|
|
pathnode.loc.c = wp.c
|
|
pathnode.ignore = true
|
|
pathnode.map_desc = wp.map_desc
|
|
pathnode.map_desc_chain = last_path[k + 1]
|
|
pathnode.local_allocated = true
|
|
pathnode.cluster = last_path[k + 1].cluster
|
|
table.insert(real_path, pathnode) -- Technically, we'll end up with the distance to the next objective. I'm okay with this.
|
|
|
|
if not condense_class and wp.condense_class then
|
|
condense_start, condense_class = #real_path, wp.condense_class
|
|
end
|
|
if condense_class then
|
|
condense_to = wp.map_desc
|
|
end
|
|
end end
|
|
|
|
if condense_class then condense_doit() end -- in case we have stuff left over
|
|
end
|
|
|
|
if progress then progress:SetPercentage(k / #last_path) end
|
|
end
|
|
|
|
for _, v in pairs(notification_funcs) do
|
|
QH_Timeslice_Yield()
|
|
v(real_path)
|
|
end
|
|
|
|
-- I hate having to do this, I feel like I'm just begging for horrifying bugs
|
|
if cleanup_path then
|
|
for k, v in ipairs(cleanup_path) do
|
|
if v.local_allocated then
|
|
QuestHelper:ReleaseTable(v.loc)
|
|
QuestHelper:ReleaseTable(v)
|
|
end
|
|
end
|
|
|
|
QuestHelper:ReleaseTable(cleanup_path)
|
|
cleanup_path = nil
|
|
end
|
|
|
|
cleanup_path = real_path
|
|
|
|
QH_Timeslice_Yield()
|
|
end
|
|
|
|
local filters = {}
|
|
|
|
function QH_Route_RegisterFilter(filter)
|
|
QuestHelper: Assert(not filters[filter.name])
|
|
QuestHelper: Assert(filter)
|
|
filters[filter.name] = filter
|
|
end
|
|
|
|
-- we deal very badly with changing the requirement links after things are set up, so right now we're just relying on the fact that everything is unchanging afterwards
|
|
-- this is one reason the API is not considered stable :P
|
|
local function ScanNode(node, ...)
|
|
local stupid_lua = {...}
|
|
Route_Core_EarlyExit()
|
|
table.insert(pending, function ()
|
|
for k, v in pairs(filters) do
|
|
if v:Process(node, unpack(stupid_lua)) then
|
|
Route_Core_IgnoreNode(node, v)
|
|
else
|
|
Route_Core_UnignoreNode(node, v)
|
|
end
|
|
end
|
|
end)
|
|
end
|
|
|
|
local function ScanCluster(clust)
|
|
Route_Core_EarlyExit()
|
|
table.insert(pending, function ()
|
|
for _, v in ipairs(clust) do
|
|
ScanNode(v)
|
|
end
|
|
end)
|
|
end
|
|
|
|
local show_debug_commands = false
|
|
|
|
function QH_Route_Filter_Rescan_Now()
|
|
Route_Core_TraverseNodes(function (...)
|
|
ScanNode(...)
|
|
end)
|
|
end
|
|
|
|
function QH_Route_Filter_Rescan(name, suppress_earlyexit)
|
|
if not suppress_earlyexit then Route_Core_EarlyExit() --[[print("ee rscn", (debugstack(2, 1, 0):gsub("\n...", "")))]] end
|
|
QuestHelper: Assert(not name or filters[name] or name == "user_manual_ignored")
|
|
table.insert(pending, function ()
|
|
if show_debug_commands then print("delayed qrfr") end
|
|
QH_Route_Filter_Rescan_Now() -- yeah, so we're really rescanning every node, aren't we. laaaazy
|
|
end)
|
|
end
|
|
|
|
function QH_Route_IgnoreNode(node, reason)
|
|
Route_Core_EarlyExit() --print("ee in")
|
|
table.insert(pending, function () if show_debug_commands then print("delayed qrin") end Route_Core_IgnoreNode(node, reason) end)
|
|
end
|
|
|
|
function QH_Route_UnignoreNode(node, reason)
|
|
Route_Core_EarlyExit() --print("ee uin")
|
|
table.insert(pending, function () if show_debug_commands then print("delayed qrun") end Route_Core_UnignoreNode(node, reason) end)
|
|
end
|
|
|
|
function QH_Route_ClusterAdd(clust)
|
|
for _, v in ipairs(clust) do
|
|
QuestHelper: Assert(v.cluster == clust)
|
|
end
|
|
Route_Core_EarlyExit() --print("ee ca")
|
|
table.insert(pending, function () if show_debug_commands then print("delayed qrca1") end Route_Core_ClusterAdd(clust) end)
|
|
rescan_it_all = true
|
|
end
|
|
|
|
function QH_Route_ClusterRemove(clust)
|
|
Route_Core_EarlyExit() --print("ee cre")
|
|
table.insert(pending, function () if show_debug_commands then print("delayed qrcrm") end Route_Core_ClusterRemove(clust) end)
|
|
end
|
|
|
|
function QH_Route_ClusterRequires(a, b)
|
|
Route_Core_EarlyExit() --print("ee cr")
|
|
table.insert(pending, function () if show_debug_commands then print("delayed qrcrq") end Route_Core_ClusterRequires(a, b) end)
|
|
end
|
|
|
|
function QH_Route_IgnoreCluster(clust, reason)
|
|
Route_Core_EarlyExit() --print("ee ic")
|
|
table.insert(pending, function () if show_debug_commands then print("delayed qric") end Route_Core_IgnoreCluster(clust, reason) end)
|
|
end
|
|
|
|
function QH_Route_UnignoreCluster(clust, reason)
|
|
Route_Core_EarlyExit() --print("ee uic")
|
|
table.insert(pending, function () if show_debug_commands then print("delayed qruc") end Route_Core_UnignoreCluster(clust, reason) end)
|
|
end
|
|
|
|
function QH_Route_SetClusterPriority(clust, pri)
|
|
QuestHelper: Assert(clust)
|
|
Route_Core_EarlyExit() --print("ee scp")
|
|
table.insert(pending, function () if show_debug_commands then print("delayed qrscp") end Route_Core_SetClusterPriority(clust, pri) end)
|
|
end
|
|
|
|
local pending_recalc = false
|
|
function QH_Route_FlightPathRecalc()
|
|
if not pending_recalc then
|
|
pending_recalc = true
|
|
Route_Core_EarlyExit() --print("ee recalc")
|
|
table.insert(pending, function () if show_debug_commands then print("delayed qrfpr") end pending_recalc = false QH_redo_flightpath() pathcache_active = new_pathcache_table() pathcache_inactive = new_pathcache_table() Route_Core_DistanceClear() ReplotPath() end)
|
|
end
|
|
end
|
|
QH_Route_FlightPathRecalc() -- heh heh
|
|
|
|
-- Right now we just defer to the existing ones
|
|
function QH_Route_TraverseNodes(func)
|
|
return Route_Core_TraverseNodes(func)
|
|
end
|
|
function QH_Route_TraverseClusters(func)
|
|
return Route_Core_TraverseClusters(func)
|
|
end
|
|
function QH_Route_IgnoredReasons_Cluster(clust, func)
|
|
return Route_Core_IgnoredReasons_Cluster(clust, func)
|
|
end
|
|
function QH_Route_IgnoredReasons_Node(node, func)
|
|
return Route_Core_IgnoredReasons_Node(node, func)
|
|
end
|
|
function QH_Route_Ignored_Cluster(clust)
|
|
return Route_Core_Ignored_Cluster(clust)
|
|
end
|
|
function QH_Route_Ignored_Cluster_Active(clust)
|
|
return Route_Core_Ignored_Cluster_Active(clust)
|
|
end
|
|
function QH_Route_GetClusterPriority(clust)
|
|
return Route_Core_GetClusterPriority(clust)
|
|
end
|
|
|
|
|
|
|
|
Route_Core_Init(
|
|
function(path, progress)
|
|
last_path = path
|
|
ReplotPath(progress)
|
|
end,
|
|
function(loc1, loctable, reverse, complete_pass)
|
|
if #loctable == 0 then return QuestHelper:CreateTable("null response") end
|
|
|
|
QH_Timeslice_Yield()
|
|
|
|
QuestHelper: Assert(loc1)
|
|
QuestHelper: Assert(loc1.loc)
|
|
|
|
local lt = QuestHelper:CreateTable("route controller path shunt loctable")
|
|
for _, v in ipairs(loctable) do
|
|
QuestHelper: Assert(v.loc)
|
|
QuestHelper: Assert(type(v.loc) == "table")
|
|
table.insert(lt, v.loc)
|
|
end
|
|
QuestHelper: Assert(#loctable == #lt)
|
|
|
|
local rvv
|
|
|
|
if not reverse then
|
|
if not pathcache_active[loc1] then pathcache_active[loc1] = new_pathcache_table() end
|
|
if not pathcache_inactive[loc1] then pathcache_inactive[loc1] = new_pathcache_table() end
|
|
else
|
|
for _, v in ipairs(loctable) do
|
|
if not pathcache_active[v] then pathcache_active[v] = new_pathcache_table() end
|
|
if not pathcache_inactive[v] then pathcache_inactive[v] = new_pathcache_table() end
|
|
end
|
|
end
|
|
|
|
rvv = QuestHelper:CreateTable("route controller path shunt returnvalue")
|
|
local rv = QH_Graph_Pathmultifind(loc1.loc, lt, reverse, true)
|
|
--QuestHelper: Assert(#lt == #rv, string.format("lt has %d items, rt has %d items. Both should be the same.", #lt, #rv))
|
|
|
|
-- We want to store the math.max(sqrt(#rv), 10) shortest paths
|
|
local tostore = complete_pass and math.max(sqrt(#rv), 10) or #rv
|
|
--print("would store", #rv, "am store", tostore)
|
|
local linkity = QuestHelper:CreateTable("shortest path summary")
|
|
for k, v in ipairs(rv) do
|
|
local tk = QuestHelper:CreateTable("shortest path summary item")
|
|
tk.k = k
|
|
tk.v = v
|
|
table.insert(linkity, tk)
|
|
|
|
rvv[k] = rv[k].d
|
|
end
|
|
|
|
table.sort(linkity, function(a, b) return a.v.d < b.v.d end)
|
|
while #linkity > tostore do
|
|
local rip = table.remove(linkity)
|
|
QuestHelper:ReleaseTable(rip.v)
|
|
QuestHelper:ReleaseTable(rip)
|
|
end
|
|
|
|
for _, it in pairs(linkity) do
|
|
local k, v = it.k, it.v
|
|
|
|
if not rv[k] then
|
|
QuestHelper:TextOut(QuestHelper:StringizeTable(loc1.loc))
|
|
QuestHelper:TextOut(QuestHelper:StringizeTable(lt[k]))
|
|
end
|
|
QuestHelper: Assert(rv[k], string.format("%d to %d", loc1.loc.p, loctable[k].loc.p))
|
|
QuestHelper: Assert(rv[k].d)
|
|
|
|
-- We're only setting the inactive to give the garbage collector potentially a little more to clean up (i.e. the old path.)
|
|
if not reverse then
|
|
QuestHelper: Assert(pathcache_active[loc1])
|
|
QuestHelper: Assert(pathcache_inactive[loc1])
|
|
pathcache_active[loc1][loctable[k]] = rv[k]
|
|
pathcache_inactive[loc1][loctable[k]] = rv[k]
|
|
else
|
|
QuestHelper: Assert(loctable[k])
|
|
QuestHelper: Assert(pathcache_active[loctable[k]])
|
|
QuestHelper: Assert(pathcache_inactive[loctable[k]])
|
|
pathcache_active[loctable[k]][loc1] = rv[k]
|
|
pathcache_inactive[loctable[k]][loc1] = rv[k]
|
|
end
|
|
end
|
|
|
|
for _, v in ipairs(linkity) do
|
|
-- we do not release v.v, since that's now stored in our path cache
|
|
QuestHelper:ReleaseTable(v)
|
|
end
|
|
QuestHelper:ReleaseTable(linkity)
|
|
QuestHelper:ReleaseTable(lt)
|
|
QuestHelper:ReleaseTable(rv) -- this had better be releasable
|
|
|
|
return rvv
|
|
end
|
|
)
|
|
|
|
local StartObjective = {desc = "Start", tracker_hidden = true} -- this should never be displayed
|
|
|
|
local lapa = GetTime()
|
|
local passcount = 0
|
|
|
|
local lc, lx, ly, lrc, lrz
|
|
|
|
local last_playerpos = nil
|
|
|
|
local function ReleaseShard(ki, shard)
|
|
for k, tv in pairs(shard) do
|
|
if not pathcache_active[ki] or not pathcache_active[ki][k] then QuestHelper:ReleaseTable(tv) end
|
|
end
|
|
QuestHelper:ReleaseTable(shard)
|
|
end
|
|
|
|
local function process()
|
|
|
|
local last_cull = 0
|
|
local last_movement = 0
|
|
|
|
local first = true
|
|
-- Order here is important. We don't want to update the location, then wait for a while as we add nodes. We also need the location updated before the first nodes are added. This way, it all works and we don't need anything outside the loop.
|
|
while true do
|
|
if last_cull + 120 < GetTime() then
|
|
last_cull = GetTime()
|
|
|
|
for k, v in pairs(pathcache_inactive) do
|
|
ReleaseShard(k, v)
|
|
end
|
|
QuestHelper:ReleaseTable(pathcache_inactive)
|
|
|
|
pathcache_inactive = pathcache_active
|
|
pathcache_active = new_pathcache_table()
|
|
end
|
|
|
|
if last_movement + 1 < GetTime() then
|
|
local c, x, y, rc, rz = QuestHelper.routing_ac, QuestHelper.routing_ax, QuestHelper.routing_ay, QuestHelper.routing_c, QuestHelper.routing_z -- ugh we need a better solution to this, but with this weird "planes" hybrid there just isn't one right now
|
|
if c and x and y and rc and rz and (c ~= lc or x ~= lx or y ~= ly or rc ~= lrc or rz ~= lrz) then
|
|
--local t = GetTime()
|
|
lc, lx, ly, lrc, lrz = c, x, y, rc, rz
|
|
|
|
local new_playerpos = {desc = "Start", why = StartObjective, loc = NewLoc(c, x, y, rc, rz), tracker_hidden = true, ignore = true}
|
|
Route_Core_SetStart(new_playerpos)
|
|
if last_path then last_path[1] = new_playerpos end
|
|
--QuestHelper: TextOut(string.format("SS takes %f", GetTime() - t))
|
|
ReplotPath()
|
|
|
|
if last_playerpos then
|
|
-- if it's in active, then it must be in inactive as well, so we do our actual deallocation in inactive only
|
|
if pathcache_active[last_playerpos] then QuestHelper:ReleaseTable(pathcache_active[last_playerpos]) pathcache_active[last_playerpos] = nil end
|
|
for k, v in pairs(pathcache_active) do v[last_playerpos] = nil end
|
|
|
|
if pathcache_inactive[last_playerpos] then ReleaseShard(last_playerpos, pathcache_inactive[last_playerpos]) pathcache_inactive[last_playerpos] = nil end
|
|
for k, v in pairs(pathcache_inactive) do if v[last_playerpos] then QuestHelper:ReleaseTable(v[last_playerpos]) v[last_playerpos] = nil end end
|
|
end
|
|
|
|
last_playerpos = new_playerpos
|
|
|
|
last_movement = GetTime()
|
|
end
|
|
end
|
|
|
|
if not first then
|
|
Route_Core_Process()
|
|
QH_Timeslice_Doneinit()
|
|
|
|
-- Wackyland code here
|
|
if QH_WACKYLAND then
|
|
QH_Route_Filter_Rescan()
|
|
QH_Route_TraverseClusters(function (clust) QH_Route_SetClusterPriority(clust, math.random(-2, 2)) end)
|
|
end
|
|
end
|
|
first = false
|
|
|
|
passcount = passcount + 1
|
|
if lapa + 60 < GetTime() then
|
|
if debug_output then QuestHelper:TextOut(string.format("%d passes in the last minute, %d nodes", passcount, Route_Core_NodeCount())) end
|
|
lapa = lapa + 60
|
|
passcount = 0
|
|
end
|
|
|
|
QH_Timeslice_Yield()
|
|
|
|
-- snag stuff so we don't accidentally end up changing pending in two things at once
|
|
while #pending > 0 do
|
|
local lpending = pending
|
|
pending = {}
|
|
|
|
for k, v in ipairs(lpending) do
|
|
v()
|
|
QH_Timeslice_Yield()
|
|
end
|
|
end
|
|
|
|
if rescan_it_all then
|
|
rescan_it_all = false
|
|
--[[ assert(#pending == 0) ]] -- assert that everything is consistent after the scan
|
|
QH_Route_Filter_Rescan_Now()
|
|
end
|
|
end
|
|
end
|
|
|
|
-- 4.0.3a Breakage related
|
|
QH_Timeslice_Add(process, "new_routing")
|