私は、Delphi XE2を使用してSWFファイルの操作を行うための小さなツールを作成しています。これまでのところ、私は単にthe SWF specificationに従っています。そして今、私は形状を表すデータ構造を実装する際に小さな問題にぶつかりました。レコード内の複数のバリアント部分
SWFシェイプには、番号の形状レコードが含まれています。形状レコードは、エッジレコードまたは非エッジレコードであり、これらの2つのタイプのそれぞれは、2つの追加のサブタイプを有する。
具体的には、仕様の135ページに、2つの非エッジレコードタイプが記述されています。 EndShapeRecord
およびStyleChangeRecord
。 SWFファイルで、これらを区別する方法は、5つのフラグビット(TypeFlagの後)がすべて0であるかどうかをチェックすることです。そうであればEndShapeRecord
、それ以外の場合はStyleChangeRecord
です。
後でシェイプレコードを処理するのに役立つように、バリアントレコードを使用して、エッジレコードと非エッジレコードを単一のレコードタイプに統一したいと思います。さまざまな種類のレコードを区別するのは簡単です。ネストされたバリアントレコードを使用すると、エッジレコードを簡単に分離できます。非エッジレコードの場合は、StyleChangeRecord
から5つのフラグを宣言し、関数IsEndRecord
を書き込むことができます。
しかし、ソースコードをできるだけ厳密に仕様に反映させるために、私はさらに一歩進んでいきたいと思います。 StyleChangeRecord
の他のフィールドの存在は、これらの5つのフラグの値を前提としているので、各フラグによって追加されたフィールドを含む5つのバリアントレコードをフラグごとに宣言できるようにしたいと考えています。 (これは何らかの形でメモリの使用には影響しませんが、それはポイントではありません。)
残念ながら、デルファイは「レベル」ごとに複数のバリアントパーツを許可していないようです。同じレベルのバリアントパーツでは、文法エラーが多発するだけです。少し単純に言えば
TShapeRecord = record
case EdgeRecord: Boolean of
False: (
case StateMoveTo: Boolean of
True: (
MoveBits: Byte;
MoveDeltaX: Int32;
MoveDeltaY: Int32;
);
case StateLineStyle: Boolean of // << Errors start here
True: (LineStyle: UInt16);
//Additional flags
);
//Fields for edge records
end;
が、目標はそうのようなレコードを処方することができるようにすることです:レコードのバリアント部分を削除せずに...
TNonEdgeRecord = record
case StateMoveTo: Boolean of
True: (
MoveBits: Byte;
MoveDeltaX: Int32;
MoveDeltaY: Int32;
);
case StateLineStyle: Boolean of
True: (LineStyle: UInt16);
end;
をし、以来、(それらをネストなしネスティングは構文的な観点から誤った関係を意味する)。
複数の(ネストされていない)バリアントパーツをレコードに宣言することはできますか?または内部パーツのバリアントレコードを使用しないように戻す必要がありますか?
私は完全にあなたが達成しようとしているものを理解していないが、それはのように聞こえます独自のバリアントレコード処理をロールバックする必要があります。これは、レコードプロパティーを使用するのは簡単です。 –
@DavidHeffernan:いいえ、それはそれほど大したことではありません。私は*型定義*に、特定のフラグや変数の値が与えられている場合に、どのフィールドが存在するかを表示したいと思っています。これは基本的にバリアントレコードの機能です。私の問題は、* single *レコードの複数の*を取得することです。私ができる最善の策は、それらを入れ子にすることですが、これらのフラグは互いに独立しているので、それはばかげているでしょう。うまくいけばそれをもっと明確にするために少し質問を書き直そうとします。 –
構文は、複数の独立したフラグをサポートしていません。ネスティングは1つの選択肢です。メソッド/プロパティを持つレコードは、私が考えることのできるものです。 –