Created
April 14, 2015 10:57
-
-
Save mstubna/f1529160ae0268a355df to your computer and use it in GitHub Desktop.
Lazy loader that can be used for backing a view collection in order to keep a small number of views loaded. Appropriate for use in a scrolling image gallery for example.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class @LazyLoader | |
# Queue that lazily constructs new items only as required to keep the buffers full | |
# If objects in the queue back a corresponding view, they should implement a destroy_view() function so that they can be properly garbage collected | |
# - object_constructor should be a function that accepts a single argument - the index of the newly constructed object | |
# - buffer_size is the number of prev and next items to keep continuously populated | |
# - initial_index is the index of the initial object to construct | |
constructor: (@obj_constructor, @buffer_size, initial_index) -> | |
@prev_objs = [] | |
@next_objs = [] | |
@current_index = if initial_index? then initial_index else 0 | |
@current_obj = @obj_constructor @current_index | |
@populate_buffers() | |
goto: (index) -> | |
# iterate through next objs until you hit the desired obj or run out of objs | |
while index > @current_index | |
if @next_objs.length > 0 | |
@prev_objs.push @current_obj | |
@current_obj = @next_objs.shift() | |
@current_index += 1 | |
else | |
@empty_buffers() | |
@current_obj = @obj_constructor index | |
@current_index = index | |
# iterate through prev objs until you hit the desired obj or run out of objs | |
while index < @current_index | |
if @prev_objs.length > 0 | |
@next_objs.unshift @current_obj | |
@current_obj = @prev_objs.pop() | |
@current_index -= 1 | |
else | |
@empty_buffers() | |
@current_obj = @obj_constructor index | |
@current_index = index | |
@populate_buffers() | |
@current_obj | |
empty_buffers: -> | |
@current_obj.destroy_view() | |
while @prev_objs.length > 0 | |
@prev_objs.pop().destroy_view() | |
while @next_objs.length > 0 | |
@next_objs.pop().destroy_view() | |
populate_buffers: -> | |
# trim next objects to buffer size | |
while @next_objs.length > @buffer_size | |
@next_objs.pop().destroy_view() | |
# add next items as necessary | |
should_continue = true | |
while @next_objs.length < @buffer_size and should_continue | |
new_obj = @obj_constructor @current_index+@next_objs.length+1 | |
if new_obj? | |
@next_objs.push new_obj | |
else | |
should_continue = false | |
# trim prev objs to buffer size | |
while @prev_objs.length > @buffer_size | |
@prev_objs.shift().destroy_view() | |
# add prev items as necessary | |
should_continue = true | |
while @prev_objs.length < @buffer_size and should_continue | |
new_obj = @obj_constructor @current_index-(@prev_objs.length+1) | |
if new_obj? | |
@prev_objs.unshift new_obj | |
else | |
should_continue = false | |
all_prev_and_next_objs: -> | |
[@prev_objs..., @next_objs...] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment