134 lines
3.1 KiB
Lua
134 lines
3.1 KiB
Lua
--[[
|
|
This file is part of Ice Lua Components.
|
|
|
|
Ice Lua Components is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
Ice Lua Components is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
along with Ice Lua Components. If not, see <http://www.gnu.org/licenses/>.
|
|
]]
|
|
|
|
function collect_new_prioq(fn_compare)
|
|
local this = {} this.this = this
|
|
|
|
local DEBUG_HEAP_ASSERT = false
|
|
|
|
function this.clear()
|
|
this.q = {}
|
|
end
|
|
|
|
local function prv_debug_check_heap(idx)
|
|
local cidx = idx*2
|
|
if cidx > #(this.q) then return end
|
|
|
|
if fn_compare(this.q[cidx], this.q[idx]) then error("heap check failed") end
|
|
prv_debug_check_heap(cidx)
|
|
if cidx+1 <= #(this.q) then
|
|
if fn_compare(this.q[cidx+1], this.q[idx]) then error("heap check failed") end
|
|
prv_debug_check_heap(cidx+1)
|
|
end
|
|
end
|
|
|
|
local function prv_sift_down(idx)
|
|
while idx*2 <= #(this.q) do
|
|
-- find highest prio child
|
|
local cidx = idx*2
|
|
if cidx+1 <= #(this.q) and fn_compare(this.q[cidx+1], this.q[cidx]) then
|
|
cidx = cidx + 1
|
|
end
|
|
|
|
-- swap if necessary
|
|
if fn_compare(this.q[cidx], this.q[idx]) then
|
|
this.q[idx], this.q[cidx] = this.q[cidx], this.q[idx]
|
|
idx = cidx
|
|
else
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
function this.push(v)
|
|
local idx = #(this.q)+1
|
|
this.q[idx] = v
|
|
|
|
-- sift up
|
|
while idx > 1 do
|
|
-- check parent
|
|
local pidx = math.floor(idx/2)
|
|
if fn_compare(this.q[idx], this.q[pidx]) then
|
|
this.q[idx], this.q[pidx] = this.q[pidx], this.q[idx]
|
|
idx = pidx
|
|
else
|
|
break
|
|
end
|
|
end
|
|
|
|
-- sift down
|
|
prv_sift_down(idx)
|
|
|
|
if DEBUG_HEAP_ASSERT then prv_debug_check_heap(1) end
|
|
end
|
|
|
|
function this.pop()
|
|
local qlen = #(this.q)
|
|
if qlen == 0 then return nil end
|
|
local v = this.q[1]
|
|
this.q[1] = this.q[qlen]
|
|
this.q[qlen] = nil
|
|
if this.q[1] then prv_sift_down(1) end
|
|
if DEBUG_HEAP_ASSERT then prv_debug_check_heap(1) end
|
|
return v
|
|
end
|
|
|
|
function this.empty()
|
|
return #(this.q) == 0
|
|
end
|
|
|
|
this.clear()
|
|
|
|
return this
|
|
end
|
|
|
|
function collect_new_history_buf()
|
|
local this = {history={""}, pos=1}
|
|
|
|
-- Return the first value from the history.
|
|
function this.shift()
|
|
return table.remove(this.history, 1)
|
|
end
|
|
|
|
-- Get the length of the history.
|
|
function this.length()
|
|
return #this.history
|
|
end
|
|
|
|
function this.next()
|
|
this.pos = math.min(#this.history, this.pos + 1)
|
|
return this.history[this.pos]
|
|
end
|
|
|
|
function this.prev()
|
|
this.pos = math.max(1, this.pos - 1)
|
|
return this.history[this.pos]
|
|
end
|
|
|
|
-- Update the newest node
|
|
function this.edit(text)
|
|
this.history[#this.history] = text
|
|
end
|
|
|
|
-- Commit the current node
|
|
function this.append()
|
|
table.insert(this.history, "")
|
|
this.pos = #this.history
|
|
end
|
|
|
|
return this
|
|
end |