Add Indexer property wizard
Often when you add an indexer / array property you need to insert additional members that implement the indexer. For example a field to store the values, make sure there's a constructor and add some initialization code. The ModelMaker Code Explorer Add Indexer Wizard is used to centralize this process. The wizard is highly customizable using Indexer implementation templates.
Pascal Example: adding an Indexer / Array property
Assume you have a class TStore that stores TThings. To expose the Things we define a read-only indexer property Things[Index] like this:
TStore = class(TObject)
private
function GetThings(Index: Integer): TThing;
public
property Things[Index: Integer]: TThing read GetThings; default;
end;
Apart from the property declaration there are usually other members required to fully implement this indexer property. For example: you'll need a field of type TList or TObjectList to actually store the things. This field must be initialized in the constructor and Freed in the destructor. You additionally might want to expose a Count property to allow iteration. The TStore class interface would then look like this:
TStore = class(TObject)
private
FThings: TList; // stores TThings
function GetCount: Integer; // return FThings.Count
function GetThings(Index: Integer): TThing; // return FThings[Index]
public
constructor Create; // create FThings
destructor Destroy; override; // destroy FThings
property Count: Integer read GetCount; // Number of Things
// the actual indexer property
property Things[Index: Integer]: TThing read GetThings; default;
end;
The above scenario is very common and ModelMaker Code Explorer comes with a highly specialized and flexible "Add Indexer" wizard that automates (most of) the entire process.
Just click OK in this dialog and the above mentioned class interface is inserted including the corresponding implementation code:
begin
inherited Create;
FThings := TList.Create;
end;
destructor TStore.Destroy;
begin
FreeAndNil(FThings);
inherited Destroy;
end;
function TStore.GetCount: Integer;
begin
Result := FThings.Count;
end;
function TStore.GetThings(Index: Integer): TThing;
begin
Result := TThing(FThings[Index]);
end;
Customizing the wizard
The indexer implementation templates are customizable and new ones can be added. Referring to the above example: More advanced implementations could include methods FindThing(..), AddThing(..), DeleteThing(..) etc. Indexer Templates are stored in directory [install-root]\Shared\Indexers. Typically "C:\Program Files\ModelMakerTools\Shared\Indexers".
The template that defines the implementation for the above mentioned TStore / Things example looks like this:
//MM#:description=Simple TList implementation with Count
//MM#:getter=begin\N Result := <!PropertyType!>(F<!PropertyName!>[<!PropIndexCallParams!>]);\Nend;
//MM#:ctor=F<!PropertyName!> := TList.Create;
//MM#:dtor=FreeAndNil(F<!PropertyName!>);
unit IndexerTemplate1;
interface
type
TCodeTemplate = class
private
F<!PropertyName!>: TList;
function GetCount: Integer;
public
property Count: Integer read GetCount;
end;
implementation
function TCodeTemplate.GetCount: Integer;
begin
Result := F<!PropertyName!>.Count;
end;
end.

