LoginSignup
3
3

More than 5 years have passed since last update.

【OpenSiv3D】OpenSiv3Dで独自で定義したクラスや構造体のシリアライズ・デシリアライズを行う

Posted at

【はじめに】

Militumです。

今回はOpenSiv3Dを使用して、
独自で定義したクラスのシリアライズ・デシリアライズする方法を紹介したいと思います。

【OpenSiv3Dのバージョン】

Windows Desktop 0.3.1

【サンプルコード】

#include <Siv3D.hpp>

namespace
{
    struct Character
    {
        uint32 id_;    // 識別用ID
        String name_;  // 名前
        int32 hp_;     // 体力
        int32 attack_; // 攻撃力

        template <class Archive>
        void SIV3D_SERIALIZE(Archive& archive)
        {
            archive(
                id_,
                name_,
                hp_,
                attack_
            );
        }
    };
}

void Main()
{
    // バイナリファイルへ書き込み①
    {
        const Character character{ 1000, U"Siv3Dくん", 100, 20 };
        Serializer<BinaryWriter> writer(U"OpenSiv3D-Character.bin");
        writer(character);
        writer.getWriter().close();
    }

    // バイナリファイルへ書き込み②
    {
        const Character character{ 1001, U"Siv3Dくん", 200, 10 };
        Serializer<BinaryWriter> writer(U"OpenSiv3D-Character2.bin");
        writer(character.id_);
        writer(character.name_);
        writer(character.hp_);
        writer(character.attack_);
        writer.getWriter().close();
    }

    // バイナリファイルの読み込み①
    {
        Character character;
        Deserializer<BinaryReader> reader(U"OpenSiv3D-Character.bin");
        reader(character);
        reader.getReader().close();

        Print(character.id_);
        Print(character.name_);
        Print(character.hp_);
        Print(character.attack_);
    }

    Print(U"-----"); // 仕切り線

    // バイナリファイルの読み込み② 変数別に格納
    {
        Character character;
        Deserializer<BinaryReader> reader(U"OpenSiv3D-Character2.bin");
        reader(character.id_);
        reader(character.name_);
        reader(character.hp_);
        reader(character.attack_);
        reader.getReader().close();

        Print(character.id_);
        Print(character.name_);
        Print(character.hp_);
        Print(character.attack_);
    }

    // 旧Siv3DのWaitKeyに当たる関数が見当たらなかったので終了イベントを任意のキーに指定
    System::SetExitEvent(WindowEvent::AnyKey);
    while (System::Update())
    {
    }
}

実行結果

20190312-225515-858.png

補足

独自で定義したクラスのシリアライズ/デシリアライズを行う場合、
サンプルで構造体内に実装した下記の関数が肝となります。
SIV3D_SERIALIZE は、OpenSiv3Dで用意されたマクロで、Serializer経由で呼び出せばシリアライズ、
Deserializer経由で呼び出せばデシリアライズ用の関数として機能します。

template <class Archive>
void SIV3D_SERIALIZE(Archive& archive)
{
    archive(
        id_,
        name_,
        hp_,
        attack_
    );
}

組み合わせられる

サンプルコードでは、構造体のシリアライズ関数を通してシリアライズしたデータ、
個々のパラメータを別々にシリアライズしたデータを書き込む際と読み込む際にペアとしていますが、
これらは組み合わせを変えても問題ありません。(書き込みは①で出力し、読み込みは②を使用するなど)
この挙動は、Windows Desktop 0.3.1時点のOpenSiv3Dの仕様の可能性もあるので、
今後のバージョンでは使えなくなるかもしれません。


次回は、今回紹介した処理を応用しつつ、
規定フォーマットのCSVファイルを使用して、ツールでシリアライズしたデータを出力し、
OpenSiv3Dのアプリケーションでデシリアライズする処理を紹介予定です。

参考

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3