Created
June 20, 2018 11:29
-
-
Save Hc747/2d1f55e17b55f76c660c92e6a146b9da 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 { | |
assert(contains(element)) | |
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 | |
} | |
override fun iterator(): MutableIterator<T> = EntityListIterator(entities.values.iterator()) | |
private fun isExhausted() = indicies.isEmpty() | |
private inner class EntityListIterator(private val itr: MutableIterator<EntityIndexReference<T>>) : MutableIterator<T> { | |
override fun hasNext() = itr.hasNext() | |
override fun next() = itr.next().entity | |
override fun remove() = itr.remove() | |
} | |
} | |
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