Working with Script API Objects in Altium Designer
スクリプティングシステムのより強力な機能の一つは、そのアプリケーションプログラミングインターフェース(API)を通じてAltium Designerの設計オブジェクトにアクセスできることです。これにより、スクリプトは開かれた設計ドキュメント内の設計オブジェクトプロパティを読み取り、変更することができます。
オブジェクトモデルは、Embarcadero Delphiのオブジェクトインターフェース技術を適用することでAltium Designer内でアクセスされ、スクリプトに公開されるオブジェクトインターフェースを実装するために使用されます。本質的に、オブジェクトインターフェースはAltium Designer内の既存のオブジェクトを参照します。したがって、スキーマティックドキュメント内の設計オブジェクトはスキーマティックインターフェースを使用して更新され、PCBドキュメント内のものはPCBインターフェースを使用して更新されます。
スクリプティングシステム自体はEmbarcadero Delphiで書かれており、Delphiオブジェクトとツールパレットパネルコンポーネントを通じて利用可能なDelphiビジュアルコンポーネントライブラリのサブセットを提供します。
Altium Designerシステムは、単一のクライアント実行可能ファイルと、プラグインされたサーバー拡張機能で構成されています。クライアントモジュールはDXPソフトウェア技術プラットフォームの一部であり、Altium Designerユーザーによって生成されたアクションを処理します。
サーバー拡張機能は、ユーザーによって要求されたドメインタスクに応じて特化した機能を提供します。例えば、スキーマティックとPCBサーバーは、設計プロセスで使用される2つの主要なドキュメントエディターサーバーであり、それぞれが独自のドキュメントタイプ(設計およびライブラリドキュメント)を持っています。
Altium Designerのクライアントおよびサーバーの範囲については、オブジェクトモデルを参照するためのオブジェクトインターフェースが利用可能です。オブジェクトインターフェースにはメソッドがあり、多くの場合、プロパティも持っています:
- メソッドは、オブジェクトインターフェースから呼び出される手続きまたは関数であり、オブジェクトが行うことを表します。
- オブジェクトインターフェースのプロパティは、読み取りまたは変更できる属性です。プロパティはGetおよびSetメソッドによって実装されますが、一部のプロパティは読み取り専用であり、値を返すことはできますが設定することはできません。
例えば、PCB APIオブジェクトモデルのIPCB_Componentインターフェースには、Height プロパティと、そのReadおよびWrite識別子によってサポートされる関連メソッドがあります。コンポーネントの高さプロパティは、GetState_HeightおよびSetState_Heightメソッドを使用するか、プロパティ自体(IPCB_Component.Height)を直接参照することでアクセスできます。CreateComponentOnPCBスクリプト例(Example Scriptsコレクション内)で実装例を参照してください。
DXPオブジェクトインターフェース
Altium Designerのスクリプティングでは、オブジェクトのインスタンスを作成するのではなく、既存のオブジェクトを参照するオブジェクトインターフェースを使用します。オブジェクトモデルとそれをサポートするインターフェースは、次のように機能的にグループ化されています。各サーバー(またはクライアント)APIは、特定のスクリプティングインターフェースの階層を提供します:
- クライアントオブジェクトモデル
- ワークスペースマネージャーオブジェクトモデル
- スキーマティックオブジェクトモデル
- PCBオブジェクトモデル
- 統合ライブラリオブジェクトモデル
- Nexusオブジェクトモデル
プロジェクト内で開かれている典型的なPCB設計ドキュメントについて...
プロジェクトとその対応するドキュメントは、ワークスペースマネージャーAPIとそのオブジェクトモデルによって管理されます。ここで:
-
開かれたプロジェクトは
IProjectオブジェクトインターフェースによって表されます。 -
このプロジェクトのドキュメントは
IDocumentインターフェースによって表されます。
PCBドキュメントとPCB設計オブジェクトは、PCBエディターAPIとそのPCBオブジェクトモデルによって管理されます。ここで:
-
開かれているPCBドキュメントは、その
IPCB_Boardインターフェースによって表されます。 -
設計オブジェクト、例えば、パッドオブジェクトとトラックオブジェクトは、
IPCB_PadおよびIPCB_Trackインターフェースによって表されます。
PCBオブジェクト
PCBオブジェクトモデルにより、スクリプトはPCBオブジェクトとPCBドキュメントにアクセスできます。PCBドキュメントまたはPCBエディターサーバー上のPCBオブジェクトへのゲートウェイは、PCBServer関数です。スクリプトで呼び出されると、PCBServer関数はPCBエディターサーバーを表すIPCB_ServerInterfaceインターフェースを返します。
例として、GetCurrentPCBBoardメソッドは通常、スクリプトで呼び出され、Altium Designer内の現在のPCBドキュメントを表すIPCB_Boardインターフェースを取得するために使用されます。階層を下ると、PCBパッドオブジェクトはIPCB_Padインターフェースによってカプセル化されます。
以下のDelphiScript例では、GetCurrentPCBBoardメソッドが呼び出され、Altium Designer内の現在のPCBドキュメントを表すIPCB_Boardインターフェースを返します。スクリプトはイテレータを使用してPCBドキュメント上の特定のPCB設計オブジェクトを検索します。イテレータは、指定された領域内または指定された層上の指定されたオブジェクトを検索するように設定できますが、この場合はPCBドキュメントの層上のパッドオブジェクトのみが検索されます。
スクリプトを実行する前に、パッドオブジェクトを含むPCBドキュメントが開かれている必要があります。
Procedure PadCount;
Var
Board : IPCB_Board;
Pad : IPCB_Primitive;
Iterator : IPCB_BoardIterator;
PadNumber : Integer;
Begin
PadNumber := 0;
// 現在のボードを取得
Board := PCBServer.GetCurrentPCBBoard;
If Board = Nil Then Exit;
// イテレータを取得
Iterator := Board.BoardIterator_Create;
Iterator.AddFilter_ObjectSet(MkSet(ePadObject));
Iterator.AddFilter_LayerSet(AllLayers);
Iterator.AddFilter_Method(eProcessAll);
// パッドを検索して数える
Pad := Iterator.FirstPCBObject;
While (Pad <> Nil) Do
Begin
Inc(PadNumber);
Pad := Iterator.NextPCBObject;
End;
Board.BoardIterator_Destroy(Iterator);
// 結果をダイアログに表示
ShowMessage('Pad Count = ' + IntToStr(PadNumber));
End;
ユニークなオブジェクトインターフェース
スクリプトでは、同じタイプのすべてのオブジェクトは同じオブジェクトインターフェースを持っているため、例えば、開かれたPCBドキュメント内のすべてのPCBトラックオブジェクトはIPCB_Trackインターフェースによって表されます。
複数のオブジェクトインターフェース(それぞれがPCBトラックを表す)を区別するために、オブジェクトの一意のメモリアドレスまたはハンドルを使用できます。この場合、すべてのPCBオブジェクトアドレスはTPCBObjectHandleタイプ(数値ポインター)によって表され、PCBオブジェクトインターフェースはI_ObjectAddressメソッド(IPCB_Track.I_ObjectAddress : Pointer)を提供します。
同様に、すべてのスキーマティックオブジェクトアドレスはTSchObjectHandleタイプによって表され、スキーマティックインターフェースはFunction I_ObjectAddress : TSCHObjectHandleメソッドを持っています。
スキーマティックオブジェクト
スキーマティックオブジェクトモデルは、スクリプトがスキーマティックオブジェクトおよびスキーマティックドキュメントにアクセスできるようにします。ドキュメント内のスキーマティックオブジェクトまたはスキーマティックエディターサーバーへのゲートウェイは、SchServer関数であり、これはISch_ServerInterfaceインターフェースを返します。このオブジェクトインターフェースはスキーマティックエディターサーバーオブジェクトを取得するため、現在のスキーマティックドキュメントを取得し、スキーマティックオブジェクトからデータを抽出し、スキーマティックオブジェクトのメソッドを呼び出すことができます。
実際のAltium Designer Delphiスクリプトで使用されるスキーマティックオブジェクトインターフェースを調べるには、UsingSpatialIteratorsスクリプトを\Scripts\Delphiscript Scripts\SCHフォルダのScript Examplesコレクションからロードします - このスクリプトはSch_Scriptsプロジェクトの一部です。
実行されると、このスクリプト例は、スキーマティックシート上で境界ボックスを定義する2点をクリックするのを待つメソッドを使用します。空間イテレーターは、シート上で定義された境界内のコンポーネントを検索する検索オブジェクトであり、X、Y座標の観点からその位置を報告します。再び、このスクリプトを実行する前にスキーマティックドキュメントを開いておく必要があります。空間イテレーターはスキーマティックオブジェクトモデルのISch_Iteratorインターフェースによってカプセル化されています。
ワークスペースマネージャーオブジェクト
ワークスペースマネージャーサーバーは、プロジェクトとそれに関連するドキュメントを扱います。このサーバーはプロジェクトおよびマルチシートデザインのサポート、コンパイル、接続ナビゲーションツールなどを提供します。
ワークスペースマネージャーはスキーマティック中心であり、ネットリスターなどの出力ジェネレーターも管理します。ワークスペースマネージャーインターフェースを取得するには、GetWorkspace関数を呼び出します — IWorkspace.GetWorkspace。
実際のAltium Designer Delphiスクリプトで使用されるワークスペースマネージャーオブジェクトインターフェースを調べるには、UsingMessagePanelスクリプトを\Scripts\Delphiscript Scripts\WSMフォルダのScript Examplesコレクションからロードします - このスクリプトはWSM_Scriptsプロジェクトの一部です。
UsingMessagePanelの例は、Altium DesignerのMessages パネルに文字列を挿入する方法を示しています。 Messages パネルは、ワークスペースマネージャーオブジェクトモデルからのIMessagesManagerインターフェース(IWorkspace.DM_MessagesManager)によってカプセル化されています。
クライアントオブジェクト
Altium Designerアプリケーション内のクライアント実行モジュールは、適切なサーバーにコマンドをディスパッチし、ユーザーインターフェースとシステムレベルの機能を処理します。クライアントモジュールインターフェースを取得するには、Client 関数を呼び出します。 Client 関数はIClientインターフェースを取得し、これはクライアント実行モジュールをカプセル化します。
実際のAltium Designer Delphiスクリプトで使用されるクライアントオブジェクトインターフェースを調べるには、OpenADocスクリプトを\Scripts\Delphiscript Scripts\DXPフォルダのScript Examplesコレクションからロードします - このスクリプトはDXP_Scriptsプロジェクトの一部です。
その例では、OpenDocumentShowOrHideメソッドを使用して、指定されたテキストファイルをAltium Designerで開きます(ただし表示はしません)。ここで、OpenDocumentShowOrHideメソッドはIServerDocumentインターフェースを返し、これはAltium Designerでドキュメントを表示するためにShowDocumentDontFocusメソッドのパラメータとして使用されます。
スクリプトを実行する前に、対応するテキストファイルが利用可能であること(例:C:\Report.txt)と、スクリプトがそれに応じて編集されていることを確認してください — コード行15でFileName := 'C:\Report.Txt';。
スクリプトからプロセスを実行する
Altium Designerのクライアントモジュールは、サーバープロセスの観点からコマンドを解釈し、これらのプロセスを適切なサーバーに委任します。コマンドは実行されるアクションを表し、パッケージ化されたプロセスランチャーを介してプロセス文字列によってサポートされます。
プロセスはserver name:server process文字列として実装され、サーバーによって維持されるコマンドランチャーテーブルに格納されます。Altium Designerのグラフィカルユーザーインターフェース(GUI)を介してプロセスが実行されるたびに、それは適切なサーバーのコマンドテーブルを参照してプロセス文字列を取得し、次にこの文字列を正しいサーバーに送信してどのプロセスを実行するかを決定します。サーバーの機能はそのサーバーのプロセスによって公開されます。
例えば、スキーマティックメニューを使用してワイヤーを配置するとき、クライアントはこのアクションを'SCH: PlaceWire'コマンドとして解釈し、コマンドをスキーマティックエディターサーバーに委任します。スキーマティックサーバーは、コマンドを実行することによって応答します。要するに、サーバーはそのプロセスのセットによってサポートされ、これらのプロセスはGUIとこのサーバーとの間のリンクとして機能します。
以下に示す簡単な例では、開かれたスキーマティックドキュメントに新しいスキーマティックポートを配置します。例を試すには、Process_Scriptsプロジェクトを\Scripts\DelphiScript Scripts\ProcessesフォルダのScript Examplesコレクションから開き、次にPlaceSchPort.pasスクリプトを開きます。
Begin
ResetParameters;
AddIntegerParameter('Location.X', 20000000 );
AddIntegerParameter('Location.Y', 20000000 );
AddIntegerParameter('Style' , 2 );
AddIntegerParameter('IOType' , 3 );
AddIntegerParameter('Alignment' , 0 );
AddIntegerParameter('Width' , 10000000 );
AddStringParameter ('Name' , 'Test Port');
AddIntegerParameter('AreaColor' , $FFFFFF );
AddIntegerParameter('TextColor' , $000000 );
RunProcess ('Sch:PlacePort' );
End.
上記のPlaceSchPortスクリプトは、Schematic Serverプロセスを使用します。ResetParametersメソッドが最初に呼び出され、Altium Designerのプロセスバッファをクリアします。サーバープロセスパラメータは、AddIntegerParameterおよびAddStringParameterメソッドを使用して設定され、最終的にRunProcessメソッドでサーバープロセスが呼び出されます。
スクリプト内のDelphiオブジェクト
スクリプトシステムは、スクリプトフォームのための2種類のコンポーネントオブジェクトを扱います:ビジュアルとノンビジュアルコンポーネントです。ビジュアルコンポーネント(例えばButton、Edit、Memoコンポーネント)はユーザーインターフェースの構築に使用され、ノンビジュアルコンポーネントは背後でのさまざまなタスクに使用されます - 例えばTimer、OpenDialog、MainMenuコンポーネントなどです。Timerノンビジュアルコンポーネントは、特定のコードをスケジュールされた間隔でアクティブにするために使用され、これはユーザーには見えません。Altium Designerでは、これらのコンポーネントはDelphi Run Time Libraryから来ています。
すべてのスクリプトフォームには、コントロールとも呼ばれる1つ以上のコンポーネントがあります。任意の組み合わせのコンポーネントをスクリプトフォームに配置でき、スクリプトが実行されている間、ユーザーはフォームの任意のコンポーネントと対話できます。スクリプトコードは、ユーザーがボタンをクリックしたり、Editボックスのテキストを変更したりしたときに何が起こるかを決定します。
フォームコンポーネントの配置
Altium DesignerのTool Paletteパネルは、スクリプトフォームに配置できる利用可能なすべてのコンポーネントを公開します。アクティブなフォームにコンポーネントを配置するには、Tool Paletteパネルのコンポーネントアイコンをダブルクリックします。フォームにコンポーネントが配置されると、スクリプトシステムは自動的にコンポーネントの使用に必要なコードを生成し、スクリプトフォームを更新します。オブジェクトを作成または破棄する必要はありません。スクリプトフォームがこれを自動的に行います。
プロパティを設定し、イベントハンドラーにコードを追加し(Event タブをObject Inspectorパネルで参照)、必要に応じてスクリプトフォーム上のコンポーネントを操作するメソッドを使用します。また、Object Inspectorパネルを使用して、スクリプトフォーム上のコンポーネントのプロパティを簡単に操作することもできます。
フォームコンポーネントの作成
スクリプトでは、コンポーネントを直接作成および破棄できます。通常、スクリプトフォームが自動的に処理するため、フォームのハンドルを渡す必要はありません。したがって、以下に示すように、コンポーネントのコンストラクターにはNilパラメータが渡されます。
Function LoadAFile : String;
Var
OpenDialog : TOpenDialog;
Begin
Result := '';
OpenDialog := TOpenDialog.Create(nil);
OpenDialog.InitialDir := 'C:\';
// OpenDialogコンポーネントを表示
OpenDialog.Execute;
// 選択されたファイルのファイル名を取得
Result := OpenDialog.Filename;
OpenDialog.Free;
End;
DelphiのCreateObject関数もダイアログインスタンスを作成するために使用できることに注意してください。この関数は複数のパラメータを取り、上記の例の場合、TOpenDialogクラスとnilパラメータです。上記で灰色にハイライトされた行は、OpenDialog := CreateObject(TOpenDialog, nil);
に変更されます。
Delphiクラスのインスタンス化TStringListオブジェクトなどの他のDelphiオブジェクトについて、スクリプトの期間中にそれらを作成するためにDelphiランタイムクラスのいくつかが使用されます。これらのクラスは通常、オブジェクトを作成し、オブジェクトに情報を格納し、それらが不要になったときに解放するために使用されます。オブジェクトは適切な場所で作成および解放する必要があります。
TStringListクラスを作成して使用する例:
Procedure Demo_TStringList_Class;
Var
AList : TStringList;
Begin
Try
AList := TStringList.Create;
AList.Add('Line 1');
AList.Add('Line 2');
AList.SaveToFile(FileName);
Finally
AList.Free;
End;
End;