Entitas icon indicating copy to clipboard operation
Entitas copied to clipboard

New Playmode Options: No Domain Reload vs. Unique Entities & Event Handlers

Open thygrrr opened this issue 3 years ago • 3 comments

What is the current best practice to use Entitas Teardown() / Contexts.Reset() / ... in conjunction with the new playmode options that are in Unity 2020?

image

The problem is, that unique entities stay alive; as do the handlers for EntityLinks (or specifically, Events that then try to access GameObjects that are Unity null / destroyed)

I have tried to work with Script Execution Order and OnApplicationQuit() on my main controller, but... UnityView components get destroyed befor and after the context is being reset. So either I get the "detected retained entities" issue, or Unity's "trying to access a destroyed GameObject" error.

What kind of seems to work, but feels very hacky, is resetting the contexts on Start():

        private void Start()
        {
            _contexts = Contexts.sharedInstance;
            _contexts.Reset();

and catching the edge case where a UnityView is destroyed:

        private void OnDestroy()
        {
            //UnityEngine.Debug.Log($"Destroying view {gameObject.name}, linked to {LinkedEntity}");
            if (LinkedEntity != null)
                gameObject.Unlink();
        }

... the latter feels like an inappropriate re-inversion of control, and can have unwanted side effects if something that's not the ~~end of the world~~ Application quit kills the gameobject.

thygrrr avatar Mar 07 '21 10:03 thygrrr

To clarify, object destruction order on application termination appears (kind of naturally/obviously) to be largely detached from script execution order, or occurs in several stages! But OnApplicationQuit() is invoked before all of these. You do not get another tick in between, though.

image

thygrrr avatar Mar 07 '21 10:03 thygrrr

In my project in test's Teardown we do:

  • unlink all gameobjects
  • deactivate entitas systems
  • clear scene (destroy gameobjects, clear DontDestroyOnLoad scene)
  • destroy all entities
  • reset entitas contexts
  • activate contexts indices

mrobaczyk avatar Mar 08 '21 07:03 mrobaczyk

Here is my solution :

Add below method to https://github.com/sschmid/Entitas-CSharp/blob/master/Addons/Entitas.CodeGeneration.Plugins/Entitas.CodeGeneration.Plugins/Context/CodeGenerators/ContextsGenerator.cs

    public static Contexts CreateNewInstance()
    {
        _sharedInstance = new Contexts();
        
        return _sharedInstance ;
    }

Recompile Entitas.CodeGeneration.Plugins

Then call this method before any entitas's call.

roygear avatar Jul 23 '21 08:07 roygear