14.UniRx序列(First、FirstOrDefault、BatchFrame、Buffer、GroupBy、ThrottleFirst、Throttle...)

First()
FirstOrDefault()
BatchFrame()
Buffer()
GroupBy()
ThrottleFirst()
ThrottleFrame()
ThrottleFirstFrame()


First

取基礎流裏面第一個數據或者取第一個滿足條件的數據,圖解
在這裏插入圖片描述
執行結果
在這裏插入圖片描述
代碼示例

public class No14_Mixed4 : MonoBehaviour
{
    void Start()
    {
        var first = Observable.EveryUpdate().First(FirstCondition);
        var disposable = first.Subscribe(Next, Error, Complete);
        disposable.AddTo(gameObject);
    }

    bool FirstCondition(long frame)
    {
        if (frame == 100)
        {
            return true;
        }

        return false;
    }

    void Next(long frame)
    {
        Debug.LogFormat("First事件發生在{0}幀", frame);
    }

    void Error(Exception ex)
    {
        Debug.LogException(ex);
    }

    void Complete()
    {
        Debug.LogFormat("Complete");
    }
}

代碼解析

FirstCondition是取一個滿足條件的數據,基礎流包裝的long類型,返回必須指定爲bool類型,true爲找到了第一個需要索取的數據。


FirstOrDefault

和First功能差不多,但FirstOrDefault如果是基於條件的查找,沒有找到匹配的數據則返回默認的初始化值,圖解同First

執行結果
在這裏插入圖片描述

代碼示例

public class No14_Mixed4 : MonoBehaviour
{
    void Start()
    {
        var first = Observable.EveryUpdate().Take(10).FirstOrDefault(FirstCondition);
        var disposable = first.Subscribe(Next, Error, Complete);
        disposable.AddTo(gameObject);
    }

    bool FirstCondition(long frame)
    {
        if (frame == 100)
        {
            return true;
        }

        return false;
    }

    void Next(long frame)
    {
        Debug.LogFormat("First事件發生在{0}幀", frame);
    }

    void Error(Exception ex)
    {
        Debug.LogException(ex);
    }

    void Complete()
    {
        Debug.LogFormat("Complete");
    }
}

代碼解析

滿足條件的第一個first在100幀,但是我只取了5幀,返回默認值,long的默認值是0,結果輸出0。


BatchFrame

UniRx特有的,對基礎流的幀數據進行打包或叫緩衝,然後等待一個時機一次性處理

執行結果

在這裏插入圖片描述

代碼示例

public class No14_Mixed4 : MonoBehaviour
{
    void Start()
    {
        var batchFrame = Observable.EveryFixedUpdate().BatchFrame(5, FrameCountType.FixedUpdate);
        var disposable = batchFrame.Subscribe(Next, Error, Complete);
        disposable.AddTo(gameObject);
    }

    void Next(IList<long> frames)
    {
        Debug.LogFormat("BatchFrame事件發生最後在{0}幀", frames[frames.Count -  1]);
    }

    void Error(Exception ex)
    {
        Debug.LogException(ex);
    }

    void Complete()
    {
        Debug.LogFormat("Complete");
    }
}

代碼解析

BatchFrame擁有初始化幀數,batch5幀大概是固定在7幀斷點,EveryFixedUpdate()擁有多種封裝的Update幀更新方式,包裝了Unity裏面內建的Update、FixedUpdate、LateUpdate、另外還有EveryEndOfFrame幀率方式。


Buffer

Buffer相對於BatchFrame功能更爲強大,Buffer可以對各種數據進行緩衝;將基礎流的數據緩衝到一塊再輸出,圖解
在這裏插入圖片描述
執行結果

在這裏插入圖片描述

代碼示例

public class No14_Mixed4 : MonoBehaviour
{
    void Start()
    {
        var buffer = Observable.EveryFixedUpdate().Buffer(100);
        var disposable = buffer.Subscribe(Next, Error, Complete);
        disposable.AddTo(gameObject);
    }

    void Next(IList<long> frames)
    {
        Debug.LogFormat("BatchFrame事件發生最後在{0}幀", frames[frames.Count -  1]);
    }

    void Error(Exception ex)
    {
        Debug.LogException(ex);
    }

    void Complete()
    {
        Debug.LogFormat("Complete");
    }
}

代碼解析

Buffer相對BatchFrame,功能更爲強大,擁有BatchFrame的全部功能,既可指定一個時間段來buffer也可指定一定數量的幀數來buffer。


GroupBy

對基礎流裏面的數據進行分組,分組之後按照組名和具體數據的排列方式存放,圖解
在這裏插入圖片描述
執行結果
在這裏插入圖片描述

代碼示例

public class No14_Mixed4 : MonoBehaviour
{
    private List<long> mArrOdd  = new List<long>(); // 奇數
    private List<long> mArrEven = new List<long>(); // 偶數

    void Start()
    {

        var buffer = Observable.EveryFixedUpdate().Buffer(10).GroupBy(GroupDesc);
        var disposable = buffer.Subscribe(Next, Error, Complete);
        disposable.AddTo(gameObject);
    }

    IList<long> GroupDesc(IList<long> longs)
    {
        longs.ToList().ForEach(l =>
        {
            if (l % 2 == 0)
            {
                mArrEven.Add(l);
            }
            else
            {
                mArrOdd.Add(l);
            }
        });
        return mArrEven;
    }

    void Next(IGroupedObservable<IList<long>, IList<long>> observable)
    {
        Debug.LogFormat("GroupBy:{0}, ValueCount:{1}", observable.Key.Count);

        observable.Subscribe(arr =>
        {
            arr.ToList().ForEach(l =>
            { 
                Debug.LogFormat("value:{0}", l);
            });
        });
    }

    void Error(Exception ex)
    {
        Debug.LogException(ex);
    }

    void Complete()
    {
        Debug.LogFormat("Complete");
    }
}

代碼解析

GroupBy是將基礎流按照一定的形式進行分組,將結果按照<key, groupvalues>的形式展現給用戶,具體使用方法有待探究。


ThrottleFirst

每次間隔一定時間,輸出一次數據,輸出的數據以第一幀爲有效幀,和Simple功能類似,圖解
在這裏插入圖片描述

執行結果
在這裏插入圖片描述

代碼示例

public class No14_Mixed4 : MonoBehaviour
{
    void Start()
    {

        var throttleFirst = Observable.EveryUpdate().ThrottleFirst(TimeSpan.FromSeconds(1f));
        var disposable = throttleFirst.Subscribe(Next, Error, Complete);
        disposable.AddTo(gameObject);
    }

    void Next(long frame)
    {
        Debug.LogFormat("間隔1秒,第一個輸出數據的幀數:{0}", frame);
    }

    void Error(Exception ex)
    {
        Debug.LogException(ex);
    }

    void Complete()
    {
        Debug.LogFormat("Complete");
    }
}

代碼解析

ThrottleFirst是基於時間單位的一個間隔數據聯動流,但只會對第一個數據進行Throttle,過了第一個數據則無效,輸出結果。


ThrottleFrame

UniRx特有的,對一定聯動的幀數進行融合,在一定的幀數裏面輸出判斷繼續,否則輸出,和Throttle功能類似,一個是基於時間單位,這個是基於幀單位來判斷需要輸出的信息,圖解
在這裏插入圖片描述
執行結果

在這裏插入圖片描述

代碼示例

public class No14_Mixed4 : MonoBehaviour
{
    void Start()
    {

        var throttleFrame = Observable.EveryUpdate().BatchFrame(10, FrameCountType.Update).ThrottleFrame(10);
        var disposable = throttleFrame.Subscribe(Next, Error, Complete);
        disposable.AddTo(gameObject);
    }

    void Next(IList<long> frames)
    {
        Debug.LogFormat("間隔10幀,輸出聯動數據幀數:{0}", frames[frames.Count - 1]);
    }

    void Error(Exception ex)
    {
        Debug.LogException(ex);
    }

    void Complete()
    {
        Debug.LogFormat("Complete");
    }
}

代碼解析

BatchFrame是將幀保存起來,不進行刷新,等到一定的數量才進行刷新,這裏的邏輯的是每10幀輸出一次


ThrottleFirstFrame

間隔一定時間,對聯動的數據進行第一次採樣,採樣判斷以第一幀輸出的數據爲準

執行結果

在這裏插入圖片描述

代碼示例

public class No14_Mixed4 : MonoBehaviour
{
    void Start()
    {
        var throttleFirstFrame = Observable.EveryUpdate().ThrottleFirstFrame(10);
        var disposable = throttleFirstFrame.Subscribe(Next, Error, Complete);
        disposable.AddTo(gameObject);
    }

    void Next(long frame)
    {
        Debug.LogFormat("間隔10幀,第一次輸出聯動數據幀數:{0}", frame);
    }

    void Error(Exception ex)
    {
        Debug.LogException(ex);
    }

    void Complete()
    {
        Debug.LogFormat("Complete");
    }
}

代碼解析


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章