Created
June 21, 2018 06:23
-
-
Save Hc747/b9bb39d72c8a0435e1183ad09a31a87a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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