Regarding the new Firebase SDK for Unity and Threading tasks

I have a more general question regarding Unity C # and the new Firebase SDK . I looked through all the new documentation and have not yet seen the answer. If you retrieve data from the database below, this does not allow you to execute methods such as Instantiate inside this function, because it does not happen in the main thread. How would you do that? TL; DR I want to know how to perform game functions after or while fetching material from Firebase.

   FirebaseDatabase.DefaultInstance
    .GetReference("Scenes").OrderByChild("order")
    .ValueChanged += (object sender2, ValueChangedEventArgs e2) => {
      if (e2.DatabaseError != null) {
        Debug.LogError(e2.DatabaseError.Message);
        }
        scenes = asset.text.Split('\n');
        return;
      }
      if (e2.Snapshot != null && e2.Snapshot.ChildrenCount > 0) {
        sceneCollection.Clear();
        foreach (var childSnapshot in e2.Snapshot.Children) {
          var sceneName = childSnapshot.Child("name").Value.ToString(); 
          sceneCollection.Add( new SceneItem(sceneName, 0));

          // I WANTED TO INSTANTIATE SOMTHING HERE

        }

      }
    };
+4
source share
2 answers

( Firebase )

, :

https://firebase.google.com/support/release-notes/unity#1.0.1

, - ui . , .Net SynchronizationContext:

https://msdn.microsoft.com/en-us/library/system.threading.synchronizationcontext(v=vs.110).aspx

UnitySynchronizationContext.Install();

class UnitySynchronizationContext : SynchronizationContext {
  static UnitySynchronizationContext _instance = null;
  GameObject gameObject;
  Queue<Tuple<SendOrPostCallback, object>> queue;

  private UnitySynchronizationContext() {
    gameObject = new GameObject("SynchronizationContext");
    gameObject.AddComponent<SynchronizationContextBehavoir>();
    queue =
      gameObject.GetComponent<SynchronizationContextBehavoir>()
        .Queue;
  }

  public static void Install() {
    if (SynchronizationContext.Current == null)
    {
      if (_instance == null)
      {
        _instance = new UnitySynchronizationContext();
      }
      SynchronizationContext.SetSynchronizationContext(_instance);
    }
  }

  public override void Post(SendOrPostCallback d, object state) {
    lock (queue)
    {
      queue.Enqueue(new Tuple<SendOrPostCallback, object>(d, state));
    }
  }

  class SynchronizationContextBehavoir : MonoBehaviour {
    Queue<Tuple<SendOrPostCallback, object>> callbackQueue
        = new Queue<Tuple<SendOrPostCallback, object>>();

    public Queue<Tuple<SendOrPostCallback, object>>
        Queue { get { return callbackQueue; }}

    IEnumerator Start() {
      while (true)
      {
        Tuple<SendOrPostCallback, object> entry = null;
        lock (callbackQueue)
        {
          if (callbackQueue.Count > 0)
          {
            entry = callbackQueue.Dequeue();
          }
        }
        if (entry != null && entry.Item1 != null)
        {
          try {
            entry.Item1(entry.Item2);
          } catch (Exception e) { 
            UnityEngine.Debug.Log(e.ToString());
          }
        }
        yield return null;
      }
    }
  }
}
+3

Source: https://habr.com/ru/post/1660554/


All Articles