view Slide/master-slide.html @ 57:309de2ffb2bd

update
author riono <e165729@ie.u-ryukyu.ac.jp>
date Mon, 14 Feb 2022 20:57:33 +0900
parents 01087d212c1a
children c269b11bb810
line wrap: on
line source






<!DOCTYPE html>
<html>
<head>
   <meta http-equiv="content-type" content="text/html;charset=utf-8">
   <title>継続を使用する並列分散フレームワークのUnity実装</title>

   <meta name="generator" content="Slide Show (S9) v4.1.0 on Ruby 2.6.3 (2019-04-16) [universal.x86_64-darwin19]">
   <meta name="author"    content="Ryo Yasuda, Shinji Kono" >

<!-- style sheet links -->
<link rel="stylesheet" href="s6/themes/projection.css"   media="screen,projection">
<link rel="stylesheet" href="s6/themes/screen.css"       media="screen">
<link rel="stylesheet" href="s6/themes/print.css"        media="print">
<link rel="stylesheet" href="s6/themes/blank.css"        media="screen,projection">

<!-- JS -->
<script src="s6/js/jquery-1.11.3.min.js"></script>
<script src="s6/js/jquery.slideshow.js"></script>
<script src="s6/js/jquery.slideshow.counter.js"></script>
<script src="s6/js/jquery.slideshow.controls.js"></script>
<script src="s6/js/jquery.slideshow.footer.js"></script>
<script src="s6/js/jquery.slideshow.autoplay.js"></script>

<!-- prettify -->
<link rel="stylesheet" href="scripts/prettify.css">
<script src="scripts/prettify.js"></script>

<script>
  $(document).ready( function() {
    Slideshow.init();

    $('code').each(function(_, el) {
      if (!el.classList.contains('noprettyprint')) {
        el.classList.add('prettyprint');
      }
    });
    prettyPrint();
  } );

</script>

<!-- Better Browser Banner for Microsoft Internet Explorer (IE) -->
<!--[if IE]>
<script src="s6/js/jquery.microsoft.js"></script>
<![endif]-->

    

</head>
<body>

<div class="layout">
  <div id="header"></div>
  <div id="footer">
    <div align="right">
      <img src="s6/images/logo.svg" width="200px">
    </div>
  </div>
</div>

<div class="presentation">

  <div class='slide cover'>
    <table width="90%" height="90%" border="0" align="center">
      <tr>
        <td>
          <div align="center">
              <h1><font color="#808db5">継続を使用する並列分散フレームワークのUnity実装</font></h1>
          </div>
        </td>
      </tr>
      <tr>
        <td>
          <div align="left">
              Ryo Yasuda, Shinji Kono
              並列信頼研
            <hr style="color:#ffcc00;background-color:#ffcc00;text-align:left;border:none;width:100%;height:0.2em;">
          </div>
        </td>
      </tr>
    </table>
  </div>



<div class='slide'>
  <h3 id="本研究における成果">本研究における成果</h3>
<ul>
  <li>並列分散フレームワークChristieをUnityで動作可能に
    <ul>
      <li>Unity上でp2pを基礎としたオンラインゲームの開発が可能に</li>
    </ul>
  </li>
  <li>Christie Sharpと既存のUnityの通信フレームワークとの機能的な比較を行った
    <ul>
      <li>Christie Sharpの利点
        <ul>
          <li>単体でも並列ライブラリとして機能する</li>
          <li>通信切断が起こった場合でもゲームロジックが停止しない</li>
        </ul>
      </li>
    </ul>
  </li>
</ul>



</div>

<div class='slide'>
  <!-- _S9SLIDE_ -->


<h3 id="概要">概要</h3>
<ul>
  <li>オンラインゲームにおける通信にはクライアントサーバ方式が主流
    <ul>
      <li>データの共有はサーバを経由するため低速</li>
    </ul>
  </li>
  <li>当研究室で開発を行っているChristie の分散計算を使用することで、高速に通信できると考えた</li>
  <li>Christie をUnity で使用するためにC# で書き換えを行った</li>
  <li>Christie SharpとUnity既存の通信フレームワークとの機能的な比較を行った</li>
</ul>



</div>

<div class='slide'>
  <!-- _S9SLIDE_ -->


<h3 id="オンラインゲームにおけるデータ通信">オンラインゲームにおけるデータ通信</h3>
<ul>
  <li>オンラインゲームは複数のプレイヤーが関与する分散プログラム
    <ul>
      <li>分散プログラムを正しく書くことは難しい
        <ul>
          <li>ネットワークの変化、故障、性能の多様性を吸収する</li>
          <li>スケーラビリティー リソースの追加のみでサービスの質の直感的に維持できる性能基準を備える</li>
        </ul>
      </li>
      <li>Debugも困難な場合が多い</li>
    </ul>
  </li>
  <li>クライアントの負荷軽減やチート対策のため、クライアントサーバ方式が主流
    <ul>
      <li>データの同期にはサーバを経由するためp2pに比べ低速</li>
    </ul>
  </li>
</ul>



</div>

<div class='slide'>
  <!-- _S9SLIDE_ -->


<h3 id="オンラインゲームにおけるデータ通信-1">オンラインゲームにおけるデータ通信</h3>
<ul>
  <li>当研究室では並列分散通信フレームワークChristie を開発中である
    <ul>
      <li>型のあるDataGear とKey を持つタプル空間、DataGearManager として格納している</li>
      <li>他のノードはDGM のproxyを持っており、proxy に書き込むことで通信を実現している</li>
      <li>DGM はトポロジーマネージャーによって自動的に構築される
        <ul>
          <li>プログラム自体はDGM の名前を知っていれば良い</li>
          <li>他のノードのIP addressなどを知る必要はない</li>
        </ul>
      </li>
    </ul>
  </li>
  <li>ネットワークが切断されてもゲームは継続可能</li>
  <li>本研究ではChristieをC#で再実装を行い、Unityの通信ライブラリとして使用可能にする</li>
  <li>既存のUnityの通信ライブラリとの機能面での比較を行い、Christie Sharpのオンラインゲーム向けの通信ライブラリとしての考察を行う</li>
</ul>



</div>

<div class='slide'>
  <!-- _S9SLIDE_ -->


<h3 id="christie-の基礎概念">Christie の基礎概念</h3>
<ul>
  <li>Christie は当研究室で開発をしている並列分散通信フレームワークである
    <ul>
      <li>同じく当研究室で開発しているGearsOS に導入予定のため次のような概念を持っている</li>
    </ul>
  </li>
  <li>CodeGear  (クラスやスレッド)</li>
  <li>DataGear  (変数データ)</li>
  <li>CodeGearManager  (CG,DG,DGMを管理)</li>
  <li>DataGearManager  (DGを管理,localとremoteの2種類がある, put操作によりDGを格納)</li>
</ul>

<center><img src="../Paper/images/GearsRelationships.pdf" alt="message" width="550" height="350" /></center>
<center>
各Gearの関係性
</center>



</div>

<div class='slide'>
  <!-- _S9SLIDE_ -->


<h3 id="christie-の基礎概念-1">Christie の基礎概念</h3>
<ul>
  <li>全てのCGM はThreadPool と他のCGM をList として共有している</li>
  <li>ThreadPool はCPU に合わせた並列度でqueue に入ったThread を逐次実行していく
    <ul>
      <li>1つのThreadPool で処理を行うことでCPU のコア数に適したThread を管理でき、並列度を下げ流ことを防ぐ</li>
    </ul>
  </li>
  <li>ThreadPoolを共有することメタレベルで全てのCG/DG にアクセス可能</li>
</ul>
<center><img src="../Paper/images/ChristieClass.pdf" alt="message" width="600" height="450" /></center>
<center>
Christie を同一プロセスで複数インスタンス立ち上げた際の接続の構造図
</center>



</div>

<div class='slide'>
  <!-- _S9SLIDE_ -->


<h3 id="christie-の基礎概念-annotationについて">Christie の基礎概念 annotationについて</h3>
<p>DG を取り出すためにCG内に宣言した変数データにannotation をつける。annotationには以下の4つがある。</p>

<ul>
  <li>Take
    <ul>
      <li>先頭のDG を読み込み、そのDG を削除する</li>
      <li>DG が複数ある場合Take を使用する</li>
    </ul>
  </li>
  <li>Peek
    <ul>
      <li>先頭のDG を読み込むがDG を削除しない</li>
      <li>操作をしない場合は同じデータを参照し続ける</li>
    </ul>
  </li>
  <li>TakeFrom
    <ul>
      <li>Take と同じ動作だが、remote 先のDGMを指定できる</li>
    </ul>
  </li>
  <li>PeekFrom
    <ul>
      <li>Peek と同じ動作だが、remote 先のDGMを指定できる</li>
    </ul>
  </li>
</ul>



</div>

<div class='slide'>
  <!-- _S9SLIDE_ -->


<h3 id="topology-manager">Topology Manager</h3>
<ul>
  <li>Christie 上でNetwork Topology を形成する
    <ul>
      <li>参加を表明したノードに名前を与える</li>
      <li>必要があればノード同士の配線を自動で行う</li>
    </ul>
  </li>
  <li>静的Topology と動的Topology 2種類がある</li>
</ul>



</div>

<div class='slide'>
  <!-- _S9SLIDE_ -->


<h3 id="topology-manager静的topology">Topology Manager 静的Topology</h3>
<ul>
  <li>静的Topology は以下のようなdot ファイルを与えることでNode の関係を構築できる</li>
  <li>それぞれのNode への通信にはIP address などは使用せずright というlabel を使用することで接続できる</li>
</ul>

<center>dot 形式による node 間接続の記述</center>
<pre><code class="language-ring.dot">digraph test {
	node0 -&gt; node1 [label="right"]
	node1 -&gt; node2 [label="right"]
	node2 -&gt; node0 [label="right"]
}
</code></pre>

<center><img src="../Paper/images/ring.pdf" alt="message" width="480" height="300" /></center>
<center>
ring状の接続
</center>



</div>

<div class='slide'>
  <!-- _S9SLIDE_ -->


<h3 id="topology-manager静的topology-1">Topology Manager 静的Topology</h3>
<ul>
  <li>動的Topologyは以下の図のように自動的に接続される</li>
  <li>現在はTree型の接続のみに対応している</li>
</ul>

<center><img src="../Paper/images/DynamicTopology.pdf" alt="message" width="1000" height="450" /></center>
<center>動的Topologyの接続手順</center>



</div>

<div class='slide'>
  <!-- _S9SLIDE_ -->


<h3 id="christie-のコード例">Christie のコード例</h3>
<ul>
  <li>コンストラクタで与えた数字をインクリメントし、10回printする例題
    <pre><code class="language-java:StartCountup.java">public class StartCountup extends StartCodeGear {
  public StartCountup(CodeGearManager cgm) { super(cgm); }

  public static void main(String args[]) {
      StartCountup start = StartCountup(createCGM(10001));
  }
    
  @Override
  protected void run(CodeGearManager cgm) {
      cgm.setup(new CountUpper());
      CountObject count = new CountObject(1);
      put("count", count);
  }
}
</code></pre>
    <p>```java:CountUpper.java
public class CountUpper extends CodeGear {
  @Take
  public CountObject count;</p>

    <p>@Override
  protected void run(CodeGearManager cgm) {
      System.out.println(count);</p>

    <pre><code>  if (count &lt; 10) {
      cgm.setup(new CountUpper());
      count.number += 1;
      put("count", count);
  } else {
      cgm.getLocalDGM().finish();
  }   } }
</code></pre>
  </li>
</ul>

<pre><code>```java:CountObject.java
@Message
public class CountObject {
    public int number;

    public CountObject(int number) {
        this.number = number;
    }
}
</code></pre>



</div>

<div class='slide'>
  <!-- _S9SLIDE_ -->


<h3 id="christie-のコード例-1">Christie のコード例</h3>

<p>シーケンス図を使った説明</p>



</div>

<div class='slide'>
  <!-- _S9SLIDE_ -->


<h3 id="cへの書き換えの意義">C#への書き換えの意義</h3>
<ul>
  <li>ChristieはJavaで実装されている
    <ul>
      <li>C#に書き換えを行うべきか</li>
    </ul>
  </li>
  <li>Unityはandroidの開発向けにjarファイルからJavaのメソッドをC#上で呼び出せる機能がある
    <ul>
      <li>stringを使用してリソースディレクトリから検索し、使用</li>
      <li>高速化が求められる並列分散プログラミングには不適</li>
    </ul>
  </li>
  <li>JavaとC#の2つの管理が必要になる
    <ul>
      <li>C#とJavaは記述方法が非常に似ており、APIもほとんど同様な機能が実装されている</li>
      <li>リポジトリをネスト化して対応</li>
    </ul>
  </li>
</ul>



</div>

<div class='slide'>
  <!-- _S9SLIDE_ -->


<h3 id="書き換えの方針">書き換えの方針</h3>
<ul>
  <li>C#で記述するChristieをChristie Sharpとする</li>
  <li>Christie設計時の意図や、互換性を保つためChristieと同じ動作をさせる</li>
  <li>ChristieはJava9から開発されており、非推奨なコードやが含まれている</li>
  <li>C#に対応しつつ、処理動作の向上や最適化を行うために以下の変更を行った
    <ul>
      <li>MessagePackのバージョンアップ</li>
      <li>ThreadPoolからTaskへ変更</li>
    </ul>
  </li>
</ul>



</div>

<div class='slide'>
  <!-- _S9SLIDE_ -->


<h3 id="java-からの変更点">Java からの変更点</h3>
<ul>
  <li>Java とC# は基本的に書き方は変わらない</li>
</ul>

<pre><code class="language-java:ex.java">Java
public class StartCountup extends StartCodeGear { }

@Override
protected void run(CodeGearManager cgm) { }

@Take String countObject;
</code></pre>

<pre><code class="language-cs:ex.cs">C#
public class StartCountup : StartCodeGear { }

public override void Run(CodeGearManager cgm) { }

[Take] string countObject;
</code></pre>



</div>

<div class='slide'>
  <!-- _S9SLIDE_ -->


<h3 id="christie-sharp-のコード例">Christie Sharp のコード例</h3>
<pre><code class="language-cs:StartCountUp.cs">public class StartCountUp : StartCodeGear {
    public StartCountUp(CodeGearManager cgm) : base(cgm) { }

    public static void Main(string[] args) {
        StartCountUp start = StartCountUp(createCGM(10001));
    }

    public override void Run(CodeGearManager cgm) {
        cgm.Setup(new CountUpper());
        CountObject count = new CountObject(1);
        put("count", count);
    }
}
</code></pre>

<pre><code class="language-cs:CountUpper.cs">public class CountUpper : CodeGear {
    [Take] public CountObject count;

    public override void Run(CodeGearManager cgm) {
        Console.WriteLine(count.number);

        if (count.number &lt; 10) {
            cgm.Setup(new CountUpper());
            count.number += 1;
            put("count", count);
        } else {
            cgm.GetLocalDGM().Finish();
        }
    }
}
</code></pre>

<pre><code class="language-cs:CountObject.cs">[MessagePackObject]
public class CountObject {
    public int number;

    public CountObject(int number) {
        this.number = number;
    }
}
</code></pre>
<!--
1. Main関数でCGM のインスタンス生成
2. 2つのCG をsetupして待ち状態にする
3. key:hellowWorld data:"hello" がTake される
4. 変数が揃ったためStartHelloWorld のRun が実行される
5. "hello" がprintされ、再び待ち状態になる。 key:hellow data:"hello"がput される
6. key:hellowWorld data:"world" がTake され、4,5と同様に処理される
7. 変数hello とworld がput され揃ったため、FinishHelloWorld のRun が実行され、プログラムは終了する

-->



</div>

<div class='slide'>
  <!-- _S9SLIDE_ -->


<h3 id="take-annotationの実装">Take annotationの実装</h3>
<ul>
  <li>Christie ではDGを取得するためにannotation を使用している
    <ul>
      <li>C# ではannotation と同様の機能にattribute があり、Take をattribute で実装した</li>
    </ul>
  </li>
  <li>Take はフィールド変数に対して適用する</li>
</ul>

<pre><code class="language-java:Take.java">@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Take { }
</code></pre>

<pre><code class="language-cs:Take.cs">[AttributeUsage(AttributeTargets.Field)]
public class Take : Attribute { }
</code></pre>



</div>

<div class='slide'>
  <!-- _S9SLIDE_ -->


<h3 id="messagepackの相違点">MessagePackの相違点</h3>
<ul>
  <li>Christie ではMessagePack を使用してデータを圧縮し送受信している
    <ul>
      <li>インスタンス内のpublic 変数に対して圧縮可能</li>
    </ul>
  </li>
  <li>バージョンが古いため、現在はサポートされていない
    <ul>
      <li>そのため、最新版とは記述方法が異なる</li>
    </ul>
  </li>
  <li>圧縮するクラスには@Message annotatoinをつける</li>
  <li>MessagePack インスタンスを作成後、write、read することでデータの圧縮解凍が可能
    <ul>
      <li>圧縮されたデータはbyte[] 型になる</li>
    </ul>
  </li>
</ul>

<pre><code class="language-java:MessagePackEx.java">public class MessagePackExample {
    @Message
    public static class MyMessage {
        public String name;
        public double version;
    }
 
    public static void main(String[] args) throws Exception {
        MyMessage src = new MyMessage();
        src.name = "msgpack";
        src.version = 0.6;
 
        MessagePack msgpack = new MessagePack();
        // Serialize
        byte[] bytes = msgpack.write(src);
        // Deserialize
        MyMessage dst = msgpack.read(bytes, MyMessage.class);
    }
}
</code></pre>



</div>

<div class='slide'>
  <!-- _S9SLIDE_ -->


<h3 id="messagepackの相違点-1">MessagePackの相違点</h3>
<ul>
  <li>C# のMessagePack は複数存在している
    <ul>
      <li>java 版と似たような書き方をするMessagePack-CSharp を選択した</li>
    </ul>
  </li>
  <li>圧縮を行いたいクラスに対してMessagePackObject attribute を付ける</li>
  <li>圧縮する変数に対してkey を設定できる
    <ul>
      <li>解凍時にjson として展開できる</li>
    </ul>
  </li>
  <li>データの圧縮にはMessagePackSerializer.Serialize 関数を用い、byte[] に圧縮される</li>
  <li>データの解凍にはMessagePackSerializer.Deserialize 関数を使用する
    <ul>
      <li>Deserialize 関数はジェネリスク関数であるため&lt;&gt;内に解凍するデータの型情報を記述する</li>
    </ul>
  </li>
</ul>

<pre><code class="language-cs.MessagePackEx.cs">[MessagePackObject]
public class MyClass {
    [Key(0)]
    public int Age { get; set; }
    [Key(1)]
    public string FirstName { get; set; }
    [Key(2)]
    public string LastName { get; set; }

    static void Main(string[] args) {
        var mc = new MyClass {
            Age = 99,
            FirstName = "hoge",
            LastName = "huga",
        };

        byte[] bytes = MessagePackSerializer.Serialize(mc);
        MyClass mc2 = MessagePackSerializer.Deserialize&lt;MyClass&gt;(bytes);

        // [99,"hoge","huga"]
        var json = MessagePackSerializer.ConvertToJson(bytes);
        Console.WriteLine(json);
    }
}
</code></pre>



</div>

<div class='slide'>
  <!-- _S9SLIDE_ -->


<h3 id="threadpoolからtaskへの書き換え">ThreadPoolからTaskへの書き換え</h3>
<ul>
  <li>Christie ではThreadPool を使用していた
    <ul>
      <li>Christie # ではThreadPoolより高機能なTask を用いて書き換えを行った</li>
    </ul>
  </li>
  <li>Task は複雑な非同期処理を通常のコーディングと同じ感覚で直感的に記述できる</li>
  <li>裏でThreadPool が動くようになっている
    <ul>
      <li>大きく動作は変わらない</li>
    </ul>
  </li>
</ul>



</div>

<div class='slide'>
  <!-- _S9SLIDE_ -->


<h3 id="threadpoolからtaskへの書き換え-1">ThreadPoolからTaskへの書き換え</h3>

<pre><code class="language-java:PriorityThreadPoolExecutors.java">public class PriorityThreadPoolExecutors {

    private static class PriorityThreadPoolExecutor extends ThreadPoolExecutor {
        private static final int DEFAULT_PRIORITY = 0;
        private static AtomicLong instanceCounter = new AtomicLong();

        public PriorityThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
                                int keepAliveTime, TimeUnit unit) {
            super(corePoolSize, maximumPoolSize, keepAliveTime, unit, (BlockingQueue) new PriorityBlockingQueue&lt;ComparableTask&gt;(10,
		ComparableTask.comparatorByPriorityAndSequentialOrder()));
        }

        @Override
        public void execute(Runnable command) {
                super.execute(command);
        }
    }
}
</code></pre>

<pre><code class="language-cs:ThreadPoolExecuters.cs">public class ThreadPoolExecutors {
    
    public ThreadPoolExecutors(int nWorkerThreads, int nIOThreads) {
        ThreadPool.SetMinThreads(nWorkerThreads, nIOThreads);
    }
    
    public void Execute(CodeGearExecutor command) {
        Task.Factory.StartNew(() =&gt; command.Run());
    }
}
</code></pre>



</div>

<div class='slide'>
  <!-- _S9SLIDE_ -->


<h3 id="unity">Unity</h3>
<ul>
  <li>UnityはUnity Technologies が開発を行っているゲームエンジンである
    <ul>
      <li>世界中で使用されているゲームエンジン</li>
      <li>非常に軽く、スペックが低いノートPCでもゲーム開発が可能</li>
    </ul>
  </li>
  <li>プログラミング言語にはC# が採用されている
    <ul>
      <li>C# のAPI やUnity 向けに拡張されたAPIも使用可能</li>
      <li>開発した機能をUnity に組み込むことも可能</li>
    </ul>
  </li>
</ul>



</div>

<div class='slide'>
  <!-- _S9SLIDE_ -->


<h3 id="christie--on-unityのコード例">Christie # on Unityのコード例</h3>
<pre><code class="language-cs:TransformMoveTest.cs">public class TransformMoveTest : MonoBehaviour {
    private CodeGearManager cgm;
    public Transform otherTransform;
    private Vector3 pos;

    void Start() {
        cgm = StartCodeGear.CreateCgm(10000);
        cgm.Setup(new PositionAssignCodeGear());
        cgm.GetLocalDGM().Put("transform", transform);
    }

    public void Update() {
        pos = otherTransform.position;
        Vector3 newPos = new Vector3(pos.x + 3, pos.y, pos.z + 3);
        cgm.GetLocalDGM().Put("pos", newPos);
    }

    private void LateUpdate() {
        cgm.Setup(new PositionAssignCodeGear());
    }
}

</code></pre>

<pre><code class="language-cs:PositionAssingCodeGear.cs">public class PositionAssignCodeGear : CodeGear {
    [Take] private Vector3 pos;
    [Peek] private Transform transform;

    public override void Run(CodeGearManager cgm) {
        MainThreadDispatcher.Post(_ =&gt; {
            transform.position = pos;
        }, null);
    }
}

</code></pre>



</div>

<div class='slide'>
  <!-- _S9SLIDE_ -->


<h3 id="unityで使用されているライブラリとの比較">Unityで使用されているライブラリとの比較</h3>
<p>Unityで使用されている既存のライブラリとして、Photon Unity Networking 2(PUN2)、Mirrorと、Christie # の比較を行う。</p>

<table>
  <thead>
    <tr>
      <th> </th>
      <th>Christie #</th>
      <th>PUN2</th>
      <th>Mirror</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>通信方式</td>
      <td>p2p</td>
      <td>クライアントサーバ方式</td>
      <td>クライアントサーバ方式</td>
    </tr>
    <tr>
      <td>プロトコル</td>
      <td>TCP</td>
      <td>TCP</td>
      <td>TCP</td>
    </tr>
    <tr>
      <td>特徴</td>
      <td>通信のためのIP address がプログラム直接記述されていない</td>
      <td>Photon Cloud でサーバを自前で用意する必要がない</td>
      <td>Unity公式でサポートされている  RPC が使用可能</td>
    </tr>
  </tbody>
</table>



</div>

<div class='slide'>
  <!-- _S9SLIDE_ -->


<h3 id="christie-sharpの利点">Christie Sharpの利点</h3>
<ul>
  <li>単体でも並列処理が可能
    <ul>
      <li>CodeGear/DataGearを利用した待ち合わせ処理</li>
      <li>CodeGearの処理はTaskによってThreadPoolで行われる</li>
      <li>外部のライブラリを使用しなくてもUnityで強力な並列処理が可能</li>
    </ul>
  </li>
  <li>通信が切断した際にゲームロジックが停止しない
    <ul>
      <li>通信先の参照データをPeekで取得する</li>
      <li>DGMでproxyとしてデータはやりとりされているため、データは更新されないが参照は可能</li>
      <li>TopologyManagerにCookieの機能があるため、改良すれば切断から復帰可能であると考える</li>
    </ul>
  </li>
</ul>



</div>

<div class='slide'>
  <!-- _S9SLIDE_ -->


<h3 id="まとめ">まとめ</h3>
<ul>
  <li>Christie をUnity で使用するためにC# に書き換えを行った</li>
  <li>書き換え方針としては、attribute やMessagePack などC# 独自の機能に対応しつつ元のソースコードと同じ機能になるようにした</li>
  <li>Unityで動作検証を行い、正しく動作することを確認した</li>
  <li>Unity既存のライブラリとの比較を行った</li>
</ul>

<h3 id="今後の課題">今後の課題</h3>
<ul>
  <li>TopologyManagerの完成
    <ul>
      <li>2nd keyを用いたTreeMapの通信</li>
    </ul>
  </li>
  <li>Christie の性能検証を行う</li>
</ul>


</div>


</div><!-- presentation -->
</body>
</html>