sebas77/Svelto.ECS

PreconditionException: from group not found

Closed this issue · 7 comments

Because SubmitEntityViews is not called immediately. Delete the entity just created before the SubmitEntityViews call, it will throw an exception.

PreconditionException: from group not found
DBC.ECS.Check.Require (Boolean assertion, System.String message) (at Assets/Plugins/Svelto.ECS/DBC.cs:70)
Svelto.ECS.EnginesRoot.MoveEntity (Svelto.ECS.IEntityBuilder[] entityBuilders, EGID entityGID, Int32 toGroupID, System.Collections.Generic.Dictionary`2 toGroup) (at Assets/Plugins/Svelto.ECS/Svelto.ECS/EnginesRoot.Entities.cs:144)
Svelto.ECS.EnginesRoot.SubmitEntityViews () (at Assets/Plugins/Svelto.ECS/Svelto.ECS/EnginesRoot.Submission.cs:28)
System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:222)

All the operations [add and delete] now happens always the next submit operation. Today I am going to commit another fix/change of behavior to be sure that everything is in-line with this, however deleting items next iteration has been there for quite a while now.

is this still happening?

It still happens. At the same time, the delete operation is performed first. At this point, the add operation has not been performed, so the group cannot be found. I hope my broken English has been made clear...

Can I see your code? My understanding is that on the same frame you do two operations on the same entity which is something I reckon should never happen

You're right. We haven't used it in the project yet, but we do some pre-research based on survival example. This may be rare in real project. However, we believe that extreme cases are still possible, especially in the case of multi-thread. Maybe it would be better if the engine solved it. Anyway, this is my personal opinion :)

Here's our test code,

        void BuildRandomIsland(IFleetComponent fleet, int islandCount)
        {
            var point = fleet.points[fleet.pointIdx];
            var info = new UnmovableInfo
            {
                position = point
            };
            for (int i = 0; i < islandCount; i++)
            {
                var data = this._islandDatas[Random.Range(0, this._islandDatas.Length - 1)];

                info.position.x += Random.Range(-MAX_RANDOM_RANGE, MAX_RANDOM_RANGE);
                info.position.z += Random.Range(-MAX_RANDOM_RANGE, MAX_RANDOM_RANGE);
                info.rotation.y = Random.Range(-MAX_RANDOM_RANGE, MAX_RANDOM_RANGE);
                string key = _actorFactory.Build(data, ref info, ECSGroups.ActiveEnemies);

                this._islands.Enqueue(key);
            }
        }

        void ClearUnusedIsland()
        {
            while (this._islands.Count > MAX_QUEUE_COUNT)
            {
                var key = this._islands.Dequeue();
                _actorFactory.Remove<UnmovableEntityDescriptor>(key, ECSGroups.ActiveEnemies);
            }
        }

OK. It's unusual, obviously removing the excess in this case is weird. I can fix the problem, but it would make the building of the entities much slower.

For multithreading it's a different problem. the EnginesRoots are not thread safe, so if you want to add and remove from other threads, you will need at least to create your specialized Entity Scheduler in such away adding and remove is thread safe inside a specific thread.

I don't think massive parallelism is ever needed to add and remove entities, I suggest use synchronization points instead.

This is in theory tho, as in practice I never added and removed entities from other threads, although the next example I want to develop will be totally multithreaded so I can investigate more cases.

Please let me know what you think about all of this. Currently your code would crash by design, but I would need a pretty strong argument to fix it as it would make build entities slower.

Understand. I think we can avoid these problems in the project.