2
0
mirror of https://github.com/koreader/koreader synced 2024-11-13 19:11:25 +00:00
koreader/frontend/depgraph.lua
Qingping Hou 9b7aba3fba fix: override readerhighlight hold in readerfooter
Also fix touch zone dependency graph generation code.

ReaderHighlight has now been migrated to use touch zone

Inputcontainer's touch event handling logic changed to only stop
propagation when handler returns `true`. Previously, it stops
propagation when a handler is found. This is needed to support
both readerhighlight_tap and tap_forward touch zones.
2017-01-30 05:53:44 -08:00

107 lines
3.1 KiB
Lua

--[[--
DepGraph module.
Library for constructing dependency graphs.
Example:
local dg = DepGraph:new{}
dg:addNode('a1', {'a2', 'b1'})
dg:addNode('b1', {'a2', 'c1'})
dg:addNode('c1')
-- The return value of dg:serialize() will be:
-- {'a2', 'c1', 'b1', 'a1'}
]]
local DepGraph = {}
function DepGraph:new(new_o)
local o = new_o or {}
o.nodes = {}
setmetatable(o, self)
self.__index = self
return o
end
function DepGraph:addNode(node_key, deps)
if not self.nodes[node_key] then
self.nodes[node_key] = {}
end
if not deps then return end
local node_deps = {}
for _,dep_node_key in ipairs(deps) do
if not self.nodes[dep_node_key] then
self.nodes[dep_node_key] = {}
end
table.insert(node_deps, dep_node_key)
end
self.nodes[node_key].deps = node_deps
end
function DepGraph:removeNode(node_key)
self.nodes[node_key] = nil
for curr_node_key, curr_node in pairs(self.nodes) do
if curr_node.deps then
local remove_idx
for idx, dep_node_key in ipairs(self.nodes) do
if dep_node_key == node_key then
remove_idx = idx
break
end
end
if remove_idx then table.remove(curr_node.deps, remove_idx) end
end
end
end
function DepGraph:addNodeDep(node_key, dep_node_key)
local node = self.nodes[node_key]
if not node then
node = {}
self.nodes[node_key] = node
end
if not node.deps then node.deps = {} end
table.insert(node.deps, dep_node_key)
end
function DepGraph:serialize()
local visited = {}
local ordered_nodes = {}
for node_key,_ in pairs(self.nodes) do
if not visited[node_key] then
local queue = {node_key}
while #queue > 0 do
local pos = #queue
local curr_node_key = queue[pos]
local curr_node = self.nodes[curr_node_key]
local all_deps_visited = true
if curr_node.deps then
for _, dep_node_key in ipairs(curr_node.deps) do
if not visited[dep_node_key] then
-- only insert to queue for later process if node
-- has dependencies
if self.nodes[dep_node_key].deps then
table.insert(queue, dep_node_key)
else
table.insert(ordered_nodes, dep_node_key)
end
visited[dep_node_key] = true
all_deps_visited = false
break
end
end
end
if all_deps_visited then
visited[curr_node_key] = true
table.remove(queue, pos)
table.insert(ordered_nodes, curr_node_key)
end
end
end
end
return ordered_nodes
end
return DepGraph