OpenSiv3D の開発状況と展望

2012 年に最初のバージョンが公開された [Siv3D](http://play-siv3d.hateblo.jp/) (以下、現行版 Siv3D) を、より実用的でモダンな設計に置き換えるため、2016 年 3 月に **OpenSiv3D** プロジェクトがスタートしました。

![logo.png](https://qiita-image-store.s3.amazonaws.com/0/30255/f36b9c42-4c4a-ec61-8452-2f15b8940276.png)

OpenSiv3D は以下の目標のもと開発が進められています。

- オープンソース化
- クロスプラットフォーム対応
- 最新の C++17 規格に基づいたコードへのアップデート
- 現行版 Siv3D から得た知見やユーザからのリクエストに基づく API デザインの一新
- 多数の新機能追加

OpenSiv3D はまだ開発途中で、一般リリースの段階ではありません。現行版 Siv3D に習熟し、次世代の機能にいち早く触れてみたいユーザは、GitHub から開発中のバージョンを試すことができます。
OpenSiv3D リポジトリ: https://github.com/Siv3D/OpenSiv3D

## 対応プラットフォーム
OpenSiv3D の対応プラットフォームは、当初は Windows と macOS のみでしたが、2016 年 10 月に、有志による Linux 版のリポジトリが登場し、2017 年 3 月の v0.0.8 で Linux 版が本家リポジトリに試験的に統合されました。現在最新版の v0.1.7 では Windows / macOS / Linux において、ほぼ共通のコードで同じ機能が利用できるようになっています。

## 開発状況
配列や文字列、図形などの基本クラス、簡単な 2D 描画、オーディオ再生、ファイル処理などが実装されています。一方で、ゲームパッドや Kinect, LeapMotion などのデバイス管理、GUI や 3D グラフィックス、通信など、未実装の機能が多数あるため、現行版の Siv3D アプリを OpenSiv3D に移植するのはまだ難しいです。
筆者が開発しているビジュアルプログラミング言語 [Enrect](https://enrect.org/) は最新版の OpenSiv3D で開発されているので、現時点でどれほどのことができるかを知る参考になります。

## おもな新機能
細かいクラスや関数を含めると、OpenSiv3D にはすでに 500 以上の新機能が実装されています。
ここではとくに、ゲームやアプリの開発に役立つ機能をいくつか紹介します。

### 絵文字描画
2200 種類以上の Unicode 絵文字を Texture や Font として読み込み、描画できるようになりました。
動物や食べ物の絵文字を、簡単なゲームを作る際の素材としても活用できます。
![20171201-104623-470.png](https://qiita-image-store.s3.amazonaws.com/0/30255/df4246ed-5dc7-9b72-6f41-fadb49e7ca88.png)

### Glyph
Font を描画する際に、文字単位ごとに色や描画位置を制御できるようになりました。
簡単なマークアップ言語の作成にも応用が可能です。
![glyphDesc.png](https://qiita-image-store.s3.amazonaws.com/0/30255/0fca90f1-325f-c8d4-beba-592ebdda6c23.png)

### アイコン描画
Font Awesome によって提供されている [600 種類以上のアイコン](http://fontawesome.io/icons/) を Texture として読み込み、描画できるようになりました。
時計のアイコンや歯車のアイコン、フォルダのアイコンなど、高品質なアイコンセットを活用して、アプリの UI のクオリティを改善できます。
![20171201-112715-276.png](https://qiita-image-store.s3.amazonaws.com/0/30255/4345fb76-563f-7a71-858c-91522ab1b58b.png)

### Array クラスのメンバ関数
動的配列 `Array` クラスに多くのメンバ関数が追加されました。
配列から先頭の要素を削除する `Array::pop_front()`, 指定した条件を満たす要素数をカウントする `Array::count_if()`, 配列内の要素をランダムに並び替える `Array::shuffle()` など、開発でよく使う便利な操作が簡単に実現できます。

### 名前付き引数
`Arg::??? = ...` または `Arg::???(...)` という構文で、疑似的な名前付き引数の仕組みを実装しました。
関数のオーバーロードのバリエーションが増え、例えば `Rect` のコンストラクタは、左上の座標を指定するだけでなく、中心座標を指定するもの、右下の座標を指定するもの、上辺の中心位置を指定するものなど、オーバーロードが充実し、細かいところに手が届く仕様にパワーアップしました。

```cpp
const Rect r(Arg::center(30, 30), 40, 50);

Rect(Arg::topCenter(40, 200), 100, 50).draw();
```

## 今後の予定
現在 OpenSiv3D v0.2 世代が GitHub の u_update ブランチで開発中です。v0.2 の目玉機能は以下の通りです。

- 全体的なコードのクリーンアップ
- すべてのプラットフォームで文字表現を char32 に統一
- Placeholder オブジェクトの導入
- VS2017 15.5 や Xcode 9 で可能になった最新の C++14/17 規格への対応
- テキストファイル処理の強化

文字表現を char32 に統一することで、`𩸽` や `🐈` のように、これまで 16bit の `wchar_t` 型では扱えなかった文字単位の処理が可能になります。一方で、文字や文字列リテラルのプレフィックスは従来の `L""` から `U""` に変更されるので、注意が必要です。
Placeholder オブジェクト `s3d::Lambda::_` は、ラムダ式の記述を簡略にする機能です。

```cpp
using Lambda::_;

const Array<int32> v = { 10, 20, 30, 40 };

const size_t count = v.count_if(_ < 30);
```
また、戻り値を処理すべきあらゆる関数に `[[nodiscard]]` がつけられ、誤って戻り値を無視するコードがコンパイル時に警告されるようになります。

```cpp
Vec2 v(2.0, 1.5);

v.normalized(); // 警告

Vec2 v2 = v.normalized(); // OK

v.normalize(); // OK
```

v0.2 のリリース以降もアップデートを重ね、2018 年の春までには現行版 Siv3D の主要な機能の移植を終える目標です。

## OpenSiv3D の開発に参加する
OpenSiv3D の開発にあたっては、不定期で開催される「OpenSiv3D 実装会」の参加者や Siv3D Slack の #open-siv3d チャンネルのメンバーを中心に、様々な新機能の提案や実装が進められています。Advent Calendar 11 日目の記事で紹介される「トランプ描画機能」も、そうしたユーザからの実装案が採用されたケースです。

OpenSiv3D の開発に参加するのは簡単で、

- [OpenSiv3D の GitHub issue](https://github.com/Siv3D/OpenSiv3D/issues) に機能の提案や実装を投稿する
- [Siv3D Slack](https://github.com/Siv3D/Reference-JP/wiki/Slack) の `#open-siv3d` チャンネルに参加して発言する
- Twitter で不定期に告知される [OpenSiv3D 実装会](https://twitter.com/search?f=tweets&vertical=default&q=OpenSiv3D%20%E5%AE%9F%E8%A3%85%E4%BC%9A&src=typd) に参加する[^1]

などの方法があります。
開発コミュニティはまだ人数が少なくメンバーを募集中です。OpenSiv3D 実装会ではコードのレビューや開発のメンタリングなど、C++/Siv3D プログラミング技術の習得支援も行っています。オープンソース開発を通してプログラミング能力を磨きたい方など、ぜひ参加してみてください。

[^1]: 次回の開催は 2018 年 2 月を予定しています。