Defragment and compress everything into a single chunks beginning at 0

Returns the elements that moved as a list.

intrude import gamnit::flat

var array = new GroupedArray[String]
array.add "a"
array.add "b"
array.add "c"
array.add "d"
array.remove "c"
array.remove "a"
assert array.to_s == "[b][d]"

var moved = array.defragment
assert moved.to_s == "[d]"
assert array.to_s == "[d,b]"
assert array.length == 2
assert array.capacity == 2

array.add "e"
array.add "f"
assert array.to_s == "[d,b,e,f]"

Property definitions

gamnit $ GroupedArray :: defragment
	# Defragment and compress everything into a single chunks beginning at 0
	#
	# Returns the elements that moved as a list.
	#
	# ~~~
	# intrude import gamnit::flat
	#
	# var array = new GroupedArray[String]
	# array.add "a"
	# array.add "b"
	# array.add "c"
	# array.add "d"
	# array.remove "c"
	# array.remove "a"
	# assert array.to_s == "[b][d]"
	#
	# var moved = array.defragment
	# assert moved.to_s == "[d]"
	# assert array.to_s == "[d,b]"
	# assert array.length == 2
	# assert array.capacity == 2
	#
	# array.add "e"
	# array.add "f"
	# assert array.to_s == "[d,b,e,f]"
	# ~~~
	fun defragment(max: nullable Int): Array[E]
	do
		app.perf_clock_sprites.lapse
		max = max or else length

		var moved = new Array[E]
		while max > 0 and (starts.length > 1 or starts.first != 0) do
			var i = ends.last - 1
			var e = items[i]
			assert e != null
			remove e
			add e
			moved.add e
			max -= 1
		end

		if starts.length == 1 and starts.first == 0 then
			for i in [length..capacity[ do items.pop
			available.clear
		end

		sys.perfs["gamnit flat gpu defrag"].add app.perf_clock_sprites.lapse
		return moved
	end
lib/gamnit/flat/flat_core.nit:1650,2--1699,4