Log in

View Full Version : small delphi problem


esby
7th January 2005, 01:33
the structure first ...



type
class TClip = class
private
<snip> // some datas
public
constructor create;
class function Screate:TClip; virtual; abstract;
class function ClipIdent:string; virtual; abstract;
<snip>
end;

class TClipDerived = class (TClip)

public
constructor create;
class function Screate:TClip; override;
class function ClipIdent:string; override;
end;

class TClipDerived2 = class (TClip)

public
constructor create;
class function Screate:TClip; override;
class function ClipIdent:string; override;
end;


var
filterTypeList:TClassList;


end;
Implementation

{TClip}
constructor TClip.create;
begin
<snip>
end;

{TClipDerived}
creator TClipDerived.create;
begin
inherited create;
<snip>
end;

Class function TClipDerived.Screate:TClip;
begin
result := create;
end;

class function TClipDerived.ClipIdent: string;
begin
result :='TClipDerived';
end;

{TClipDerived2}
creator TClipDerived2.create;
begin
inherited create;
<snip>
end;

Class function TClipDerived2.Screate:TClip;
begin
result := create;
end;

class function TClipDerived2.ClipIdent: string;
begin
result :='TClipDerived2';
end;

initialization


filterTypeList := TClassList.Create;

filterTypeList.Add(TClipDerived);
filterTypeList.Add(TClipDerived2);





Now the problem...

filterTypeList inventories the different filters available...

Now I want to instanciate any clip i could need according to its clipIdent string.
for example, if I need a TClipDerived2 instance
I call


clip := InvokeClip('TClipDerived2');

with

function InvokeClip(str:string):TClip;
var i:integer;
clip:TClip;
begin
result := nil;
i:=0;
while (result=nil) and (i< filterTypeList.Count)
do begin
clip := TClip(filterTypeList.Items[i].NewInstance);
if AnsiSameText(str,clip.ClipIdent)
then result := clip.Screate;
clip.free;
end;
end;




But to achieve that, I am finding that the InvokeClip is a bit too hackish for me... as I create a dummy instance of any class stored in the class list, which I check versus classIdent...

Any better solution?

thanks in advance.

esby

[Toff]
7th January 2005, 23:19
You can probably simplify a bit by using the ClassName field of the TClass (in fact a TObject).

TClip = class
end;

TClipA = class(TClip)
end;

TClipB = class(TClip)
end;

function InvokeClip(ClipName : string) : TClip;
var Clip : TClip;
i : Integer;
begin
Result := nil;
for i:=0 to filterTypeList.Count-1 do
begin
if (filterTypeList[i].ClassName = ClipName) then
begin
Result := filterTypeList[i].NewInstance as TClip;
Break;
end;
end;
end;

esby
7th January 2005, 23:29
yeah,
I've think to it, and I'll probably go this way.
And I can probably simplifly by removing screate too... (and using the default constructor).
Now I was wondering if there was any chance to get access to the class method of an object via the TClass container... Apparently not, without creating an instance, which is kinda sad for accessing a class method.

esby

esby
7th January 2005, 23:40
ok, I solved my problem


type TClassClip = class of Tclip;

<snip>

function InvokeClip(str:string):TClip;
var i:integer;
begin
result := nil;
i:=0;
while (result=nil) and (i< filterTypeList.Count)
do if AnsiSameText(str,TClassClip(filterTypeList.Items[i]).ClipIdent)
then result := TClassClip(filterTypeList.Items[i]).create
else inc(i);
end;

[Toff]
8th January 2005, 22:30
Any reason why you wanna use your ClipIdent class method?
As I've said in Delphi you already have a field called ClassName that exactly does this job.

For example, with this declaration :

TClipA = class(TClip)
end;

You have :
TClipA.ClassName = 'TClipA'

Or maybe you wan't to add (and check) for other characteristics?

esby
8th January 2005, 23:29
Well, I could use the class name,
but since I am copying the avs structure,
and intend to to do the same with the parser structure,
i intend to be able to parse 'avisource' as a Tavisource...
so I'll need the identifier anyway.

esby