Skip to content

Instantly share code, notes, and snippets.

@mstubna
Created April 14, 2015 10:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mstubna/f1529160ae0268a355df to your computer and use it in GitHub Desktop.
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.
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