./image_streamer.lua

  1. -- Script that encapsulates logic with streaming in and out images for UI elements that navigate through a list/grid/etc. 
  2. -- This is intended to be included as a script dependency for other lua scripts.  Only one doc can be loaded at a time that 
  3. -- depends on this script. 
  4.  
  5. local Image_streamer_data = { 
  6. 	image_list = {}, 
  7. 	on = false, 
  8. } 
  9.  
  10. function image_streamer_unwrap(arguments, start) 
  11. 	if start < #arguments then 
  12. 		return arguments[start + 1], image_streamer_unwrap(arguments, start + 1) 
  13. 	end	 
  14. end 
  15.  
  16. -- This callback is called when a load from the image streamer script is complete. 
  17. -- 
  18. function image_streamer_load_cb() 
  19.  
  20. 	-- Call the document defined callback that was passed in when streaming was started. 
  21. 	Image_streamer_data.in_progress = false 
  22. 	if Image_streamer_data.load_callback ~= nil then 
  23. 		Image_streamer_data.load_callback() 
  24. 	end 
  25. end 
  26.  
  27. -- Add an image to the list.  Appended to the end of the list.  Returns false on error (is streaming already started?). 
  28. -- 
  29. -- image_name: name of the image to add. 
  30. -- 
  31. function image_streamer_add_image(image_name) 
  32.  
  33. 	if Image_streamer_data.on then 
  34. 		return false 
  35. 	end 
  36.  
  37. 	-- Make a new entry after any current entries 
  38. 	local index = #Image_streamer_data.image_list + 1 
  39. 	Image_streamer_data.image_list[index] = {} 
  40. 	local info = Image_streamer_data.image_list[index] 
  41.  
  42. 	info.image_name = image_name 
  43. end 
  44.  
  45. -- Removes all images from the list.  Returns false on error, for example if you haven't stopped streaming first. 
  46. -- 
  47. function image_streamer_remove_all_images() 
  48.  
  49. 	if Image_streamer_data.on then 
  50. 		return false 
  51. 	end 
  52.  
  53. 	-- blow away the list 
  54. 	Image_streamer_data.image_list = {} 
  55. 	return true 
  56. end 
  57.  
  58. -- Initialize values for the image streamer, and commence streaming.  The image names should be added before calling this. 
  59. -- Returns false if there was an error (you've already started streaming?). 
  60. -- 
  61. -- start_index:   Index (starting from 1) which will be the index of the first image to be loaded.  Image loading will wrap past the 
  62. --                last index in a circular fashion. 
  63. -- num_loaded:    The number of images to be loaded loaded concurrently. 
  64. -- load_callback: callback function to call when a streaming load is complete 
  65. --  
  66. function image_streamer_start_streaming(start_index, num_loaded, load_callback) 
  67.  
  68. 	-- check for issues 
  69. 	if Image_streamer_data.on or #Image_streamer_data.image_list < num_loaded or #Image_streamer_data.image_list < start_index or num_loaded < 1  or start_index < 1 then 
  70. 		return false 
  71. 	end 
  72.  
  73. 	-- init settings 
  74. 	Image_streamer_data.on = true 
  75. 	Image_streamer_data.index = start_index 
  76. 	Image_streamer_data.num_loaded = num_loaded 
  77. 	Image_streamer_data.load_callback = load_callback 
  78. 	Image_streamer_data.in_progress = true 
  79. 	 
  80. 	-- now stream initial loaded images 
  81. 	local images_to_load = {} 
  82. 	local index = start_index 
  83. 	for image_num = 1,num_loaded do 
  84. 		images_to_load[image_num] = Image_streamer_data.image_list[index].image_name 
  85. 		index = index + 1 
  86. 		if index > #Image_streamer_data.image_list then 
  87. 			index = 1 
  88. 		end 
  89. 	end 
  90. 	 
  91. 	game_peg_load_with_cb("image_streamer_load_cb", num_loaded, image_streamer_unwrap(images_to_load, 0)) 
  92. 	return true 
  93. end 
  94.  
  95. -- Stop streaming of images, and unload all images.  Returns false if there was an error (you didn't start streaming?). 
  96. -- 
  97. function image_streamer_end_streaming() 
  98.  
  99. 	if Image_streamer_data.on == false then 
  100. 		return false 
  101. 	end 
  102.  
  103. 	Image_streamer_data.on = false 
  104. 	 
  105. 	-- now unload all images 
  106. 	local index = Image_streamer_data.index 
  107. 	for image_num = 1,Image_streamer_data.num_loaded do 
  108. 		game_peg_unload(Image_streamer_data.image_list[index].image_name) 
  109. 		index = index + 1 
  110. 		if index > #Image_streamer_data.image_list then 
  111. 			index = 1 
  112. 		end 
  113. 	end	 
  114. 	 
  115. 	return true 
  116. end 
  117.  
  118. -- Returns true if a stream is currently is progress, false otherwise. 
  119. -- 
  120. function image_streamer_is_stream_in_progress() 
  121. 	return Image_streamer_data.in_progress 
  122. end 
  123.  
  124. -- Moves the index, and handle all necessary streaming.  Will return false if operation not attempted (ie. streaming  
  125. -- is already in progress, or not enabled). 
  126. -- 
  127. -- offset: how many positions to move the index.  Can be negative.  Will wrap when going past either end of the list. 
  128. -- 
  129. function image_streamer_nav_index(offset) 
  130.  
  131. 	if Image_streamer_data.on == false or Image_streamer_data.in_progress or offset > #Image_streamer_data.image_list then 
  132. 		return false 
  133. 	end 
  134. 	 
  135. 	local image_list = {} 
  136. 	local images_to_load = {} 
  137. 	 
  138. 	-- Initialize our "state" array. 
  139. 	for image_num = 1,#Image_streamer_data.image_list do 
  140. 		image_list[image_num] = {} 
  141. 	end 
  142. 	 
  143. 	-- First, calculate all images that should be loaded now. 
  144. 	local index = Image_streamer_data.index 
  145. 	for image_num = 1,Image_streamer_data.num_loaded do 
  146. 		image_list[index].is_loaded = true 
  147. 		index = index + 1 
  148. 		if index > #Image_streamer_data.image_list then 
  149. 			index = 1 
  150. 		end 
  151. 	end	 
  152. 	 
  153. 	-- Update the index to the new value.  I should really get rid of the use of # and start indexing at 0 so this will be simpler. 
  154. 	Image_streamer_data.index = Image_streamer_data.index + offset 
  155. 	if Image_streamer_data.index > #Image_streamer_data.image_list then 
  156. 		Image_streamer_data.index = Image_streamer_data.index - #Image_streamer_data.image_list 
  157. 	end 
  158. 	if Image_streamer_data.index <  1 then 
  159. 		Image_streamer_data.index = Image_streamer_data.index + #Image_streamer_data.image_list 
  160. 	end 
  161. 	 
  162. 	-- Calculate which images should be loaded when we're done with this request. 
  163. 	index = Image_streamer_data.index  
  164. 	for image_num = 1,Image_streamer_data.num_loaded do 
  165. 		image_list[index].will_be_loaded = true 
  166. 		index = index + 1 
  167. 		if index > #Image_streamer_data.image_list then 
  168. 			index = 1 
  169. 		end 
  170. 	end	 
  171. 	 
  172. 	-- Unload images that have been scrolled off. 
  173. 	for image_num = 1, #Image_streamer_data.image_list do 
  174. 		if image_list[image_num].is_loaded == true and image_list[image_num].will_be_loaded ~= true then 
  175. 			game_peg_unload(Image_streamer_data.image_list[image_num].image_name) 
  176. 		end 
  177. 	end 
  178. 	 
  179. 	-- Finally, load images that have been scrolled on. 
  180. 	for image_num = 1, #Image_streamer_data.image_list do 
  181. 		if image_list[image_num].is_loaded ~= true and image_list[image_num].will_be_loaded == true then 
  182. 			local i = #images_to_load + 1 
  183. 			images_to_load[i] = Image_streamer_data.image_list[image_num].image_name 
  184. 		end 
  185. 	end 
  186. 	 
  187. 	game_peg_load_with_cb("image_streamer_load_cb", #images_to_load, image_streamer_unwrap(images_to_load, 0)) 
  188. 	return true 
  189. end 
  190.  
  191. function image_streamer_get_images() 
  192. 	return Image_streamer_data.image_list 
  193. end 
  194.  
  195.