UnityThreadQueueというUnityのライブラリを作成しました。

UnityThreadQueueという、Unity上でThreadを使って、非同期処理をQueueを使って行うためのライブラリを公開しました。
https://github.com/TakuKobayashi/UnityThreadQueue
よかったら使っていただけたらと思います。m(_ _)m。starももらえるとうれしいです。
以下、使い方と作成経緯とThreadとかQueueとかUnityにおける仕様とかの前提知識について書きます。

# 使い方
<font color="#FF0000">UnityThreadQueue.unitypackage</font>があるので、それをインストールしてください。
AsyncSample.cs(非同期でやるもの)とSyncSample.cs(同期するもの)でサンプルを作成しましたのでそれも参照してください。

 * 基本的な使い方

```C#:AsyncSample.cs
UnityThreadQueue.Instance.Enqueue (() => {
  //非同期で行いたい処理を記述
});
```

* 非同期(Thread)で実行中の処理があるかどうか

```C#:SyncSample.cs
public bool UnityThreadQueue.Instance.ExistQueueEvent;
```
 * 上記二つを組み合わせて、Threadで行われた処理と同期させる一例

```C#:SyncSample.cs
void Start(){
  UnityThreadQueue.Instance.Enqueue (() => {
    //非同期で行いたい処理を記述
  });
  StartCoroutine (SyncCorutine());
}

private IEnumerator SyncCorutine(){
  while (UnityThreadQueue.Instance.ExistQueueEvent) {
    yield return null;
  }
  // 同期させた後に書きたい処理を書く
}
```

# 処理概要
![thread_timing.png](https://qiita-image-store.s3.amazonaws.com/0/72596/4c03ad62-7ec3-df5b-9a86-8c70536d77eb.png)

上記タイミング図のようにEnqueueすると別スレッドで処理が行われます。
(今回行われる処理では処理が完了するまでに100の時間がかかるものとします)

基本的にMainThreadの他に一つだけ別スレッドが立ち、その別スレッド内で処理が行われます。(スレッドとして立っているものは合計2個だけになります)
別スレッドの処理が終わる前にEnqueueした場合、すでに入っている処理が終わり次第、新しく入った処理がそのスレッド内で行われます。(タイミング図参照)
Queueの中に入っている処理が全てなくなったら、アイドル状態となります。

(なお上記のタイミング図は[PlantUML](http://plantuml.com/)を使って表示しています。以下に記述内容を記載します。)

```plantuml
@startuml
robust "QueueThread" as QT
concise "MainThread" as MT

@0
MT is 処理中
QT is アイドル

@+100
MT -> QT : Enqueue
MT is 処理中
QT is 処理中

@+100
QT -> MT : 終了通知
MT is 処理中
QT is アイドル

@+100
MT -> QT : Enqueue
MT is 処理中
QT is 処理中

@+50
MT -> QT : Enqueue
MT is 処理中
QT is 処理中

@+150
QT -> MT : 終了通知
MT is 処理中
QT is アイドル


@enduml
```

# 経緯
<font color="#FF0000">時間がかかる処理を高速かつ、制御できるものが必要になった</font>ためです。
(※制御できるもの: 非同期処理を行うThreadが乱立することなく、処理が行われる順番も担保されているもの)
また、使うにあたり、あらゆるところから呼び出せるようにもしました。

# 概要
Unityは基本的に非同期の処理をコルーチンで処理するが、コルーチンは基本的に同期処理(非同期のように見せているだけ)なので、時間がかかる処理の場合には画面が固まってしまったり、Totalの処理時間は変わらないため、結局時間がかるなど、注意が必要。(詳しくは後述)
そのため、この問題の解決にもこのライブラリは有用です。

# 前提知識
## [Queue(キュー)](https://ja.wikipedia.org/wiki/%E3%82%AD%E3%83%A5%E3%83%BC_(%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF))
Queueとはコンピュータの基本的なデータ構造の一つ。以下の図のようにデータを先入れ先出しのリスト構造で保持するもの。
![405px-Data_Queue.svg.png](https://qiita-image-store.s3.amazonaws.com/0/72596/9e2274f6-0a87-8598-d470-eee3233f173d.png)
今回、実装したものは処理を入れた(Enqueueした)順番で実行していく仕組み。

## 並行処理(マルチタスク)
コンピュータにおいて複数のタスクを切り替えて実行できるシステムのこと。
一般的にCPUを効率的に使用することで並行処理を実現している。CPUの利用単位として一般的にスレッドとプロセスがあり、それらを用いてマルチタスクを実現させるのが一般的。
なお、<font color="#FF0000">基本的に並行処理を実装する場合、制御する難度が格段に上がるので注意が必要</font>
![dt-mthread01_03.gif](https://qiita-image-store.s3.amazonaws.com/0/72596/f70156b6-8a8d-eda5-ffea-7ee6b2a6ca1a.gif)

## [Process(プロセス)](https://ja.wikipedia.org/wiki/%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9)
プロセスはCPU上で実行されるもので、タスクを完了するために、OSが制御するあらゆるリソースを使うことができます。
一般的にアプリ起動 → プロセス起動

## [Thread(スレッド)](https://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%AC%E3%83%83%E3%83%89_(%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF))
スレッドとは、CPU利用の単位を指します。スレッドは1つのプロセスから生成される実行単位で、同じプロセスから1つ以上のスレッドを起動させて実行させることができます。

![2013-12-process-thread_mini.jpg](https://qiita-image-store.s3.amazonaws.com/0/72596/adb77252-32a2-2165-5d69-6f127289a50a.jpeg)


## [コルーチン](https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%AB%E3%83%BC%E3%83%81%E3%83%B3)
コルーチンとはプログラミングの構造の一種。サブルーチンがエントリーからリターンまでを一つの処理単位とするのに対し、コルーチンはいったん処理を中断した後、続きから処理を再開できる。(このような機能を持った処理)
<font color="#FF0000">Unityにおける、コルーチンは処理が行われる順番が、フレーム単位で分けて実行されているだけであって、実際にはマルチタスクが行われているわけではない</font>ので厳密には非同期処理ではない。


## UnityにおけるThreadを使った非同期処理について
上記、非同期で行いたい処理はの中では、<font color="#FF0000">Unityの提供しているAPI(using UnityEngineが必要なもの)は使用できない。</font>(使用するとエラーになる)
これはUnityの仕様で、非同期処理中はThreadで処理が行われているためです。

#参考
[Unityでスレッドを使う](http://tsubakit1.hateblo.jp/entry/20121110/1352555965)
[Unityの非同期処理](http://techblog.kayac.com/unity_advent_calendar_2016_8)

---
###2017/11/28更新
ライブラリのプロジェクトを移動させることにしました。
新しいものはこちらになります。
https://github.com/TakuKobayashi/UnityThreadQueue
以前のものはアーカイブにしました。