在二次开发中实现脚本对算定义类的调用
如何为一个类添加脚本支持,FastScript是解释执行的语言,通过对语义的分析来执行
FastScript已经对Delphi常用的类做好了解释,比如fs_iformsrtti解释了脚本对窗体的调用,fs_iinirtti解释了脚本对TIniFiles类的使用
一个类的published属性,在RTTI的支持下可以自动解释,关键是函数的解释
模拟下面源代码的编写,就可以在脚本中直接使用该类
unit fs_iMyClassRTTI; //按FastScript的习惯命名, fs_类名RTTI.pas
interface
uses
Windows, Messages, SysUtils, StrUtils, Variants, Classes, Graphics, Controls, Forms;
type
TMyClass=class(TObject)
private
FNewProp:string;
FNewProp2:string;
public
constructor Create;
function Func1(int i):int;
function Func2(str:TStrings):boolean;
public
property NewProp2:string read FNewProp2 write FNewProp2;
published
property NewProp:string read FNewProp write FNewProp;
end;
implementation
type
TFunctions = class(TfsRTTIModule)
private
private
//函数调用
function CallMethod(Instance: TObject; ClassType: TClass; const MethodName: String; Caller: TfsMethodHelper): Variant;
//属性获取
function GetProp(Instance: TObject; ClassType: TClass; const PropName: String): Variant;
//属性设置
procedure SetProp(Instance: TObject; ClassType: TClass; const PropName: String; Value: Variant);
public
//在构照器进行类型,函数说明
constructor Create(AScript: TfsScript); override;
end;
{ TMyClass }
function TMyClass.Func1(int i):int;
begin
result:=0;
end;
function TMyClass.Func2(str:TStrings):boolean;
begin
result:=True;
end;
{ TFunctions }
function TFunctions.CallMethod(Instance: TObject; ClassType: TClass; const MethodName: String; Caller: TfsMethodHelper): Variant;
begin
Result := 0;
//根据函数名调用实际执行的函数,关键当参数为类对象时的转换,看函数Func2的调用写法
if ClassType = TMyClass then
begin
if MethodName = 'CREATE' then
Result := Integer(TMyClass.Create)
else if MethodName = 'FUNC1' then
Result:= TMyClass(Instance).Func1(Caller.Params[0]))
else if MethodName = 'FUNC2' then
Result := TMyClass(Instance).Func2(TStrings(Integer(Caller.Params[0])))
end;
end;
constructor TFunctions.Create(AScript: TfsScript);
begin
inherited;
with AScript do
begin
//添加类说明,第一个参数为被说明的类,第二个参数为该类型的基类
with AddClass(TMyClass, 'TObject') do
begin
//添加函数定义说明,第二个参数是该函数由哪个函数调用
AddMethod('function Func1(int i):int;',CallMethod);
AddMethod('function Func2(str:TStrings):boolean;',CallMethod);
end;
end;
end;
function TFunctions.GetProp(Instance: TObject; ClassType: TClass; const PropName: String): Variant;
begin
//添加属性说明,published属性不必添加
if ClassType = TMyClass then
begin
if PropName = 'NewProp2' then
Result := TMyClass(Instance).NewProp2;
end
end;
procedure TFunctions.SetProp(Instance: TObject; ClassType: TClass; const PropName: String; Value: Variant);
begin
if ClassType = TMyClass then
begin
if PropName = 'NewProp2' then
TMyClass(Instance).NewProp2:=Value;
end
end;
initialization
//文件加载时,将解析类TFunctions添加到脚本引擎RTTI库
fsRTTIModules.Add(TFunctions);
finalization
fsRTTIModules.Remove(TFunctions);