Closed rrbox closed 4 months ago
class EntityCommand {
func runCommand(in world: World, forEntity entity: Entity, entityRecord: EntityRecordRef)) {
}
}
class EntityCommands {
var commandQueue: [EntityCommand]
func runCommand(in world: World, forEntity entity: Entity, entityRecord: EntityRecordRef)) {
for command in self.commandQueue {
command.run(in: world, forEntity: entity, entityRecord: entityRecord)
}
}
}
class SpawnCommand: Command {
let entityCommands: EntityCommands
func pushCommand(_ command: EntityCommand) {
self.commandQueue.append(command)
}
func id() -> Entity {
// ???
// この関数を実装するなら、やはり即時的に entity を生成すべきか?
}
func runCommand(in world: World) {
let (entity, record) = world.spawn()
self.entityCommands.run(in: world, forEntity: entity, entityRecord: record)
}
}
entity 生成のルール(slot のインクリメント)の責任を Commands に負担させる場合の spawn メソッドです。
class Commands {
var generator = EntityGenerator()
func spawn() -> EntityCommands {
let entity = self.generator.generate()
let record = EntityRecordRef()
record.map.body[ObjectIdentifier(Entity.self)] = ImmutableRef(value: entity)
self.generator.pop()
self.__entityQueue__.append(SpawnCommand(id: entity, entityRecord: record))
return EntityCommands(entity: entity, commands: self)
}
}
class SpawnCommand {
let id: Entity
let entityRecord: EntityRecordRef
override func runCommand(in world: World) {
world.push(entity: self.entity, entityRecord: self.entityRecord)
}
}
extension World {
func push(entity: Entity, entityRecord: EntityRecordRef) {
if entity.generation == 0 {
self.entities.allocate() // entities: SparseSet<EntityRecordRef>
}
self.entities.insert(entity: entity, entityRecord: entityRecord)
self.worldStorage
.chunkStorage
.push(entity: entity, entityRecord: entityRecord)
self.worldStorage
.eventStorage
.commandsEventWriter(eventOfType: DidSpawnEvent.self)!
.send(value: DidSpawnEvent(spawnedEntity: entity))
}
}
sparse set の導入により、entity 生成方法が変わります。それまでは引数を取らないイニシャライザで簡単に生成できましたが、今後は world の entities から空きスロットに対応する entity を生成しなければなりません。
この変化に伴い、これまでの commands の entity spawn 処理および、entity commands の作成がうまく機能しなくなります。とくに、entity spawn 処理は world へのアクセスを要求するため、遅延実行されることになります。従って、続く entity commands は entity のデータをプロパティに格納することができないことになります。
そこで entity commands の再定義と spawn, despawn の処理内容の調整を行うべきとしました。