Digamos que meu jogo tenha um monstro que o kamikaze possa explodir no jogador. Vamos escolher um nome para esse monstro aleatoriamente: um Creeper. Portanto, a Creeper
classe tem um método que se parece com isso:
void Creeper::kamikaze() {
EventSystem::postEvent(ENTITY_DEATH, this);
Explosion* e = new Explosion;
e->setLocation(this->location());
this->world->addEntity(e);
}
Os eventos não estão na fila, eles são despachados imediatamente. Isso faz com que o Creeper
objeto seja excluído em algum lugar dentro da chamada para postEvent
. Algo assim:
void World::handleEvent(int type, void* context) {
if(type == ENTITY_DEATH){
Entity* ent = dynamic_cast<Entity*>(context);
removeEntity(ent);
delete ent;
}
}
Como o Creeper
objeto é excluído enquanto o kamikaze
método ainda está em execução, ele falha quando tenta acessar this->location()
.
Uma solução é enfileirar os eventos em um buffer e enviá-los mais tarde. Essa é a solução comum em jogos em C ++? Parece um pouco complicado, mas isso pode ser apenas por causa da minha experiência com outros idiomas com diferentes práticas de gerenciamento de memória.
Em C ++, existe uma solução geral melhor para esse problema em que um objeto se exclui acidentalmente de dentro de um de seus métodos?
autorelease
Objective-C, onde as exclusões são suspensas até "apenas um pouco".