Example of RTTI - list of types in program

by Radek Červinka 20. October 2010 23:43

I played with new RTTI (Run Time Type Information) and I was so impressed with the ease of use. The result is a simple program that displays a tree of known types, including methods, fields and property. It also demonstrates the effective use of anonymous methods, generic types, and all in 100 lines, including the declaration.

Strom s RTTI

Create form with TTreeView aligned to client and this code.

    1unit Unit1;
    2
    3interface
    4
    5uses
    6  Forms, StdCtrls, ComCtrls, Classes, Controls, Generics.Defaults;
    7
    8type
    9  TForm1 = class(TForm)
   10    tv1: TTreeView;
   11    procedure FormCreate(Sender: TObject);
   12  private
   13    { Private declarations }
   14    procedure mFillTree;
   15  public
   16    { Public declarations }
   17  end;
   18
   19var
   20  Form1: TForm1;
   21
   22implementation
   23
   24{$R *.dfm}
   25
   26uses
   27  SysUtils, Rtti, Generics.Collections, TypInfo;
   28
   29procedure TForm1.FormCreate(Sender: TObject);
   30begin
   31  tv1.Items.BeginUpdate;
   32  try
   33    mFillTree;
   34  finally
   35    tv1.Items.EndUpdate;
   36  end;
   37end;
   38
   39procedure TForm1.mFillTree;
   40var
   41  ctx: TRttiContext;
   42  t: TRttiType;
   43  oNode, oTempNode: TTreeNode;
   44  arTypes: TArray<Rtti.TRttiType>;
   45  cmp:TDelegatedComparer<Rtti.TRttiType>;
   46  arMethods: TArray<TRttiMethod>;
   47  m: TRttiMethod;
   48  p: TRttiProperty;
   49  f: TRttiField;
   50
   51begin
   52
   53  ctx:= TRttiContext.Create;
   54  try
   55    // get all known types
   56    arTypes := ctx.GetTypes;
   57
   58    // comparator with anonymous method
   59    cmp := TDelegatedComparer<Rtti.TRttiType>.Create(
   60      function (const Left, Right: TRttiType): Integer
   61        begin
   62          Result := AnsiCompareStr(Left.QualifiedName, Right.QualifiedName);
   63        end);
   64
   65    // sort with created comparer 
   66    TArray.Sort<Rtti.TRttiType>(arTypes, cmp); 
   67    cmp.Free;
   68
   69    // sorted types parse with for in do
   70    for t in arTypes do
   71    begin
   72      // uzel ve stromu pro typ
   73      oNode:= tv1.Items.AddChild(nil, t.QualifiedName);
   74
   75      // child node for methods
   76      oTempNode := tv1.Items.AddChild(oNode, 'metody');
   77      for m in t.GetMethods do
   78        tv1.Items.AddChild(oTempNode, m.ToString);
   79
   80      // child node for property
   81      oTempNode := tv1.Items.AddChild(oNode, 'property');
   82      for p in t.GetProperties do
   83        tv1.Items.AddChild(oTempNode, p.ToString);
   84
   85      // child node for pole
   86      oTempNode := tv1.Items.AddChild(oNode, 'pole');
   87      for f in t.GetFields do
   88        tv1.Items.AddChild(oTempNode, f.ToString);
   89
   90    end;
   91  finally
   92    ctx.Free;
   93  end;
   94end;
   95
   96end.

Nice code is from line 58, where use generic comparer (there are different ones), but core implementation is with anonymous method.

Declaration TDelegatedComparer is in unit Generics.Defaults and looks like (TDelegatedComparer is only one of possible class):

    1TComparison<T> = reference to function(const Left, Right: T): Integer;
    2
    3  TDelegatedComparer<T> = class(TComparer<T>)
    4  private
    5    FCompare: TComparison<T>;
    6  public
    7    constructor Create(const ACompare: TComparison<T>);
    8    function Compare(const Left, Right: T): Integer; override;
    9  end;

Compilation on Delphi 2010 plus.

Tags: , ,

Practices

Comments are closed