a byte in the header selects which packet format to use. I use this selection code as the case index so I have
...
0:(header:Tbaseheader); // only the header that all records include
...
105:(Tref : tTimeRefRec); // when the header code is 105, use this union
...
And how do you use these numbers in practice, like the values "0" or "105" above?
In my current project, for example, I have a union to store data about the text tokens. There are five types of tokens, each of them uses different data. The token is declared as variant record, and to be able to distinguish the type of the token (and use the apropriate record fields), the first field in the structure is the field with the numeric token type:
type
TGame_TextToken = record
Type_: TGame_UInt8;
case TGame_UInt8 of
GAME_TEXT_TOKEN_WORD: ( Word: record
Word: PGame_Char;
Rect: TGame_RectS32;
end );
GAME_TEXT_TOKEN_WHITE: ( White: record
NumChars: TGame_SInt32;
W: TGame_SInt32;
H: TGame_SInt32;
end );
GAME_TEXT_TOKEN_COLOR: ( Color: record
R: TGame_UInt8;
G: TGame_UInt8;
B: TGame_UInt8;
end );
GAME_TEXT_TOKEN_ALPHA: ( Alpha: record
Level: TGame_UInt8;
end );
GAME_TEXT_TOKEN_FONT: ( Font: record
Index: TGame_UInt8;
end );
end;
If I need to distinguish the type of token, I check the value of the
Type_ field, in a conditional statement or a selection statement. In my opinion, this field must exist, because I need to distinguish the token type in some way. The line
case TGame_UInt8 of is useless to me. What does it give me? Nothing but disappointment that it has to exist in code.
My proposal is to add a new data type and extend the syntax so that unions can be conveniently and legibly declared (variant-records are to be left intact). Below is a comparison of the record with the proposed union:
type type
TGame_TextToken = record TGame_TextToken = record
Type_: TGame_UInt8; Type_: TGame_UInt8;
case TGame_UInt8 of union
GAME_TEXT_TOKEN_WORD: ( Word: record Word: record
Word: PGame_Char; Word: PGame_Char;
Rect: TGame_RectS32; Rect: TGame_RectS32;
end ); end;
GAME_TEXT_TOKEN_WHITE: ( White: record White: record
NumChars: TGame_SInt32; NumChars: TGame_SInt32;
W: TGame_SInt32; W: TGame_SInt32;
H: TGame_SInt32; {vs} H: TGame_SInt32;
end ); end;
GAME_TEXT_TOKEN_COLOR: ( Color: record Color: record
R: TGame_UInt8; R: TGame_UInt8;
G: TGame_UInt8; G: TGame_UInt8;
B: TGame_UInt8; B: TGame_UInt8;
end ); end;
GAME_TEXT_TOKEN_ALPHA: ( Alpha: record Alpha: record
Level: TGame_UInt8; Level: TGame_UInt8;
end ); end;
GAME_TEXT_TOKEN_FONT: ( Font: record Font: record
Index: TGame_UInt8; Index: TGame_UInt8;
end ); end;
end; end;
end;
Variant-records look like syntactical bloatware, while the record with the union proposed is short, clean and very readable.