About the author
I have completed porting a game, Digger, written by Lutz Roeder, to Delphi.
Lutz originally wrote the game in C#. I've ported the game to Delphi so that it can run on .NET, Windows and (potentially) Linux.
I initially ported the code to Delphi.NET, before starting to port it to Delphi for Win32. During porting to Win32, I came across the following construct.
const t: array[0..15] of &Type=( typeof(Nothing), typeof(Stone), typeof(Ground), typeof(Ghost180), nil, typeof(Diamond), typeof(Wall), typeof(Ghost90L), nil, typeof(UvStone), typeof(DiggerPanel.Digger), typeof(Ghost90LR), typeof(&DiggerPanel.Exit), nil, typeof(Changer), typeof(Ghost90R) );begin SetSprite(x, y, Activator.CreateInstance(t[id]) as Sprite);end;
What the code fragment does is to create an instance of any of the classes listed above. If id is 0, then Nothing.Create is called. If id is 1, then Stone.Create is called. All the classes listed above are descendents of Sprite, and the constructor of each Sprite class is a static constructor.
While porting, I've discovered that there's no way to store the function results of typeof in a constant array.
For example, the code doesn't compile, where TRex, Compy and Apa are all classes.
const TDinosaurs: array[0..2] of Pointer = (typeof(TRex), typeof(Compsognathus), typeof(Apatosaurus));
Instead of translating literally, I've changed the code in such a way as to translate the original code into the native Delphi language.
So, the above segment of code now looks like,
type SpriteClass = class of Sprite;const t: array[0..15] of SpriteClass = ( Nothing, Stone, Ground, Ghost180, nil, Diamond, Wall, Ghost90L, nil, UvStone, DiggerPanelWin32_1.Digger, Ghost90LR, DiggerPanelWin32_1.Exit, nil, Changer, Ghost90R );var ASprite: Sprite;begin ASprite := t[id].Create; SetSprite(x, y, ASprite);end;
In addition, the constructor for Sprite is now virtual, and the descendents of Sprite overrides the constructor, so that a call to t[id].Create calls the correct constructor polymorphically.
(Oh God!) Danny, I wish Delphi can warn me when a constructor call needs to be virtual. ;o)
This article discusses the new Delphi 8 property access specifiers.