Module: Prime::AsyncTableMixin
- Extended by:
- MotionSupport::Concern
- Defined in:
- motion-prime/sections/_async_table_mixin.rb
Defined Under Namespace
Modules: ClassMethods
Instance Method Summary collapse
-
#async_data? ⇒ Boolean
Returns true if table section have enabled async data.
- #height_for_index(index) ⇒ Object
- #on_async_data_loaded ⇒ Object
- #on_cell_section_preloaded(section, index) ⇒ Object
- #on_queue_preloaded(queue_id, loaded_index) ⇒ Object
-
#preload_sections_after(from_index) ⇒ NSIndexPath, Boolean
Preloads sections after rendering cell in current sheduled index or given index.
-
#preload_sections_schedule_from(index, load_count) ⇒ Integer
Schedules preloading sections starting with given index with given limit.
- #preloader_index_service ⇒ Object
- #render_cell(index) ⇒ Object
-
#reset_collection_data ⇒ Boolean
Reset async loaded table data and preloader queue.
- #table_element_options ⇒ Object
Instance Method Details
#async_data? ⇒ Boolean
Returns true if table section have enabled async data. False by defaul.
12 13 14 |
# File 'motion-prime/sections/_async_table_mixin.rb', line 12 def async_data? self.class. end |
#height_for_index(index) ⇒ Object
34 35 36 37 38 39 40 41 42 |
# File 'motion-prime/sections/_async_table_mixin.rb', line 34 def height_for_index(index) section = cell_section_by_index(index) unless section Prime.logger.debug "could not find section with index #{index} for #{self.to_s}" return 0 end preload_section_by_index(index) section.container_height end |
#on_async_data_loaded ⇒ Object
49 |
# File 'motion-prime/sections/_async_table_mixin.rb', line 49 def on_async_data_loaded; end |
#on_cell_section_preloaded(section, index) ⇒ Object
51 |
# File 'motion-prime/sections/_async_table_mixin.rb', line 51 def on_cell_section_preloaded(section, index); end |
#on_queue_preloaded(queue_id, loaded_index) ⇒ Object
50 |
# File 'motion-prime/sections/_async_table_mixin.rb', line 50 def on_queue_preloaded(queue_id, loaded_index); end |
#preload_sections_after(from_index) ⇒ NSIndexPath, Boolean
Preloads sections after rendering cell in current sheduled index or given index. TODO: probably should be in separate class.
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'motion-prime/sections/_async_table_mixin.rb', line 58 def preload_sections_after(from_index) return unless async_data? service = preloader_index_service load_limit = self.class..try(:[], :preload_cells_count) if @preloader_next_starts_from index_to_start_preloading = service.sum_index(@preloader_next_starts_from, load_limit ? -load_limit/2 : 0) # should we start preload based on index of rendered cell return false if service.compare_indexes(from_index, index_to_start_preloading) < 0 end # adjust start/finish points based on current queues current_group = from_index.section left_to_load_in_group = cell_sections_for_group(current_group).count - from_index.row load_count = [left_to_load_in_group, load_limit].compact.min to_index = service.sum_index(from_index, load_count - 1) @preloader_next_starts_from = to_index Array.wrap(@preloader_queue).each do |queue_info| # cancelled and dealloc are left from prev data next unless [:in_progress, :completed].include?(queue_info[:state]) # filter by current group next unless queue_info[:from_index].section == current_group # reject not started threads next if queue_info[:to_index].nil? && queue_info[:state] != :in_progress if from_index.row >= queue_info[:from_index].row from_index = NSIndexPath.indexPathForRow([from_index.row, queue_info[:to_index].try(:row).try(:+, 1), (queue_info[:target_index] if queue_info[:state] == :in_progress).try(:row).try(:+, 1)].compact.max, inSection: current_group) else to_index = NSIndexPath.indexPathForRow([to_index.row, queue_info[:from_index].try(:row).try(:-, 1)].compact.min, inSection: current_group) end end load_count = to_index.row - from_index.row + 1 preload_sections_schedule_from(from_index, load_count) if load_count > 0 end |
#preload_sections_schedule_from(index, load_count) ⇒ Integer
Schedules preloading sections starting with given index with given limit. TODO: probably should be in separate class.
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'motion-prime/sections/_async_table_mixin.rb', line 101 def preload_sections_schedule_from(index, load_count) service = preloader_index_service @preloader_queue ||= [] # TODO: we do we need to keep screen ref too? queue_id = @preloader_queue.count allocate_strong_references(queue_id) @preloader_queue[queue_id] = { state: :in_progress, target_index: service.sum_index(index, load_count-1), from_index: index } BW::Reactor.schedule(queue_id) do |queue_id| result = load_count.times do |offset| if @preloader_queue[queue_id][:state] == :cancelled release_strong_references(queue_id) break end if allocated_references_released? @preloader_queue[queue_id][:state] = :dealloc release_strong_references(queue_id) break end if section = preload_section_by_index(index) on_cell_section_preloaded(section, index) end @preloader_queue[queue_id][:to_index] = index unless offset == load_count - 1 index = service.sum_index(index, 1) end true end if result @preloader_queue[queue_id][:state] = :completed on_queue_preloaded(queue_id, index) end release_strong_references(queue_id) end queue_id end |
#preloader_index_service ⇒ Object
149 150 151 |
# File 'motion-prime/sections/_async_table_mixin.rb', line 149 def preloader_index_service TableDataIndexes.new(@data) end |
#render_cell(index) ⇒ Object
44 45 46 47 |
# File 'motion-prime/sections/_async_table_mixin.rb', line 44 def render_cell(index) preload_sections_after(index) super end |
#reset_collection_data ⇒ Boolean
Reset async loaded table data and preloader queue.
27 28 29 30 31 32 |
# File 'motion-prime/sections/_async_table_mixin.rb', line 27 def reset_collection_data super # must be before to update fixed_collection_data @async_loaded_data = async_data? ? fixed_collection_data : nil Array.wrap(@preloader_queue).each { |queue| queue[:state] = :cancelled } @preloader_next_starts_from = nil end |
#table_element_options ⇒ Object
16 17 18 19 20 21 22 |
# File 'motion-prime/sections/_async_table_mixin.rb', line 16 def = super if async_data? && self.class..has_key?(:estimated_cell_height) [:estimated_cell_height] = self.class.[:estimated_cell_height] end end |