Update infinity_list, add optional context to druid event

This commit is contained in:
Insality 2020-11-29 21:37:42 +03:00
parent e9a8dd0795
commit de5dad8874
2 changed files with 78 additions and 59 deletions

View File

@ -22,11 +22,15 @@ end
--- Subscribe callback on event --- Subscribe callback on event
-- @tparam DruidEvent self -- @tparam DruidEvent self
-- @tparam function callback Callback itself -- @tparam function callback Callback itself
function DruidEvent.subscribe(self, callback) -- @tparam table context Additional context as first param to callback call
function DruidEvent.subscribe(self, callback, context)
assert(type(self) == "table", "You should subscribe to event with : syntax") assert(type(self) == "table", "You should subscribe to event with : syntax")
assert(type(callback) == "function", "Callback should be function") assert(type(callback) == "function", "Callback should be function")
table.insert(self._callbacks, callback) table.insert(self._callbacks, {
callback = callback,
context = context
})
return callback return callback
end end
@ -35,10 +39,11 @@ end
--- Unsubscribe callback on event --- Unsubscribe callback on event
-- @tparam DruidEvent self -- @tparam DruidEvent self
-- @tparam function callback Callback itself -- @tparam function callback Callback itself
function DruidEvent.unsubscribe(self, callback) -- @tparam table context Additional context as first param to callback call
for i = 1, #self._callbacks do function DruidEvent.unsubscribe(self, callback, context)
if self._callbacks[i] == callback then for index, callback_info in ipairs(self._callbacks) do
table.remove(self._callbacks, i) if callback_info.callback == callback and callback_info.context == context then
table.remove(self._callbacks, index)
return return
end end
end end
@ -64,8 +69,12 @@ end
-- @tparam DruidEvent self -- @tparam DruidEvent self
-- @tparam any ... All event params -- @tparam any ... All event params
function DruidEvent.trigger(self, ...) function DruidEvent.trigger(self, ...)
for i = 1, #self._callbacks do for index, callback_info in ipairs(self._callbacks) do
self._callbacks[i](...) if callback_info.context then
callback_info.callback(callback_info.context, ...)
else
callback_info.callback(...)
end
end end
end end

View File

@ -4,7 +4,7 @@ local const = require("druid.const")
local helper = require("druid.helper") local helper = require("druid.helper")
local component = require("druid.component") local component = require("druid.component")
local M = component.create("infinity_list", { const.ON_UPDATE }) local M = component.create("infinity_list")
function M:init(data_list, scroll, grid, create_function) function M:init(data_list, scroll, grid, create_function)
@ -25,20 +25,12 @@ function M:init(data_list, scroll, grid, create_function)
self.components = {} self.components = {}
self:_refresh() self:_refresh()
self.scroll.on_scroll:subscribe(function() self._check_elements(self) end) self.scroll.on_scroll:subscribe(self._check_elements, self)
end end
function M:on_remove() function M:on_remove()
-- TODO: make this work self.scroll.on_scroll:unsubscribe(self._check_elements, self)
-- self.scroll.on_scroll:unsubscribe(self._check_elements)
end
function M:update(dt)
if self.scroll.animate then
self:_check_elements()
end
end end
@ -48,6 +40,44 @@ function M:set_data(data_list)
end end
function M:add(data, index)
table.insert(self.data, index, data)
self:_refresh()
end
function M:remove(index, shift_policy)
table.remove(self.data, index)
self:_refresh()
end
function M:clear()
self.data = {}
self:_refresh()
end
function M:get_first_index()
return self.top_index
end
function M:get_last_index()
return self.last_index
end
function M:get_index(data)
for index, value in pairs(self.data) do
if value == data then
return index
end
end
return nil
end
function M:scroll_to_index(index) function M:scroll_to_index(index)
self.top_index = helper.clamp(index, 1, #self.data) self.top_index = helper.clamp(index, 1, #self.data)
self:_refresh() self:_refresh()
@ -90,66 +120,46 @@ end
function M:_check_elements() function M:_check_elements()
self.last_index = self.top_index
for index, node in pairs(self.nodes) do for index, node in pairs(self.nodes) do
if self.scroll:is_node_in_view(node) then if self.scroll:is_node_in_view(node) then
self.top_index = index self.top_index = index
break self.last_index = index
end end
end end
-- make items from (top_index upside self:_check_elements_from(self.top_index - 1, -1)
local is_top_outside = false self:_check_elements_from(self.top_index, 1)
local cur_index = self.top_index - 1
while not is_top_outside do
if not self.data[cur_index] then
break
end
if not self.nodes[cur_index] then for index, node in pairs(self.nodes) do
self:_add_at(cur_index) self.top_index = math.min(self.top_index or index, index)
end self.last_index = math.max(self.last_index or index, index)
if not self.scroll:is_node_in_view(self.nodes[cur_index]) then
is_top_outside = true
-- remove nexts:
local remove_index = cur_index - 1
while self.nodes[remove_index] do
self:_remove_at(remove_index)
remove_index = remove_index - 1
end
end
cur_index = cur_index - 1
end end
end
-- make items from [top_index downsize
local is_bot_outside = false function M:_check_elements_from(index, step)
cur_index = self.top_index local is_outside = false
while not is_bot_outside do while not is_outside do
if not self.data[cur_index] then if not self.data[index] then
break break
end end
if not self.nodes[cur_index] then if not self.nodes[index] then
self:_add_at(cur_index) self:_add_at(index)
end end
if not self.scroll:is_node_in_view(self.nodes[cur_index]) then
is_bot_outside = true if not self.scroll:is_node_in_view(self.nodes[index]) then
is_outside = true
-- remove nexts: -- remove nexts:
local remove_index = cur_index + 1 local remove_index = index
while self.nodes[remove_index] do while self.nodes[remove_index] do
self:_remove_at(remove_index) self:_remove_at(remove_index)
remove_index = remove_index + 1 remove_index = remove_index + step
end end
else
self.last_index = cur_index
end end
cur_index = cur_index + 1 index = index + step
end end
end end