FoxBase!
msgbartop
Блог Oracle разработчика
msgbarbottom
foxbase

08.01.2012 RemObjects PascalScript

RemObjects PascalScript
В этой статье я хочу рассказать о замечательном компоненте для Delphi RemObjects PascalScript. Суть этого компонента в том, что вы можете писать скрипты, синтаксически подобные языку Pascal и выполнять их. Движок исполнения скриптов легко встраивается в вашу программу и может позволить расширить функциональность вашего проекта возможностями встроенного скриптового языка. Иногда подобная функциональность просто незаменима и позволяет не изобретать велосипед написанием собственного компилятора или интерпретатора.
RemObjects PascalScript является бесплатным компонентом и поставляется в исходных кодах, хорошо отлажен и практически безглючен. Скачать его можно по этой ссылке.
В поставке PascalScript идет несколько компонентов, а также множество примеров, изучив которые можно сделать то, что вам нужно в вашем проекте. Поэтому подробно останавливаться на основах PascalScript мы не будем, но остановимся на следующих аспектах:
- Вызов из скриптов процедур и функций, подготовленных вами заранее
- Вызов свойств и методов ваших классов
Фактически, эти возможности являются наиболее ценными, иначе простое исполнение стандартных программных конструкций вряд ли сможет принести вам значительную пользу. Ведь главное в скриптовых движках - дать пользователю возможность писать небольшие программные конструкции, гибко расширяющие функциональность вашей системы и способные использовать заранее подготовленные мощные функции, а также экземпляры классов и их методы.

Тестовый проект

Создадим простой тестовый проект для демонстрации возможностей RemObjects PascalScript. На форму проекта поместим два TMemo (текст скрипта и сообщение результатов компиляции), одну кнопку для компиляции скрипта и сам компонент TPSScript (который присутствует в Tool Palette после установки PascalScript)
PascalScript Delphi components
Форма проекта будет выглядеть примерно так:
PascalScript test form
Код компиляции, связанный с кнопкой Compile будет такой:
procedure TForm1.CompileClick(Sender: TObject);
  var i: integer;
begin
  PSScript1.Script.Text:=Memo1.Text;
  if PSScript1.Compile then
  begin
    Memo2.Text:='No errors';
    PSScript1.Execute;
  end else
  begin
    Memo2.Lines.Clear;
    for i := 0 to PSScript1.CompilerMessageCount -1 do
      Memo2.Lines.Add(PSScript1.CompilerMessages[i].MessageToString);
  end;
end;
Тестовый код успешно компилируется. Про тонкости встроенной в PascalScript функциональности смотрите примеры, поставляемые вместе с компонентом, нас же будут интересовать вопросы, озвученные в начале статьи.

Вызов внешней функции

Одна из наиболее востребованных и интересных возможностей. Напишем простейшую функцию:
function TForm1.TestMessage(AText: string): boolean;
begin
  ShowMessage(AText);
  Result:=true;
end;
Теперь ее надо сделать доступной в PascalScript. Для этого в событие onCompile компонента PSScript1 добавим следующий код:
  Sender.AddMethod(Self, @TForm1.TestMessage,'function TestMessage(AText: string): boolean;');
Теперь можно выполнить такой скрипт:
begin
  TestMessage('Test message...');
end;
Выполнив этот скрипт, мы получим окно с переданным в функцию сообщением.

Вызов методов и свойств существующего экземпляра класса

Добавим в uses следующие модули:
uses ... , uPSRuntime, uPSCompiler;
Напишем простейший класс:
TTestClass=class
public
  data: string;
  procedure ShowMsg(AText: string);
end;
...
procedure TTestClass.ShowMsg(AText: string);
begin
  ShowMessage(AText);
end;
В форме Form1 создадим экземпляр нашего класса:
TestClass: TTestClass;
...
procedure TForm1.FormCreate(Sender: TObject);
begin
  TestClass:=TTestClass.Create;
end;
Теперь нам надо сделать экземпляр этого класса и его метод ShowMsg и свойство data видимым в PascalScript. Для этого добавим код импорта класса, его свойств и методов, а также код регистрации класса в соответствующие обработчики событий.
Код импорта класса для компилятора:
procedure TForm1.PSScript1CompImport(Sender: TObject; x: TPSPascalCompiler);
begin
  with x.AddClassN(x.FindClass('TOBJECT'),'TTestClass') do
  begin
    RegisterProperty('data', 'string', iptrw);
    RegisterMethod('Procedure ShowMsg( AText : string)');
  end;
end;
Код импорта класса для Runtime:
procedure TForm1.PSScript1ExecImport(Sender: TObject; se: TPSExec; x: TPSRuntimeClassImporter);

procedure TTestClass_data_W(Self: TTestClass; const T: string);
begin
  Self.data := T;
end;

procedure TTestClass_data_R(Self: TTestClass; var T: string);
begin
  T := Self.data;
end;

begin
  with x.Add(TTestClass) do
  begin
    RegisterPropertyHelper(@TTestClass_data_R,@TTestClass_data_W,'data');
    RegisterMethod(@TTestClass.ShowMsg, 'ShowMsg');
  end;
end;
Код регистрации класса для компилятора:
procedure TForm1.PSScript1Compile(Sender: TPSScript);
begin
  Sender.AddRegisteredPTRVariable('TestClass', 'TTestClass');
end;
Код регистрации экземпляра класса для Runtime:
procedure TForm1.PSScript1Execute(Sender: TPSScript);
begin
  PSScript1.SetPointerToData('TestClass', @FTestClass, PSScript1.FindNamedType('TTestClass'));
end;
Все, теперь можно использовать свойства и методы экземпляра класса непосредственно в скриптах. Например:
begin
  TestClass.Data:='Test Message';
  TestClass.ShowMsg(TestClass.Data);
end.
Код не требует подробного комментария, его использование вполне понятно при вдумчивом изучении тестового примера.
www.foxbase.ru




Смотрите также:



Оставьте свой комментарий

Вы должны быть авторизированны, чтобы оставить комментарий.