Entity object ownership
#1
Documenting stuff is always good, so here's some thoughts about rev 1385. Entities were rewritten, primarily so that their "Tick()" method can get the raw cChunk parameter. In order to do so, entities need to be ticked from within their respective chunks' Tick() method, which meant the global world list of entities had to be removed and instead entities are now owned by the chunk to which they belong.

The life of an entity
When an entity is first constructed, it is unowned - that means whoever constructed it, must make sure to dispose of it accordingly. The entity doesn't belong to any world, isn't sent to any clients etc. It's perfectly legal to set entity position, rotation and other parameters in this state.
Then the entity is added to a world, through its Initialize() function, which calls cWorld::AddEntity(). This bubbles through the chunkmap and calls cChunk::AddEntity(). From that moment on, the entity is owned by whichever chunk it is currently in. Each chunk ticks all its entities in its Tick() method, and it also checks and removes all entities whose Destroy() method has been called. If an entity moves to a different chunk, position-wise, the chunk detects it and within its Tick() function moves the entity to the correct chunk. So an entity doesn't need to worry itself about moving itself across chunks, the chunks do it automatically. However, it happens only within the cChunk::Tick() method, so there is a time when the entity's position doesn't correspond to the chunk in which the entity is. This needs to be taken into account when accessing entities by their chunks.
If an entity ever needs to teleport to a different world, it needs to remove itself from the world, using cWorld::RemoveEntity(), and add self to the other world using cWorld::AddEntity(). The RemoveEntity() call transfers entity ownership to whoever called it, so this whole procedure is actually a transfer of ownership, too. See cPlayer::MoveToWorld() for an example.
The entity object is deleted by the cChunk::Tick() function if the entity is marked as destroyed (by calling its Destroy() function). If required to be destroyed immediately,an entity can be also removed from the world (cWorld::RemoveEntity() ) and then safely deleted.

There are several caveats to this new system:
- An entity should not move into an unloaded chunk. If it does, currently the entity gets lost (memory leak), with a LOGWARNING()
- An entity must not be initialized until its correct position is set. If an entity is initialized into an unloaded chunk, the entity gets lost (memory leak) without any LOG, and the server will crash later on.
- When the entity crosses chunk borders, its owning chunk will get updated only after the world tick (this might get dangerous for plugins setting entity positions)
Reply
Thanks given by:


Messages In This Thread
Entity object ownership - by xoft - 04-14-2013, 07:26 AM
RE: Entity object ownership - by FakeTruth - 04-14-2013, 09:20 AM
RE: Entity object ownership - by keyboard - 04-14-2013, 03:47 PM
RE: Entity object ownership - by xoft - 04-14-2013, 04:35 PM



Users browsing this thread: 2 Guest(s)