Home > OS >  How to know when field or property initialization is done?
How to know when field or property initialization is done?

Time:08-14

For example, there's two classes here.
Class One:

    using UnityEngine;
    using System.Collections.Generic;
    
    public class One:MonoBehavior
    {
        private List<string> _assetBundleList;
        
        private void Start()
        {
            InitializeList();
        }
        
        private void InitializeList()
        {
            //Add assetBundleList field some value.
        }
        
        public IEnumerator<string> GetEnumerator()
        {
            return _assetBundleList.GetEnumerator();
        }
    }

Class two:

    public class Two:MonoBehavior
    {
        public GameObject gameObjectWithScriptOne;
        private One _scriptOne;
        
        private void Start()
        {
            scriptOne = gameObjectWithScriptOne.GetComponent<One>();
            DoSomething();
        }
        
        private void DoSomething()
        {
            foreach(var assetBundle in scriptOne)
            {
                //Load asset
            }
        }
    }

Script one is just like a manager things, I use this for storing asset bundle data, perhaps the list value will change. Script two must wait for initializing done. Is there any way to wait for it except adjusting script order?

CodePudding user response:

It can be handled with easily creating a context that initialize things sequentially. In short you need to block the main thread.

Let's say you have a root or persistent scene that do must things like loading assets etc.

//The only object in the Root Scene.
public class RootContext : MonoBehaviour
{
    private const string _playerAddress = "Player";

    public void Awake()
    {
        //Load assets
        //wait for assets loading
        //instantiate things.
        //new instantiated things can also initalize with this way.
        var handle = Addressables.LoadAssetAsync<GameObject>(_playerAddress);
        var asset = handle.WaitForCompletion();
        var go = Instantiate(bla bla bla);
    }
}

I think the what you want is a framework that organize things. You can look at Strange. It is MVCS IoC framework. Addionality what you said about "when field or property initialization is done" with [PostConstruct] attribute with Strange.

    [Inject(ContextKeys.CONTEXT)]
    public IContext Context { get; set; }

    /*Initialization of injections are guaranteed at here. Their initialization 
    is also quaranteed like this class.
    */
    [PostConstruct]
    public void Initalize()
    {
    }

CodePudding user response:

I'd go with refactoring, but if this is not the case C# events might be the solution.

Class One

public class One:MonoBehavior
{
    private List<string> _assetBundleList;
    public event Func Initialized;
    
    private void Start()
    {
        InitializeList();
    }
    
    private void InitializeList()
    {
        //Add assetBundleList field some value.
        Initialized?.Invoke();
    }
    
    public IEnumerator<string> GetEnumerator()
    {
        return _assetBundleList.GetEnumerator();
    }
}

Class Two:

public class Two:MonoBehavior
{
    public GameObject gameObjectWithScriptOne;
    private One _scriptOne;
    
    private void Start()
    {
        scriptOne = gameObjectWithScriptOne.GetComponent<One>();
        scriptOne.Initialized  = DoSomething;
    }
    
    private void DoSomething()
    {
        foreach(var assetBundle in scriptOne)
        {
            //Load asset
        }
    }
}

Also, you should unsubscribe from events when disabling an object, but you'll figure it out by yourself.

  • Related