在二次開發中實現腳本對算定義類的調用
如何為一個類添加腳本支持,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);