UniRx 5.4.1, this update is a small release. The main feature is to support Unity 5.5 Beta. Last week, Unity 5.5 beta was released. It is excellent (especially C# compiler upgrade!), but unfortunately, Unity’s auto script upgrade program brakes UniRx, so it can’t compile. Why?
Unity 5.5 deprecates MonoBehaviour.StartCoroutine_Auto, use StartCoroutine instead and upgrade program automatically, convert to StartCoroutine. Okay, it almost works, but UniRx does not because UniRx defines
new public static Coroutine StartCoroutine(IEnumerator coroutine)
If it calls StartCoroutine from the inner method, the compiler is confused. Is it static method? Is it instance base MonoBehaviour method? I’ve fixed it by rewriting, explicitly calling base MonoBehaviour.StartCoroutine.
Improvement: Support Unity 5.5 Beta
Fix: ThrottleFirstFrame throws NullReferenceException when stream sends OnNext immediately. #160, thanks @hsanno
Fix: Error on LogEntry.cs #164, thanks @kimsama
Fix: ToReadOnlyReactiveProperty should be distinct publishing #161
Fix: To(ReadOnly)ReactiveProperty cause strange result when source observable returns OnCompleted or OnError
(Breaking) Changes: PresenterBase was obsoleted(but it only commented, not marked [Obsolete])
Breaking Changes: Sample14 was removed
Breaking Changes: Removed ObservableMonoBehaviour, TypedMonoBehaviour in UNITY 5.5 or newer
Sorry, PresenterBase is obsolete because PresenterBase is too complex and lost stack trace, so it has low debuggability. You should define a simple Initialize method and call from parent to child; it works for most scenarios.
LINQ to GameObject 2.2
LINQ to GameObject is GameObject extensions for Unity that allow a traverse hierarchy and append GameObject. The design aims both to get the power of LINQ and the performance of iteration.
So yes, performance! I sometimes hear, “LINQ is slow. Do not use LINQ as it causes heavy allocations.” Hmn, it is true that LINQ causes heavy allocations.
In Unity, “LINQ” means LINQ to Objects. Select().Where()..., it create Enumerable objects on a number of method chains. There allocate Enumerator objects when called GetEnumerator. If used in lambda and capture variable, create a hidden class by the compiler; this is allocation.
In UniRx? Select().Where()…, it create Observable objects on a number of method chains. There allocate IDisposable objects when called Subscribe. If used in lambda and capture variable, create a hidden class by the compiler; this is allocation.
It is the same. But the difference is the sequence lifetime. I avoid using LINQ to Objects on a tight loop (for example, Update). UniRx (Reactive Pattern) mainly creates and subscribes only once and runs for a long time. If it runs in the pipeline, it does not allocate more (if you use the simple method).
In LINQ to GameObject? LINQ to GameObject’s traverse method does not allocate GC memory because it uses a hand-optimized struct enumerator. The unity compiler has bugs, so the struct enumerator(such as foreach List<T>) causes boxing and allocates GC memory, but Unity 5.5 and 5.3, 5.4’s compiler upgrade patch, can avoid it!
Some chain methods pass through the optimized path, for example, First, FirstOrDefault, ToArray, ForEach and ToArrayNonAlloc.
Add: Descendants/DescendantsSelf(descendIntoChildren) overload
Add: IEnumerable.Destroy(detachParent) overload
Performance Optimize: Children().ToArray() by use fixed array
Performance Optimize: Children().Destroy(detachParent) by use transform.DetachChildren
Descendants(descendIntoChildren) is borrowed from Roslyn, it stops traverse children when does not match condition.