Property definitions

gamnit $ SpriteSet :: defaultinit
# Set of sprites sorting them into different `SpriteContext`
class SpriteSet
	super HashSet[Sprite]

	# Animation speed multiplier (0.0 to pause, 1.0 for normal speed, etc.)
	var time_mod = 1.0 is writable

	# Seconds elapsed since the launch of the program, in world time responding to `time_mod`
	var time = 0.0

	# Map texture then static vs dynamic to a `SpriteContext`
	private var contexts_map = new HashMap4[RootTexture, nullable RootTexture, Bool, Int, Array[SpriteContext]]

	# Contexts in `contexts_map`, sorted by draw order
	private var contexts_items = new Array[SpriteContext]

	# Sprites needing resorting in `contexts_map`
	private var sprites_to_remap = new Array[Sprite]

	# Add a sprite to the appropriate context
	private fun map_sprite(sprite: Sprite)
	do
		assert sprite.context == null else print_error "Sprite {sprite} belongs to another SpriteSet"

		# Sort by texture and animation texture
		var texture = sprite.texture.root
		var animation = sprite.animation
		var animation_texture = if animation != null then
			animation.frames.first.root else null
		var draw_order = sprite.draw_order
		var contexts = contexts_map[texture, animation_texture, sprite.static, draw_order]

		var context = null
		if contexts != null then
			for c in contexts.reverse_iterator do
				var size = c.sprites.length + 1
				if size * 4 <= 0xffff then
					context = c
					break
				end
			end
		end

		if context == null then
			var usage = if sprite.static then gl_STATIC_DRAW else gl_DYNAMIC_DRAW
			context = new SpriteContext(texture, animation_texture, usage, draw_order)

			if contexts == null then
				contexts = new Array[SpriteContext]
				contexts_map[texture, animation_texture, sprite.static, draw_order] = contexts
			end

			contexts.add context

			contexts_items.add context
			sprite_draw_order_sorter.sort(contexts_items)
		end

		context.sprites.add sprite
		context.sprites_to_update.add sprite
		context.last_sprite_to_update = sprite

		sprite.context = context
		sprite.sprite_set = self

		if animation != null and sprite.animation_start == -1.0 then
			# Start animation
			sprite.animation_start = time
		end
	end

	# Remove a sprite from its context
	private fun unmap_sprite(sprite: Sprite)
	do
		var context = sprite.context
		assert context != null
		context.sprites.remove sprite

		sprite.context = null
		sprite.sprite_set = null
	end

	# Draw all sprites by all contexts
	private fun draw
	do
		# Remap sprites that may need to change context
		for sprite in sprites_to_remap do

			# Skip if it was removed from this set after being modified
			if sprite.sprite_set != self then continue

			unmap_sprite sprite
			map_sprite sprite
		end
		sprites_to_remap.clear

		# Sort by draw order
		for context in contexts_items do context.draw
	end

	redef fun add(e)
	do
		if contexts_items.has(e.context) then return
		map_sprite e
		super
	end

	redef fun remove(e)
	do
		super
		if e isa Sprite then unmap_sprite e
	end

	redef fun remove_all(e)
	do
		if not has(e) then return
		remove e
	end

	redef fun clear
	do
		for sprite in self do
			sprite.context = null
			sprite.sprite_set = null
		end
		super
		for c in contexts_items do c.destroy
		contexts_map.clear
		contexts_items.clear
		sprites_to_remap.clear
	end

	private fun reset
	do
		for sprite in self do
			sprite.context = null
		end

		for c in contexts_items do c.destroy
		contexts_map.clear
		contexts_items.clear
		sprites_to_remap.clear

		for sprite in self do
			map_sprite sprite
		end
	end
end
lib/gamnit/flat/flat_core.nit:891,1--1038,3