Jon Lennart Aasenden
Jon Lennart Aasenden

Reputation: 4020

Add properties to an object at runtime

Delphi RTTI makes it very easy to enumerate and extract information about an object's properties, fields and methods at runtime. However, is it possible to add a property and field to an object at runtime?

I realize that this would involve changes to the VMT if it depends on a getter / setter, which is why i mentioned fields, so the injected property could be bound to said field and thus avoid appending nodes to the VMT tree.

This might seem like a silly question, but I am working on a layout designer. The objects you can move around and position represents web elements, that all have different properties.

It would save me a lot of time if I somehow could populate these proxy design objects with the actual properties from the web elements. Then I could use a normal object inspector directly on them, rather than having to manually populate the inspector rows.

Serialization would also be easier since I could use the standard Delphi way, as opposed to hand writing IO code.

I doubt this is possible without some form of hack, but it's always best to ask.

Upvotes: 2

Views: 1214

Answers (2)

Eric Grange
Eric Grange

Reputation: 6211

An alternative approche would be to not rely on straight RTTI, but rather on an intermediate description layer.

You could initialize the intermediate layer from the RTTI for what's in the RTTI, and add extras for your dynamic properties.

This would also allow you to shield your layout designer from the RTTI quirks. Most of what the RTTI expose is very low level, and a lot of it is "unsafe" in that it can trigger unsafe behaviors in objects (and thus crash your designer).

This is especially relevant if you dot not have 100% control over the objects to fix their issues, which I guess you do not, as otherwise you would not need dynamic properties.

During interactive design invalid property values are the norm: partial inputs, typing errors, incoherent settings, etc. all these will require some kind of context-specific sanitizing, which an intermediate layer can provide.

In the Delphi IDE, the design-time sanitizing is basically up to each individual component's implementation and the csDesigning component state. While it is simple, there is very limited feedback a component can provide on incoherent or invalid properties.

Upvotes: 1

Charlie
Charlie

Reputation: 23798

Delphi is a statically typed language in its root. However, you can use variants - custom variants to be precise to create dynamic properties.

type
  TMyCustomObject= class(TInvokeableVariantType)
  public
    procedure Clear(var V: TVarData); override;
    procedure Copy(var Dest: TVarData; const Source: TVarData; const Indirect: Boolean); override;
    function GetProperty(var Dest: TVarData; const V: TVarData; const Name: string): Boolean; override;
    function SetProperty(const V: TVarData; const Name: string; const Value: TVarData): Boolean; override;
  end;

You can implement few virtual methods in the above code and get the desired results.

Here is a tutorial: http://www.uweraabe.de/Blog/2010/08/07/a-magical-gathering-part-2/

Upvotes: 2

Related Questions