SlideShare a Scribd company logo
1 of 16
Download to read offline
ロードオブナイツで使ってる
Unity非同期処理デザイン




          ++C++; 岩永信之 
              2012/10/12
イテレーター構文とUnityのコルーチン

コルーチン
ゲーム ループ
●   ゲームでは、どこか大元でループが回ってる
     while (isAlive)
     {
         // 固定 FPS なら、所定の時間が来るまで Sleep

         gameTime = … // ゲーム時間を進める

         foreach (var obj in gameObjects)
         {
             obj.Update (gameTime);
         }
     }
            1フレームに1回よばれる処理
重たい処理
●   フレームレートよりも時間がかかる処理をし
    ちゃダメ
    ダメな例
    string Load(string path)
    {
        // 30ミリ秒くらいかかるものとする
        var data = ファイルからバイナリロード(path);

        // これも30ミリ秒くらいかかるものとする
          return デシリアライズ(data);

        // 30 FPSだと、このメソッドは33ミリ秒以内に終えないと処理落ち
    }
                     2回に分けたい
そこで、イテレーター
●   イテレーターをコルーチンとして使う
ゲーム ループ中で、毎フレーム
 MoveNextを呼んでもらう
    IEnumerator Load(string path, Action<string> callback)
    {
          var data = ファイルからバイナリロード(path);        1フレーム目
        yield return null;

          callback(デシリアライズ(data));             2フレーム目
        yield return null;
    }
                         returnの代わりに
                        コールバック呼び出し
before/after (1)
●   メソッド宣言
    before
    string Load(string path)

    after
    IEnumerator Load(string path, Action<string> callback)

     ●   戻り値はIEnumerator固定
     ●   本来の戻り値はcallbackごしに返す
before/after (2)
●   return
    before
     return result;
    after
     callback(result);

     ●   returnステートメントの代わりにcallback呼び出し
before/after (3)
●    呼び出し側
    before
    var x = Load("path"); …(後続の処理)

    after
    StartCoroutine(Load("path", x => { …後続の処理 });

     ●      戻り値を直接受け取れない
            ●   形式上の戻り値(IEnumerator)はコルーチン起動のた
                めに使う
     ●      匿名関数を使って後続の処理をつなぐ
.NET Framework 4のTaskクラスを参考に、Unityコルーチンをラッピング

TASKクラス
問題
●   複数のコルーチンを扱いにくい
     StartCoroutine(A);
     StartCoroutine(B);


        ●   A, B両方が完了するのを待ちたいときはどうする?
        ●   Aの完了後にBを開始したいときはどうする?
             ● 特に、Aの(本来の)戻り値をBで使いたいときは?
             ● エラーの伝播を考えるとさらに面倒
Taskクラス
●   こういうクラスを用意
        public class Task<T> : IEnumerator
        {
            IEnumerator Routine;
            public T Result { get; }
            public Exception Error { get; }
            public void OnComplete(… callback);
            public Task<T> ContinueWith<U>(… continuation);
        }


    ●   継続処理の登録
    ●   (本来の)戻り値やエラーの伝播
実例

●   ロードオブナイツのマップ
    ●   64万要素程度の配列をJSONで受け取ってた
         ● 通信もコルーチン
            ●   通信エラーが発生する可能性あり
        ●   デコードもそこそこ高負荷なのでコルーチン化したい
            ●   (行単位でデコード、1フレームに1行ずつとか)
            ●   通信の結果を使う
            ●   デコード エラーが発生する可能性あり
        ●   ローカル ストレージにキャッシュしたい
            ●   IOエラーが発生する可能性あり

※ 最新バージョンではデータを小分けで受信するように改善され、デコード
処理はコルーチンではなくなっている
Task利用例(戻り値)
●   (本来の)戻り値の伝播
     IEnumerator A(Action<int> callback);
     IEnumerator B(int x, Action<string> callback);
     IEnumerator C(string s);

                A, B, C の順で実行したい
                A の戻り値(int)を B で、B の戻り値(string)を C で使いたい
                同期処理なら C(B(A()); だけで書けるもの

     var t = new Task<int>(A)
         .ContinueWith<string>(B)
         .ContinueWith(C);

     StartCoroutine(t);
同期処理と比べて
●   同期処理との対比
     IEnumerator A(Action<int> callback);
     IEnumerator B(int x, Action<string> callback);
     IEnumerator C(string s);

                                          int A();
                                          string B(int x);
                                          void C(string s);

     var t = new Task<int>(A)             var x = A();
         .ContinueWith<string>(B)         var s = B(x);
         .ContinueWith(C);                C(s);

     StartCoroutine(t);                      あるいは
                                            C(B(A()));
Task利用例(例外処理)
●   コルーチン内で発生した例外も受け取れる
    var t = new Task<int>(A)
        .ContinueWith<string>(B)
        .ContinueWith(C)
        .OnComplete(t =>             ●   A, B, C のどこかで例外が発
        {                                生した場合、そこでコルーチン
            if (t.Error != null) …       の実行は中断。
        });                          ●   発生した例外はErrorプロパ
                                         ティにセットされる
    StartCoroutine(t);
以上

More Related Content

What's hot

きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回Tomoya Kawanishi
 
関東GPGPU勉強会 LLVM meets GPU
関東GPGPU勉強会 LLVM meets GPU関東GPGPU勉強会 LLVM meets GPU
関東GPGPU勉強会 LLVM meets GPUTakuro Iizuka
 
Boost.Coroutine
Boost.CoroutineBoost.Coroutine
Boost.Coroutinemelpon
 
C#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive ExtensionsC#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive ExtensionsYoshifumi Kawai
 
TensorFlow XLA 「XLAとは、から、最近の利用事例について」
TensorFlow XLA 「XLAとは、から、最近の利用事例について」TensorFlow XLA 「XLAとは、から、最近の利用事例について」
TensorFlow XLA 「XLAとは、から、最近の利用事例について」Mr. Vengineer
 
Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)Yoshifumi Kawai
 
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しようUnity Technologies Japan K.K.
 
An other world awaits you
An other world awaits youAn other world awaits you
An other world awaits you信之 岩永
 
History & Practices for UniRx UniRxの歴史、或いは開発(中)タイトルの用例と落とし穴の回避法
History & Practices for UniRx UniRxの歴史、或いは開発(中)タイトルの用例と落とし穴の回避法History & Practices for UniRx UniRxの歴史、或いは開発(中)タイトルの用例と落とし穴の回避法
History & Practices for UniRx UniRxの歴史、或いは開発(中)タイトルの用例と落とし穴の回避法Yoshifumi Kawai
 
C++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングC++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングKohsuke Yuasa
 
Introduction to cython
Introduction to cythonIntroduction to cython
Introduction to cythonAtsuo Ishimoto
 
UniRxことはじめ
UniRxことはじめUniRxことはじめ
UniRxことはじめShoichi Yasui
 
Visual C++コード分析を支えるSAL
Visual C++コード分析を支えるSALVisual C++コード分析を支えるSAL
Visual C++コード分析を支えるSALegtra
 
配管流路の多目的最適化OpenFOAM+OpenMDAO(第28回オープンCAE勉強会@関西)
配管流路の多目的最適化OpenFOAM+OpenMDAO(第28回オープンCAE勉強会@関西)配管流路の多目的最適化OpenFOAM+OpenMDAO(第28回オープンCAE勉強会@関西)
配管流路の多目的最適化OpenFOAM+OpenMDAO(第28回オープンCAE勉強会@関西)TatsuyaKatayama
 
Python で munin plugin を書いてみる
Python で munin plugin を書いてみるPython で munin plugin を書いてみる
Python で munin plugin を書いてみるftnk
 
SEH on mingw32
SEH on mingw32SEH on mingw32
SEH on mingw32kikairoya
 
Observable Everywhere - Rxの原則とUniRxにみるデータソースの見つけ方
Observable Everywhere  - Rxの原則とUniRxにみるデータソースの見つけ方Observable Everywhere  - Rxの原則とUniRxにみるデータソースの見つけ方
Observable Everywhere - Rxの原則とUniRxにみるデータソースの見つけ方Yoshifumi Kawai
 

What's hot (20)

きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回
 
関東GPGPU勉強会 LLVM meets GPU
関東GPGPU勉強会 LLVM meets GPU関東GPGPU勉強会 LLVM meets GPU
関東GPGPU勉強会 LLVM meets GPU
 
Boost.Coroutine
Boost.CoroutineBoost.Coroutine
Boost.Coroutine
 
C#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive ExtensionsC#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive Extensions
 
TensorFlow XLA 「XLAとは、から、最近の利用事例について」
TensorFlow XLA 「XLAとは、から、最近の利用事例について」TensorFlow XLA 「XLAとは、から、最近の利用事例について」
TensorFlow XLA 「XLAとは、から、最近の利用事例について」
 
Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)
 
LINQ in Unity
LINQ in UnityLINQ in Unity
LINQ in Unity
 
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
 
An other world awaits you
An other world awaits youAn other world awaits you
An other world awaits you
 
History & Practices for UniRx UniRxの歴史、或いは開発(中)タイトルの用例と落とし穴の回避法
History & Practices for UniRx UniRxの歴史、或いは開発(中)タイトルの用例と落とし穴の回避法History & Practices for UniRx UniRxの歴史、或いは開発(中)タイトルの用例と落とし穴の回避法
History & Practices for UniRx UniRxの歴史、或いは開発(中)タイトルの用例と落とし穴の回避法
 
C++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングC++ マルチスレッドプログラミング
C++ マルチスレッドプログラミング
 
Introduction to cython
Introduction to cythonIntroduction to cython
Introduction to cython
 
UniRxことはじめ
UniRxことはじめUniRxことはじめ
UniRxことはじめ
 
Visual C++コード分析を支えるSAL
Visual C++コード分析を支えるSALVisual C++コード分析を支えるSAL
Visual C++コード分析を支えるSAL
 
配管流路の多目的最適化OpenFOAM+OpenMDAO(第28回オープンCAE勉強会@関西)
配管流路の多目的最適化OpenFOAM+OpenMDAO(第28回オープンCAE勉強会@関西)配管流路の多目的最適化OpenFOAM+OpenMDAO(第28回オープンCAE勉強会@関西)
配管流路の多目的最適化OpenFOAM+OpenMDAO(第28回オープンCAE勉強会@関西)
 
More C++11
More C++11More C++11
More C++11
 
フラグを愛でる
フラグを愛でるフラグを愛でる
フラグを愛でる
 
Python で munin plugin を書いてみる
Python で munin plugin を書いてみるPython で munin plugin を書いてみる
Python で munin plugin を書いてみる
 
SEH on mingw32
SEH on mingw32SEH on mingw32
SEH on mingw32
 
Observable Everywhere - Rxの原則とUniRxにみるデータソースの見つけ方
Observable Everywhere  - Rxの原則とUniRxにみるデータソースの見つけ方Observable Everywhere  - Rxの原則とUniRxにみるデータソースの見つけ方
Observable Everywhere - Rxの原則とUniRxにみるデータソースの見つけ方
 

Similar to Async design with Unity3D

Continuation with Boost.Context
Continuation with Boost.ContextContinuation with Boost.Context
Continuation with Boost.ContextAkira Takahashi
 
新しい並列for構文のご提案
新しい並列for構文のご提案新しい並列for構文のご提案
新しい並列for構文のご提案yohhoy
 
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_cccJEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_cccYujiSoftware
 
x86とコンテキストスイッチ
x86とコンテキストスイッチx86とコンテキストスイッチ
x86とコンテキストスイッチMasami Ichikawa
 
Scalaの限定継続の応用と基本
Scalaの限定継続の応用と基本Scalaの限定継続の応用と基本
Scalaの限定継続の応用と基本Kota Mizushima
 
Scalaの限定継続の応用と基本(改訂版)
Scalaの限定継続の応用と基本(改訂版)Scalaの限定継続の応用と基本(改訂版)
Scalaの限定継続の応用と基本(改訂版)Kota Mizushima
 
ji-5. 繰り返し計算
ji-5. 繰り返し計算ji-5. 繰り返し計算
ji-5. 繰り返し計算kunihikokaneko1
 
競技プログラミングのためのC++入門
競技プログラミングのためのC++入門競技プログラミングのためのC++入門
競技プログラミングのためのC++入門natrium11321
 
Javaセキュアコーディングセミナー東京第2回演習の解説
Javaセキュアコーディングセミナー東京第2回演習の解説Javaセキュアコーディングセミナー東京第2回演習の解説
Javaセキュアコーディングセミナー東京第2回演習の解説JPCERT Coordination Center
 
ji-3. 条件分岐と場合分け
ji-3. 条件分岐と場合分けji-3. 条件分岐と場合分け
ji-3. 条件分岐と場合分けkunihikokaneko1
 
20190625 OpenACC 講習会 第3部
20190625 OpenACC 講習会 第3部20190625 OpenACC 講習会 第3部
20190625 OpenACC 講習会 第3部NVIDIA Japan
 
Brief introduction of Boost.ICL
Brief introduction of Boost.ICLBrief introduction of Boost.ICL
Brief introduction of Boost.ICLyak1ex
 

Similar to Async design with Unity3D (20)

Continuation with Boost.Context
Continuation with Boost.ContextContinuation with Boost.Context
Continuation with Boost.Context
 
新しい並列for構文のご提案
新しい並列for構文のご提案新しい並列for構文のご提案
新しい並列for構文のご提案
 
Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7
 
Rの高速化
Rの高速化Rの高速化
Rの高速化
 
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_cccJEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
 
x86とコンテキストスイッチ
x86とコンテキストスイッチx86とコンテキストスイッチ
x86とコンテキストスイッチ
 
Scalaの限定継続の応用と基本
Scalaの限定継続の応用と基本Scalaの限定継続の応用と基本
Scalaの限定継続の応用と基本
 
Scalaの限定継続の応用と基本(改訂版)
Scalaの限定継続の応用と基本(改訂版)Scalaの限定継続の応用と基本(改訂版)
Scalaの限定継続の応用と基本(改訂版)
 
ji-5. 繰り返し計算
ji-5. 繰り返し計算ji-5. 繰り返し計算
ji-5. 繰り返し計算
 
Junit4
Junit4Junit4
Junit4
 
競技プログラミングのためのC++入門
競技プログラミングのためのC++入門競技プログラミングのためのC++入門
競技プログラミングのためのC++入門
 
Javaセキュアコーディングセミナー東京第2回演習の解説
Javaセキュアコーディングセミナー東京第2回演習の解説Javaセキュアコーディングセミナー東京第2回演習の解説
Javaセキュアコーディングセミナー東京第2回演習の解説
 
C++14 Overview
C++14 OverviewC++14 Overview
C++14 Overview
 
ji-3. 条件分岐と場合分け
ji-3. 条件分岐と場合分けji-3. 条件分岐と場合分け
ji-3. 条件分岐と場合分け
 
20190625 OpenACC 講習会 第3部
20190625 OpenACC 講習会 第3部20190625 OpenACC 講習会 第3部
20190625 OpenACC 講習会 第3部
 
Boost Tour 1.50.0 All
Boost Tour 1.50.0 AllBoost Tour 1.50.0 All
Boost Tour 1.50.0 All
 
boost tour 1.48.0 all
boost tour 1.48.0 allboost tour 1.48.0 all
boost tour 1.48.0 all
 
Brief introduction of Boost.ICL
Brief introduction of Boost.ICLBrief introduction of Boost.ICL
Brief introduction of Boost.ICL
 
コルーチンを使おう
コルーチンを使おうコルーチンを使おう
コルーチンを使おう
 
cp-9. 再帰関数
cp-9. 再帰関数cp-9. 再帰関数
cp-9. 再帰関数
 

Recently uploaded

[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略Ryo Sasaki
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものですiPride Co., Ltd.
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A surveyToru Tamaki
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Yuma Ohgami
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNetToru Tamaki
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdftaisei2219
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムsugiuralab
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...Toru Tamaki
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)Hiroki Ichikura
 

Recently uploaded (9)

[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものです
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdf
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システム
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
 

Async design with Unity3D

  • 3. ゲーム ループ ● ゲームでは、どこか大元でループが回ってる while (isAlive) { // 固定 FPS なら、所定の時間が来るまで Sleep gameTime = … // ゲーム時間を進める foreach (var obj in gameObjects) { obj.Update (gameTime); } } 1フレームに1回よばれる処理
  • 4. 重たい処理 ● フレームレートよりも時間がかかる処理をし ちゃダメ ダメな例 string Load(string path) { // 30ミリ秒くらいかかるものとする var data = ファイルからバイナリロード(path);     // これも30ミリ秒くらいかかるものとする return デシリアライズ(data);     // 30 FPSだと、このメソッドは33ミリ秒以内に終えないと処理落ち } 2回に分けたい
  • 5. そこで、イテレーター ● イテレーターをコルーチンとして使う ゲーム ループ中で、毎フレーム MoveNextを呼んでもらう IEnumerator Load(string path, Action<string> callback) { var data = ファイルからバイナリロード(path); 1フレーム目     yield return null; callback(デシリアライズ(data)); 2フレーム目     yield return null; } returnの代わりに コールバック呼び出し
  • 6. before/after (1) ● メソッド宣言 before string Load(string path) after IEnumerator Load(string path, Action<string> callback) ● 戻り値はIEnumerator固定 ● 本来の戻り値はcallbackごしに返す
  • 7. before/after (2) ● return before return result; after callback(result); ● returnステートメントの代わりにcallback呼び出し
  • 8. before/after (3) ● 呼び出し側 before var x = Load("path"); …(後続の処理) after StartCoroutine(Load("path", x => { …後続の処理 }); ● 戻り値を直接受け取れない ● 形式上の戻り値(IEnumerator)はコルーチン起動のた めに使う ● 匿名関数を使って後続の処理をつなぐ
  • 10. 問題 ● 複数のコルーチンを扱いにくい StartCoroutine(A); StartCoroutine(B); ● A, B両方が完了するのを待ちたいときはどうする? ● Aの完了後にBを開始したいときはどうする? ● 特に、Aの(本来の)戻り値をBで使いたいときは? ● エラーの伝播を考えるとさらに面倒
  • 11. Taskクラス ● こういうクラスを用意 public class Task<T> : IEnumerator { IEnumerator Routine; public T Result { get; } public Exception Error { get; } public void OnComplete(… callback); public Task<T> ContinueWith<U>(… continuation); } ● 継続処理の登録 ● (本来の)戻り値やエラーの伝播
  • 12. 実例 ● ロードオブナイツのマップ ● 64万要素程度の配列をJSONで受け取ってた ● 通信もコルーチン ● 通信エラーが発生する可能性あり ● デコードもそこそこ高負荷なのでコルーチン化したい ● (行単位でデコード、1フレームに1行ずつとか) ● 通信の結果を使う ● デコード エラーが発生する可能性あり ● ローカル ストレージにキャッシュしたい ● IOエラーが発生する可能性あり ※ 最新バージョンではデータを小分けで受信するように改善され、デコード 処理はコルーチンではなくなっている
  • 13. Task利用例(戻り値) ● (本来の)戻り値の伝播 IEnumerator A(Action<int> callback); IEnumerator B(int x, Action<string> callback); IEnumerator C(string s); A, B, C の順で実行したい A の戻り値(int)を B で、B の戻り値(string)を C で使いたい 同期処理なら C(B(A()); だけで書けるもの var t = new Task<int>(A) .ContinueWith<string>(B) .ContinueWith(C); StartCoroutine(t);
  • 14. 同期処理と比べて ● 同期処理との対比 IEnumerator A(Action<int> callback); IEnumerator B(int x, Action<string> callback); IEnumerator C(string s); int A(); string B(int x); void C(string s); var t = new Task<int>(A) var x = A(); .ContinueWith<string>(B) var s = B(x); .ContinueWith(C); C(s); StartCoroutine(t); あるいは C(B(A()));
  • 15. Task利用例(例外処理) ● コルーチン内で発生した例外も受け取れる var t = new Task<int>(A) .ContinueWith<string>(B) .ContinueWith(C) .OnComplete(t => ● A, B, C のどこかで例外が発 { 生した場合、そこでコルーチン if (t.Error != null) … の実行は中断。 }); ● 発生した例外はErrorプロパ ティにセットされる StartCoroutine(t);