Различия между DelphiScript и Delphi
Различия между DelphiScript и Delphi
В этом разделе рассматриваются ключевые различия между языком сценариев DelphiScript и языком программирования Delphi от Embarcadero, а также то, как это влияет на API Altium Designer.
Система скриптинга Altium Designer использует нетипизированный язык DelphiScript, поэтому в скриптах нет типов данных. Хотя вы можете объявлять переменные и их типы, а также указывать типы для функций/процедур или параметров методов для удобства чтения, DelphiScript будет преобразовывать необъявленные переменные во время выполнения скрипта. Поэтому, например, вы не можете определять записи (records) или классы.
Переменные Delphi Script
Все переменные в скрипте имеют тип Variant, а типы в объявлении переменных игнорируются и могут быть опущены. Поэтому эти три объявления корректны:
Var
a : Integer;
Var
b : Integer;
Var
c, d;
Типы параметров в объявлении процедуры/функции также игнорируются и могут быть опущены. Например, этот код корректен:
Function Sum(a, b) : Integer;
Begin
Result := a + b;
End;
В целом, variant можно использовать для хранения данных любого типа и выполнения множества операций и преобразований типов. Variant проверяется по типу и вычисляется во время выполнения. Компилятор не выдаст предупреждение о возможных ошибках в коде — их можно выявить только при тщательном тестировании. В целом, участки кода, использующие variant, можно считать интерпретируемым кодом, поскольку многие операции нельзя разрешить до момента выполнения. Это может влиять на скорость работы кода.
Следствием этого является то, что после объявления variant-переменной и присваивания ей variant-значения, его можно копировать в любой совместимый или несовместимый тип данных:
Var
V;
Begin
// variable V can be assigned values of several different types:
V := 10;
V := 'Hello, World';
V := 45.55;
End;
Если переменной присвоен несовместимый тип данных, интерпретатор DelphiScript выполняет преобразование, если это возможно. В противном случае возникает ошибка времени выполнения. На практике variant хранит информацию о типе вместе с данными, поэтому DelphiScript работает медленнее, чем эквивалентный скомпилированный код Embarcadero Delphi.
Множества (Sets) в скриптах
В DelphiScript нет типов Set и не поддерживаются операторы Set, в отличие от языка Delphi, где типы Set есть и операторы Set поддерживаются.
Чтобы использовать множества в скриптах DelphiScript, применяйте встроенные функции, которые выполняют операции с множествами в скрипте.
См. статью Using Sets in DelphiScript для получения дополнительной информации
Внутренние функции или процедуры
При рассмотрении использования функций и процедур inside a Function or Procedure, рекомендуется писать автономные функции/процедуры — хотя рекурсивные процедуры/функции допускаются.
Следующий фрагмент функции не рекомендуется:
Function A
Function B
Begin
// blah
End;
Begin
B;
End;
Рекомендуемая структура функции:
Function B
Begin
// blah
End;
Function A
Begin
B;
End;
Ключевое слово Result
Используйте ключевое слово Result, чтобы задавать возвращаемое значение внутри блока функции. Например:
Function Foo : String;
Begin
Result := 'Foo Foo';
End;
Вложенные подпрограммы
Вложенные подпрограммы поддерживаются, но переменные функции верхнего уровня нельзя использовать из вложенной.
Элементы массива
Тип элементов массива игнорируется и может быть опущен, поэтому эти два объявления эквивалентны:
Var
x : array [1..2] of double;
Var
x : array [1..2];
Обратите внимание: вы не можете объявлять типы массивов, но можете объявлять массивы как переменные.
Illegal example:
Type
TVertices = Array [1..50] Of TLocation;
Var
NewVertices : TVertices;
Legal example:
Var
NewVertices : Array [1..50] of TLocation;
Объявление открытого массива (Open Array)
Объявление Open Array не поддерживается.
Ключевое слово Case
Ключевое слово Case можно использовать для любого типа. Поэтому следующее допустимо:
Case UserName of
'Alex', 'John' : IsAdministrator := true;
'Peter' : IsAdministrator := false;
Else
Raise('Unknown user');
End;
Объявления классов
В DelphiScript нельзя определять новые классы, но можно использовать существующие классы DelphiScript и создавать их экземпляры. Например, классы TList и TStringList можно создавать и использовать в ваших скриптах.
See also
TList
TStringList
Функция CreateObject
Функцию CreateObject можно использовать для создания объектов, которые будут неявно освобождены, когда больше не используются.
Поэтому вместо:
Procedure Proc;
Var
l;
Begin
l := TList.Create;
Try
// do something with l
Finally
L.Free;
End;
...можно написать:
Procedure Proc;
Var
l;
Begin
l := CreateObject(TList);
// Do something with l
End;
See also
Функция CreateObject.
Генерация исключений (Raise)
Ключевое слово Raise можно использовать без параметров, чтобы повторно сгенерировать последнее исключение. Raise также можно использовать со строковым параметром, чтобы сгенерировать исключение с указанным текстом сообщения. Объекты Exception в DelphiScript не поддерживаются, потому что ключевое слово On не поддерживается.
Example:
Raise(Format('Invalid value : %d', [Height]));
See also
Ключевые слова Try, Finally и Raise.
ThreadVar
В Delphiscript ключевое слово Threadvar трактуется как Var. Обратите внимание: в Embarcadero Delphi переменные, объявленные с использованием ключевого слова Threadvar, имеют разные значения в каждом потоке.
Операторы множеств (Set Operators)
Оператор множеств In не поддерживается. Оператор InSet можно использовать, чтобы проверить, является ли значение элементом множества. Например:
If InSet(fsBold, Font.Style) then
ShowMessage('Bold');
Обратите внимание, что операторы множеств Delphi +, -, *, <=, >= работают некорректно. Вместо них используются встроенные функции Delphiscript MkSet, MkSetRange, SetUnion, SetDifference, SetIntersection, SubSet and InSet:
ASet := BSet + CSet; \\ should be changed to
ASet := SetUnion(BSet, CSet);
Конструкторы множеств [...] не поддерживаются — используйте функцию MkSet для создания множества:
Font.Style := MkSet(fsBold, fsItalic);
See also
MkSet keyword
MkSetRange keyword
InSet keyword
SetDifference keyword
SetIntersection keyword
SetUnion keyword
SubSet keyword
InSet keyword
Операторы
Операторы ^ и @ не поддерживаются.
Директивы
Следующие директивы не поддерживаются (обратите внимание, что некоторые из них устарели и также не поддерживаются Embarcadero Delphi): absolute, abstract, assembler, automated, cdecl, contains, default, dispid, dynamic, export, external, far, implements, index, message, name, near, nodefault, overload, override, package, pascal, private protected, public, published, read, readonly, register, reintroduce, requires, resident, safecall, stdcall, stored, virtual, write, writeonly.
Также обратите внимание, что директива in в секции Uses игнорируется.
Игнорируемые ключевые слова
Ключевые слова interface, implementation, program и unit в DelphiScript игнорируются. Скрипты могут содержать их, но они не оказывают никакого эффекта — однако эти ключевые слова могут улучшить читаемость скриптов.
Неподдерживаемые ключевые слова
Следующие ключевые слова не поддерживаются в DelphiScript:
-
as, asm, class, dispinterface, exports, finalization, inherited, initialization, inline, interface, is, library, object, out, property, record, resourcestring, set, supports, type.
Следующие функции Delphi RTL не поддерживаются в DelphiScript:
-
Abort, Addr, Assert, Dec, FillChar, Finalize, Hi, High, Inc, Initialize, Lo, Low, New, Ptr, SetString, SizeOf, Str, UniqueString, VarArrayRedim, VarArrayRef, VarCast, VarClear, VarCopy.
Функции из модуля Windows Delphi (файл windows.pas) не поддерживаются (например, функция RGB не поддерживается).
Использование API Altium Designer в скриптах
Вы не можете создавать собственные типы записей (records) или классов с помощью DelphiScript и создавать их экземпляры в скрипте, однако вы можете использовать некоторые классы из API Altium Designer. Например, классы TStringList и TList можно создавать и использовать как контейнеры для хранения данных (обычно одного типа) в соответствии с потребностями скрипта.
Объектные интерфейсы API, представляющие объекты Altium Designer, доступны для использования в скриптах. Например, у вас есть возможность обновлять объекты проекта в документах схемы (Schematic) и PCB, используя интерфейсы объектов схемы и интерфейсы объектов PCB.
По соглашению к именам интерфейсов добавляется буква «I» в начале. Например, IPCB_Board представляет интерфейс для существующего PCB-документа.
Пример использования PCB-интерфейсов в скрипте:
Procedure ViaCreation;
Var
Board : IPCB_Board;
Via : IPCB_Via;
Begin
Board := PCBServer.GetCurrentPCBBoard;
If Board = Nil Then Exit;
(\* Create a Via object\* )
Via := PCBServer.PCBObjectFactory(eViaObject, eNoDimension, eCreate_Default);
Via.X := MilsToCoord(7500);
Via.Y := MilsToCoord(7500);
Via.Size := MilsToCoord(50);
Via.HoleSize := MilsToCoord(20);
Via.LowLayer := eTopLayer;
Via.HighLayer := eBottomLayer;
(* Put this via in the Board object*)
Board.AddPCBObject(Via);
End;
В скриптах можно использовать следующие API:
- Некоторые функции и классы Embarcadero Delphi™, а также расширения DelphiScript
- Client API
- PCB Server API
- Schematic Server API
- Workspace Manager Server API
- Integrated Library API
- Функции API Altium Designer
- Параметрические процессы
Дополнительная информация
Просмотрите скрипты в downloadable коллекции скриптов, чтобы увидеть, как в скриптах используются объектные интерфейсы и функции Altium Designer, а также объекты и функции Delphi.
См. основную документацию Scripting для информации о написании скриптов для Altium Designer.
См. руководство Using the Altium Designer API для подробностей о том, как использовать объекты проектирования и их интерфейсы в ваших скриптах.
См. Altium Designer API Reference для информации о наборе API Altium Designer и их интерфейсных объектах для скриптов.