Theolizer
Version.1.2.0
serializer for C++ / Do you want to update your classes easily ?
|
ここでは、enum型を修正した時、古いプログラムが保存したデータを回復するための各種指定方法を説明します。
最初にデフォルト値について説明します。
enumのシンボルを定義している先頭のシンボルの値をTheolizerは「デフォルト値」として用います。
THEOLIZER_ANNOTATE(ES)による指定を間違った場合、enum値保存/回復やバージョン・アップ/ダウン時に対応するシンボルが見つからない場合があります。その時、警告を報告(例外にはなりません。)し、変換先の値を「デフォルト値」にします。
バージョン番号を変えない場合に可能なenum型の修正は以下のものがあります。
注:シンボル値保存/シンボル名保存の指定方法についてはenum型のバリエーション を参照下さい。
THEOLIZER_ANNOTATE(ES:)の指定方法は以下の通りです。
「シンボル名リスト」はシンボル名保存時に指定します。
「シンボル値リスト」はシンボル値保存時に指定します。 「=値」は通常のenum型と同じく省略可能です。
下記の修正を行うサンプルです。
変更前(ver1a)のソース(source/reference_and_test/ver1a/test_modify_enum.h)
変更後(ver1b)のソース(source/reference_and_test/ver1b/test_modify_enum.h)
修正内容はEnumSymNameの場合と同等です。
変更前(ver1a)のソース(source/reference_and_test/ver1a/test_modify_enum.h)
変更後(ver1b)のソース(source/reference_and_test/ver1b/test_modify_enum.h)
enum型解説の途中ですが、ここでバージョン・アップ前の準備について説明します。
今までバージョン管理していなかった時にバージョン管理を始める時、3-2.バージョン番号管理について で説明した「グローバル・バージョン番号テーブル」の生成が必要になります。
そのために必要な作業は以下の通りです。
シリライズ処理するコンパイル単位全てがインクルードするヘッダファイルで宣言して下さい。
具体的には下記書式で宣言します。
テーブル名は任意の識別子です。これはtheolizer::internal::global_table名前空間内で必要なコードを定義する時の識別子の一部として用いられます。
グローバル・バージョン番号は最初は必ず1として下さい。その後、バージョンを上げる度に1づつインクリメントして下さい。
サンプルをver1cに用意してます。(source/reference_and_test/ver1c/common.h)
グローバル・バージョン番号テーブル実体は通常のグローバル変数(配列)として定義されますので、どれか1つのコンパイル単位でのみ実体定義します。
そのコンパイル単位のソース・ファイル(.cpp)の先頭付近で下記を定義することで、Theolizerドライバがこのマクロ定義を認識し、実体をその.cppファイル用の*.theolizer.hpp内に自動生成します。
また、そのコンパイル単位をTheolizerドライバが解析する時に、シリアライズする全てのクラスとenum型の定義とそのシリアライズ指定が必要になります。そこで、当該コンパイル単位ではシリアライズする全ての型を定義したヘッダ・ファイルをインクルードして下さい。
サンプルをver1cに用意してます。(source/reference_and_test/ver1c/main.cpp)
バージョン番号を更新して、enum型をバージョン・アップすることで次の変更ができます。
enum型をバージョン・アップする時の手順は次の通りです。
単純にTHEOLIZER_ENUM()マクロで指定しするだけです。対象のenum型定義よりも後、*.theolizer.hppをインクルードする前にTHEOLIZER_ENUM()マクロを置いて下さい。なお、THEOLIZER_ENUM_VALUE()でシンボル値保存へ直接変更することはできません。シンボル値保存へ変更する場合は、ローカル・バージョン番号を更新する時に行って下さい。
サンプル
test_modify_enum.hで定義しているEnumFullAutoとScopedEnumFullAutoはver1a, ver1bまでは非侵入型完全自動ですが、ver1cにて非侵入型半自動へ修正しています。
半自動型へ変更した(ver1c)のソース(source/reference_and_test/ver1c/test_modify_enum.h)
enum型はバージョン・アップする時、前バージョンと現バージョン間のシンボル値の対応を指定することができます。現バージョンのシンボルに対して、対応する前バージョンのシンボル値を指定します。
この場合、THEOLIZER_ANNOTATE(ES:)の第3パラメータで指定します。
「対応する前バージョンのシンボル値」はenumシンボルではなく直接数値で指定して下さい。前バージョンのenum型そのものは存在しません。しかし、旧版のenum型シンホルの値を変更することも有りえませんので指定可能です。
また、前バージョンとシンボル値が変化していない場合は「対応する前バージョンのシンボル値」の指定を省略できます。
これは、シンボルを名前変更したり削除(デフォルト値へ割り当て)したりした後、変更前に使っていたシンボルを他の意味で使いたいケースを想定しています。
この場合、バージョン・アップすることで、そのシンボルを他のシンボルへの再割当てすることができます。その際、3-3.バージョン・アップ時のシンボル対応 の方法で指定します。
再割当てしたいシンボルを「enumシンボル」に追加します。
この時、「対応する前バージョンのシンボル値」には前バージョンにおける「デフォルト値」を指定して下さい。
なお、上記の指定方法で、バージョン・アップ前のバージョンの特定のシンボルを、以前使っていたシンボルへ戻すことも可能です。ただし、これはシンボルの意味の変更を伴いませんので、バージョン・アップしても問題ないですが、バージョン・アップする必要はありません。
下記の修正を行うサンプルです。
バージョン・アップ前(ver1c)のソース(source/reference_and_test/ver1c/test_modify_enum.h)
バージョン・アップ後(ver2a)のソース(source/reference_and_test/ver2a/test_modify_enum.h)
開発当初は変更対応しやすいシンボル名保存が使い勝手が良いです。(C#
での経験ですが、シンボル値を気にしないで良いのはたいへんありがたかったです。)
ある程度枯れてきたら、シンボル名では効率が悪いのでシンボル値へ変更したくなります。
そして、再度、大改造する際に一旦シンボル名へ戻したい時もあるでしょう。
このようなシナリオに対応することを想定しています。
変更は3-1.バージョン・アップ手順 の手順に従います。この6.の手順にて下記マクロ名を切り替えます。
下記の修正を行うサンプルです。
バージョン・アップ前(ver2a)のソース(source/reference_and_test/ver2a/test_modify_enum.h)
バージョン・アップ後(ver3a)のソース(source/reference_and_test/ver3a/test_modify_enum.h)
enum型の修正に関する網羅的なテストは 4.テスト・プログラムの構造 で説明した各フォルダの下記2つのファイルにて実装しています。
unscoped enum型とscoped enum型について下記の修正を行い、4-1-2.テストの組み合わせ の各バージョン間で正しく回復できることを確認しています。
バージョン | 修正点 | 特記事項 |
---|---|---|
ver1a→ver1b | 1.シンボル値変更 2.シンボル名変更(a→b) 3.シンボル名変更(a,b,c→a) 4.シンボル名変更(a,b,c→d) 5.シンボル名削除(指定ミス) | 単純変更 3つから先頭の1つへ対応 3つから別の1つへ対応 指定ミスは対応先指定漏れ警告が出ることを確認 |
ver1b→ver1c | 1.グローバル・バージョン番号テーブル作成 2.完全自動型を半自動型へ変更 3.シンボル名削除指定ミスの修正 | 警告が消えることを確認 |
ver1c→ver2a | 1.バージョン・アップ 2.以前使っていたシンボルの再割当て | |
ver2a→ver3a | 1.バージョン名保存→バージョン値保存 2.バージョン値保存→バージョン名保存 3.前バージョンとの対応指定ミス | バージョン・アップ処理と回復処理で警告が出ることを確認 (元完全自動型はバージョン・アップ無し) |
ver3a→ver3b | 指定ミスの修正 | 警告が消えることを確認 (元完全自動型はバージョン・アップ無し) |
ver3a/test_modify_enum.cppのtutoriseModifyEnum()関数にて対応シンボルが無い時のバージョン・ダウン処理、および、保存処理に於ける警告検出をjson形式を用いてテストしています。
ver3b/test_modify_enum.cppのtutoriseModifyEnum()関数にて上記警告が消えることをテストしています。