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
-- @tparam DruidEvent self
-- @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(callback) == "function", "Callback should be function")
table.insert(self._callbacks, callback)
table.insert(self._callbacks, {
callback = callback,
context = context
})
return callback
end
@ -35,10 +39,11 @@ end
--- Unsubscribe callback on event
-- @tparam DruidEvent self
-- @tparam function callback Callback itself
function DruidEvent.unsubscribe(self, callback)
for i = 1, #self._callbacks do
if self._callbacks[i] == callback then
table.remove(self._callbacks, i)
-- @tparam table context Additional context as first param to callback call
function DruidEvent.unsubscribe(self, callback, context)
for index, callback_info in ipairs(self._callbacks) do
if callback_info.callback == callback and callback_info.context == context then
table.remove(self._callbacks, index)
return
end
end
@ -64,8 +69,12 @@ end
-- @tparam DruidEvent self
-- @tparam any ... All event params
function DruidEvent.trigger(self, ...)
for i = 1, #self._callbacks do
self._callbacks[i](...)
for index, callback_info in ipairs(self._callbacks) do
if callback_info.context then
callback_info.callback(callback_info.context, ...)
else
callback_info.callback(...)
end
end
end

View File

@ -4,7 +4,7 @@ local const = require("druid.const")
local helper = require("druid.helper")
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)
@ -25,20 +25,12 @@ function M:init(data_list, scroll, grid, create_function)
self.components = {}
self:_refresh()
self.scroll.on_scroll:subscribe(function() self._check_elements(self) end)
self.scroll.on_scroll:subscribe(self._check_elements, self)
end
function M:on_remove()
-- TODO: make this work
-- self.scroll.on_scroll:unsubscribe(self._check_elements)
end
function M:update(dt)
if self.scroll.animate then
self:_check_elements()
end
self.scroll.on_scroll:unsubscribe(self._check_elements, self)
end
@ -48,6 +40,44 @@ function M:set_data(data_list)
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)
self.top_index = helper.clamp(index, 1, #self.data)
self:_refresh()
@ -90,66 +120,46 @@ end
function M:_check_elements()
self.last_index = self.top_index
for index, node in pairs(self.nodes) do
if self.scroll:is_node_in_view(node) then
self.top_index = index
break
self.last_index = index
end
end
-- make items from (top_index upside
local is_top_outside = false
local cur_index = self.top_index - 1
while not is_top_outside do
if not self.data[cur_index] then
break
end
self:_check_elements_from(self.top_index - 1, -1)
self:_check_elements_from(self.top_index, 1)
if not self.nodes[cur_index] then
self:_add_at(cur_index)
end
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
for index, node in pairs(self.nodes) do
self.top_index = math.min(self.top_index or index, index)
self.last_index = math.max(self.last_index or index, index)
end
end
-- make items from [top_index downsize
local is_bot_outside = false
cur_index = self.top_index
while not is_bot_outside do
if not self.data[cur_index] then
function M:_check_elements_from(index, step)
local is_outside = false
while not is_outside do
if not self.data[index] then
break
end
if not self.nodes[cur_index] then
self:_add_at(cur_index)
if not self.nodes[index] then
self:_add_at(index)
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:
local remove_index = cur_index + 1
local remove_index = index
while self.nodes[remove_index] do
self:_remove_at(remove_index)
remove_index = remove_index + 1
remove_index = remove_index + step
end
else
self.last_index = cur_index
end
cur_index = cur_index + 1
index = index + step
end
end