Closed dogwatch closed 9 years ago
Not exactly sure what the point of this is. Can you explain the reasoning behind it?
As @dogwatch said
Пока количество удаляемых Entity меньше RemovedEntitiesRetention, они попадают в removedAndAvailable для повторного использования, а если удаляемых больше, мы теряем их entity.Id для использования в ActiveEntities.
While the number of Entities removed is less than RemovedEntitiesRetention, they end up in removedAndAvailable for future use, but if the number is greater, we lose their entity.Id for its use in ActiveEntities.
I guess the reasoning behind desire to reuse just entity.Id is to neutralize (to some extent) constant growth in size of Bag<IComponent>
containers (accompanied by internal new T[newCapacity]
and Array.Copy
). RemovedEntitiesRetention
serves same purpose - in addition lowering GC pressure. But Entities retention has greater memory footprint than Ids retention.
I can only imagine a narrow case when additional Ids retention (doubtfully?) comes in handy: at some moment there is a burst in shortlived entities creation.
Bag<IComponent>
containers to grow.Bag<IComponent>
containers will not grow.Only the last case is affected by Ids retention. But the size of those int[] arrays is doubtly the case of optimization.
Or do I miss some ordinary case? And having unbound Ids retention is a cheap built-in stuff that sometimes may come in handy?
Thanks for the explanation and translation, but I think this is above my head with regards to memory management within C#.
How is Bag<IComponent>
going to grow? I guess I am not too clear how C# keeps track of components and entities in EntityWorld.
Example. Each call Heartbeat() results in the loss of a one entity.Id.
class Program
{
static EntityWorld world = new EntityWorld();
static int poolSize = world.EntityManager.RemovedEntitiesRetention;
static void Heartbeat()
{
// Create RemovedEntitiesRetention + 1 entities.
for ( int i = 0; i < poolSize + 1; ++i )
var entity = world.CreateEntity();
Console.WriteLine("ActiveEntities: " + world.EntityManager.ActiveEntities.Count);
Console.WriteLine();
for ( int i = 0; i < world.EntityManager.ActiveEntities.Count; ++i ) {
var entity = world.GetEntity(i);
if ( entity != null )
world.DeleteEntity(entity);
}
world.Update();
}
static void Main(string[] args)
{
Heartbeat();
Heartbeat();
Heartbeat();
Heartbeat();
Heartbeat();
Console.ReadKey();
}
}
Output:
ActiveEntities: 101
ActiveEntities: 102
ActiveEntities: 103
ActiveEntities: 104
ActiveEntities: 105
@KellanHiggins
How is
Bag<IComponent>
going to grow?
To accommodate new entity.Id
OK, you suggested another case: long running process. Without full Ids retention it will crash eventually with OOM.
Entities retention can be turned off by setting EntityManager.RemovedEntitiesRetention
to 0. Do you think there should be means to do the same with Ids retention? EntityManager.RemovedEntitiesIdsRetention
?
I remember the cases when we turned Entities Retention off to get rid of Ids reuse: we had a bug(?) in Systems architecture when sometimes code kept a "reference" to deleted entity's Id and then later tried to get an entity by Id - but got a fresh born one. It was a "quick fix" back then to just turn retention off.
@Maximusya
Entities retention can be turned off by setting
EntityManager.RemovedEntitiesRetention
to 0. Do you think there should be means to do the same with Ids retention?
No. You can not lose indexes. And why if identifierPool.Capacity
will always be less ActiveEntities.Capacity
?
I remember the cases when we turned Entities Retention off to get rid of Ids reuse: we had a bug(?) in Systems architecture when sometimes code kept a "reference" to deleted entity's Id and then later tried to get an entity by Id - but got a fresh born one. It was a "quick fix" back then to just turn retention off.
Maybe, maybe... Look:
static void Main(string[] args)
{
var world = new EntityWorld();
world.EntityManager.RemovedEntityEvent += (Entity oldEntity) => {
var newEntity = world.CreateEntity();
Console.WriteLine(oldEntity == newEntity);
Console.ReadKey();
};
var entity = world.CreateEntity();
world.DeleteEntity(entity);
world.Update();
}
Output: True
;D
What is the point of reusing Id in addition to reusing "Entity object + it's Id"? There is already reuse of "Entity object + it's Id" you know it, right? Можно по-русски