Skip to content

Instantly share code, notes, and snippets.

@Hc747
Created June 21, 2018 06:23
Show Gist options
  • Save Hc747/b9bb39d72c8a0435e1183ad09a31a87a to your computer and use it in GitHub Desktop.
Save Hc747/b9bb39d72c8a0435e1183ad09a31a87a to your computer and use it in GitHub Desktop.
interface IndexedEntity<T : IndexedEntity<T>> {
var index: EntityIndexReference<T>?
}
class EntityIndexReference<T : IndexedEntity<T>> internal constructor(val container: EntityList<T>, val entity: T, val index: Int)
class EntityList<T : IndexedEntity<T>>(private val capacity: Int) : AbstractCollection<T>() {
private val entities = HashMap<Int, EntityIndexReference<T>>(capacity)
private val indicies = ArrayDeque<Int>((1 .. capacity).toList())
override val size get() = capacity - indicies.size
override fun add(element: T): Boolean {
if (isExhausted()) {
return false
}
assert(element.index == null)
val index = indicies.poll()
assert(entities[index] == null)
val reference = EntityIndexReference(this, element, index)
entities[index] = reference
element.index = reference
return true
}
override fun remove(element: T): Boolean {
if (!contains(element)) {
return false
}
val reference = element.index!!
entities.remove(reference.index)
indicies.add(reference.index)
element.index = null
return true
}
fun remove(index: Int): T? {
val reference = entities.remove(index) ?: return null
val entity = reference.entity
indicies.add(reference.index)
entity.index = null
return entity
}
fun get(index: Int): T? = entities[index]?.entity
override fun contains(element: T): Boolean {
val reference = element.index ?: return false
if (reference.container != this) {
return false
}
return entities[reference.index]?.entity == element
}
private fun isExhausted() = indicies.isEmpty()
override fun iterator(): MutableIterator<T> = EntityListIterator()
private inner class EntityListIterator : MutableIterator<T> {
private val itr = entities.values.iterator()
private var current: T? = null
override fun hasNext() = itr.hasNext()
override fun next(): T {
current = itr.next().entity
return current!!
}
override fun remove() {
remove(current!!)
}
}
}
data class Player(val name: String, override var index: EntityIndexReference<Player>? = null) : IndexedEntity<Player>
abstract class AbstractEntityManager {
companion object {
const val MAX_PLAYERS = 2048
}
abstract val players: Collection<Player>
}
class EntityManager : AbstractEntityManager() {
override val players = EntityList<Player>(MAX_PLAYERS)
}
class ConcurrentEntityManager : AbstractEntityManager() {
override val players = Collections.synchronizedCollection(EntityList<Player>(MAX_PLAYERS))
}
object Main {
@JvmStatic
fun main(args: Array<String>) {
val manager = EntityManager() //or ConcurrentEntityManager
var index = 1
do {
val player = Player("P${index++}")
} while(manager.players.add(player))
println("Players Size: ${manager.players.size}")
manager.players.forEach { println("Player: $it") }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment