zoukankan      html  css  js  c++  java
  • Zenject与UniRx结合实现跨线程通信Signal

    •   修改Zenject下ProfileBlock.cs源码, 取消有关UnityEngine.Profiling.Profiler的代码.
    •   然后使用Zenject的Signal:
       // 定义Signal
        public class TestCrossThreadCommEvent : Signal<string, TestCrossThreadCommEvent> { }
    View Code
    1   // Install Signals
    2     Container.DeclareSignal<TestCrossThreadCommEvent>();
    View Code
     1 // 启动线程
     2     tth = new Thread(() =>
     3     {
     4         while (true)
     5         {
     6             Thread.Sleep(1000);
     7             _crossThreadCommEvent.Fire("fire not in main thread");
     8             //_unityEvent.Invoke();
     9         }
    10     });
    11     tth.Start();
    12     // UniRx
    13     _crossThreadCommEvent.AsObservable.ObserveOnMainThread(MainThreadDispatchType.Update)
    14         // 使用lambda表达式是没有问题的
    15         .Subscribe(s => TestCrossThreadComm(s))
    16         .AddTo(this);
    17     
    18     void TestCrossThreadComm(string msg)
    19     {
    20         Debug.Log(Thread.CurrentThread.ManagedThreadId);
    21         Debug.Log(msg);
    22         transform.RotateAround(transform.position, Vector3.up, 5f);
    23     }
    View Code
    •  输出结果:
          1
          UnityEngine.Debug:Log(Object)
          fire not in main thread
          UnityEngine.Debug:Log(Object) 
     
    • 多个参数情况:
    1 // 定义Signal
    2 public class TestCrossThreadCommEvent : Signal<string, string, TestCrossThreadCommEvent> { }
    View Code
    1 // Install Signals
    2 Container.DeclareSignal<TestCrossThreadCommEvent>();
    View Code
     1 // 启动线程
     2 tth = new Thread(() =>
     3 {
     4     while (true)
     5     {
     6         Thread.Sleep(1000);
     7         _crossThreadCommEvent.Fire("fire not in main thread", "	 so happy.");
     8         //_unityEvent.Invoke();
     9     }
    10 });
    11 tth.Start();
    12 // UniRx-Lambda
    13 _crossThreadCommEvent.AsObservable.ObserveOnMainThread(MainThreadDispatchType.Update)
    14     // 使用lambda表达式是没有问题的
    15     .Subscribe(tuple =>
    16     {
    17         Debug.Log(Thread.CurrentThread.ManagedThreadId);
    18         Debug.Log(tuple.Item1 + tuple.Item2);
    19         transform.RotateAround(transform.position, Vector3.up, 5f);
    20     })
    21     .AddTo(this);
    View Code
    •  输出结果:
    1
    UnityEngine.Debug:Log(Object)
    fire not in main thread     so happy.
    UnityEngine.Debug:Log(Object)
     
    以上为Asset Store中Zenject早期版本.
    目前有版本对Signal部分改动如下:
     1 ...
     2 #if UNITY_EDITOR && ZEN_PROFILING_ENABLED
     3             using (ProfileBlock.Start("Signal '{0}'", this.GetType().Name))
     4 #endif
     5             {
     6                 var wasHandled = Manager.Trigger(SignalId, new object[0]);
     7 
     8                 wasHandled |= (_listeners.Count > 0);
     9 
    10                 // Iterate over _tempListeners in case the
    11                 // listener removes themselves in the callback
    12                 // (we use _tempListeners to avoid memory allocs)
    13                 _tempListeners.Clear();
    14 
    15                 for (int i = 0; i < _listeners.Count; i++)
    16                 {
    17                     _tempListeners.Add(_listeners[i]);
    18                 }
    19 
    20                 for (int i = 0; i < _tempListeners.Count; i++)
    21                 {
    22                     var listener = _tempListeners[i];
    23 
    24 #if UNITY_EDITOR && ZEN_PROFILING_ENABLED
    25                     using (ProfileBlock.Start(listener.ToDebugString()))
    26 #endif
    27                     {
    28                         listener();
    29                     }
    30                 }
    31 
    32 #if ZEN_SIGNALS_ADD_UNIRX
    33                 wasHandled |= _observable.HasObservers;
    34 #if UNITY_EDITOR && ZEN_PROFILING_ENABLED
    35                 using (ProfileBlock.Start("UniRx Stream"))
    36 #endif
    37                 {
    38                     _observable.OnNext(Unit.Default);
    39                 }
    40 #endif
    41 ...
    View Code

    涉及到ProfileBlock的使用ZEN_PROFILING_ENABLED来开启, 所以想用Signal跨线程通信,否决掉ZEN_PROFILING_ENABLED就可以了.

  • 相关阅读:
    SPOJ SAMER08A
    SPOJ TRAFFICN
    CS Academy Set Subtraction
    CS Academy Bad Triplet
    CF Round 432 C. Five Dimensional Points
    CF Round 432 B. Arpa and an exam about geometry
    SPOJ INVCNT
    CS Academy Palindromic Tree
    身体训练
    简单瞎搞题
  • 原文地址:https://www.cnblogs.com/linxmouse/p/7500923.html
Copyright © 2011-2022 走看看