====================================== SequenceEditorファサード作成入門 ====================================== :著者: 稲村 泰弘 空蟬の基本コマンド実行環境である **SequenceEditor** で実行されるコマンドは *facade* (ファサード)関数と呼ばれる。これは若干の決まりごとがあるが自由に作成が可能である。ここではその具体的な作成方法と、**SequenceEditor** への反映方法を示す。 Facade(ファサード)関数について ================================== SequenceEditorは、指定されたファイルに書かれている関数を読み込んで、コマンドとしてGUI上でツリー上に表示する。一つのファイルはグループを意味し、複数のファイルを読み込んでグループごとに関数(コマンド)を配置する。関数は決められた形で書かれないと正しくコマンドとして機能・登録されない。この「決められた形で書かれた関数」をファサード関数と呼ぶ。また複数のファサード関数が含まれているファイルをファサード関数ファイルと呼ぶ。 ----------------------------- ファサード関数の利点と活用 ----------------------------- ファサード関数自体は、ごく普通のPythonの関数である。単に引数に必ずデフォルト値を指定することや、コメント行に特有の書き方を行っているだけであり、 **コマンドラインから普通に実行が可能なものである** 。つまり一度ファサード関数を作成すれば、GUI上(SequenceEditor)からもコマンドラインからも同じコマンドが同じパラメータで実行できる。 Manyoライブラリや空蟬の基本関数は、比較的プリミティブなものや共通化されすぎて不要なパラメータが必要なものも多い。よって実際にユーザーに提供する・ユーザーが使用するコマンドは、その装置ごとに最適化されたほうが良いと考えている。すなわち装置責任者は **実際にユーザーに触れさせる** コマンドを装置ごとにファサード関数として用意しておくべきだし、ユーザーは自分好みのファサードを作成することも考えて良い。 --------------------------------------------- 空蟬環境におけるファサード関数ファイル --------------------------------------------- 前章でも示したが、ファサード関数が書かれているファイルは決められた場所に納められている。これらに空蟬環境でデフォルトで使用するファサード関数が書かれたファイルが保管されているので、参考にしてほしい。 +---------------------------------------+--------------------------------------+ |フォルダ |内容 | +=======================================+======================================+ |/opt/mlfsoft/python-utsusemi/facade |空蟬の共通ファサード(Comなど) | +---------------------------------------+--------------------------------------+ |/opt/mlfsoft/python-utsusemi/XXX/facade|装置XXX固有のファサード(DR, Cmmなど)| +---------------------------------------+--------------------------------------+ なお、 */opt/mlfsoft/python-utsusemi* はいわゆる空蟬ルートディレクトリであり、環境変数 *UTSUSEMI_BASE_DIR* にて指定されている場所である。従ってインストールされた環境によって異なる可能性もある。 一方で、ユーザーが独自にファサード関数とファイルを作成し、SequenceEditorへ登録して利用することも可能である。このやり方は後述する。 ---------------------------- ファサード関数ファイルの例 ---------------------------- まず、ファサード関数ファイルの例を見てもらう。このファイル内にはHelloFacadeという名前のファサード関数(引数に *your_name* と *my_name* を受け取り、挨拶をするもの)と、DumpElementContainerという名前のファサード関数(引数にElementContainerを受け取り、そのDumpを表示する)が含まれている。 例: *PrivateFacade.py* .. code-block:: python :linenos: # -*- coding: utf-8 -*- ############################# ## Facade function sample ############################# # special reserved word for commands history HISTORY = None # reserved words for return value in this. DAT = None import Manyo import Manyo.Utsusemi as mu ######################################## def HelloFacade( your_name="Unknown", my_name="Utsusemi" ): """ Hello Facade @param your_name (string) your name to say hello. @param my_name (string) my name @retval DAT """ moji = "Hello, %s ! My name is %s"%(your_name, my_name) print moji return moji ######################################## def DumpElementContainer( ec=None ): """ DumpElementContainer @param ec [Def:EC] (ElementContainer) @retval None """ if isinstance(ec,Manyo.ElementContainer): print "This argument is not ElementContainer" return ec.Dump() ######################################## # Dictionary for entry the name of functions _functions = { "HelloFacade":HelloFacade, "DumpElementContainer":DumpElementContainer } _functionsOrder = ["HelloFacade", "DumpElementContainer" ] 8行目まではコメント行とSequencerに必要なHISTORYの定義。11行目は、空(None)の予約変数名である。 ファサード関数ファイルの構造としては主に 1. ファサード関数本体( *def HelloFacade* と *def DumpElementContainer* ) 2. SequenceEditorへのコマンド登録部分( *_functions* ) 3. SequenceEditorでのコマンドの順番指定部分( *_functionsOrder* ) から構成される。 ファサード関数ファイルの名前について --------------------------------------- ファサードファイルは通常のPythonコードと変わらないので、*Hogehoge.py* という.py拡張子をつけておけば良い。Hogehoge部分は、SequencerEditor上でのコマンドグループの名前となる。ただしこのコマンドグループの名前は固有のものをつける必要がある。よって、個人でファサードを作成する場合は、自分の名前を含むなどして、他の作者によるファサード関数ファイルの名前とかぶらないように注意すること。 ファサード関数本体について ----------------------------- ファサード関数本体は通常のPythonの関数として記述する。ただ引数の与え方と戻り値に特有のルールがある。以下にそれらルールを示す。 ^^^^^^^^^^^^^^^^^^^^^^ 引数に関するルール ^^^^^^^^^^^^^^^^^^^^^^ - 必ず **デフォルト値を与える** こと。これはSequenceEditor上で表示のデフォルト値として用いられるだけでなく、パラメータの型の確認にも用いられるため、正しい型を指定すること。 - そのためもあり、できるだけコメント行で引数の情報を記述すること。 コメント行の例: .. code-block:: python """ Hello Facade @param your_name (string) your name to say hello. @param my_name (string) my name @retval DAT """ - ElementContainerやリストなどのオブジェクトを引数として用いる場合、Noneを指定するか、Noneの予約変数名をつけておく(11行目や31行目) - オブジェクトの引数のデフォルト値にNoneを指定している場合 - SequenceEditor上でオブジェクトの名前が空になることに注意。。 - ただし指定する方法がある。コメント行内のパラメータで *[Def:XXX]* の形で指定できる。XXXがオブジェクトの名前である。 .. code-block:: python """ (中略) @param ec [Def:EC] (ElementContainer) """ ここでは、引数 **ec** に与えるオブジェクト名のデフォルト名を **EC** としている。 ^^^^^^^^^^^^^^^^^^^^^^ 戻り値に関するルール ^^^^^^^^^^^^^^^^^^^^^^ 戻り値に関してのルールとして最重要なのは、 **必ずコメント文の中に戻り値の情報を記述しておかねばならない** ことである。 コメント文の中で *@retval* を用いて指定する。 戻り値がある場合、 .. code-block:: python """ (中略) @retval DAT """ のように戻り値を明記する。ただしこの戻り値の名前は、 **必ず最初の方で指定した予約変数名を用いること** 。 また、ここで与えた名前がSequenceEditorの *Return Label* に入る。 一方、戻り値がない場合は .. code-block:: python """ (中略) @retval None """ と記述しておく。 コマンド登録部分 ---------------------------- ファサード関数をSequenceEditorにコマンドとして認識させるために、ファサード関数ファイルの末尾に *_functions* という名前の一つディクショナリを記述する。 .. code-block:: python _functions = { "HelloFacade":HelloFacade, "DumpElementContainer":DumpElementContainer } 名前は必ず *_functions* であること。またその内容としては .. "コマンド名":ファサード関数名 とすること。通常はコマンド名=ファサード関数名でよい。 コマンドの順番指定部分 ----------------------------------------- SequenceEditor上でこのファサードファイル内のコマンドが1つのグループとして並ぶが、そのグループ同士の順番を指定することができる。順番はリストで与えるが、その名前は *_functionOrder* である必要がある。 .. code-block:: python _functionsOrder = ["HelloFacade", "DumpElementContainer" ] *_functions* (登録ファサードコマンド)で指定したファサードコマンド名を、表示したい順番でリストに登録する。この *_functionsOrder* リストがない場合は順序不定で並ぶ(ディクショナリーのキーの取り出し順)。 ファサード関数ファイルを認識させるには ======================================= ファサード関数ファイルはコマンドグループごとに複数作成が可能である。またその名前はコマンドグループ名として扱われる。これらのファサード関数ファイルをSequenceEditorに認識させるために、ファサード指定ファイル( *Sequencer_facades.py* など)にそのコマンどグループ名を記述する必要がある。 ファサード関数ファイルおよびファサード指定ファイルの置き場所は以下のとおり。 +------------------+----------------------+--------------------------------+------------------------+ |空蟬基本ファサード|Com, VisualModulesなど|python-utsusemi/facade |ファサードファイルのみ | +------------------+----------------------+--------------------------------+------------------------+ |装置専用ファサード|DR, Cmmなど |python-utsusemi/XXX/facade |ファサードファイルおよび| | | | |ファサード指定ファイル | +------------------+----------------------+--------------------------------+------------------------+ |個人用ファサード |(任意) |${UTSUSEMI_USR_PRIV_HOME}/facade|ファサードファイルおよび| | | |(通常は /home/hogehoge/facade)|ファサード指定ファイル | +------------------+----------------------+--------------------------------+------------------------+ 空蟬実行環境では、これらの場所は環境変数 *PYTHONPATH* に指定されている場所である。 これらの設定を行うことで、SequenceEditor起動時に自動的に読み込まれ、コマンド化される。 個人用のファサードを作成する場合には、ホームフォルダの直下にfacadeというフォルダを作成し、ファサードファイルと指定ファイルの両方を入れておけば認識される。 ------------------------------- ファサード指定ファイルについて ------------------------------- 名前は、 *Sequencer_facades.py* が基本であるが、SequenceEditorは *Sequencer_faXXXXXX.py* (XXXXXX部分は任意)を自動的に探す。したがって、XXXXXX部分が異なる複数のファイルがあっても全て読み込まれる。 ファサード指定ファイルの内容(フォーマット)は以下のとおり。 例: .. code-block:: python __AnaFacades__ = ["DR","Cmm","Com"] __VisFacades__ = ["D1Plotter"] つまり *__AnaFacades__* と *__VisFacades__* のマクロ変数を指定するだけである。 *__AnaFacades__* は、データ処理用モジュール名をリストで並べる。この場合、 *DR.py* 、 *Cmm.py* 、*Com.py* のファサードファイルを読み込むことになる。同様に、Visualization用のファサードも指定することができる。不要な場合でも空のリストの指定を行うこと。 .. code-block:: python __AnaFacades__ = ["DR","Cmm"] __VisFacades__ = [] 個人ファサードの組み込み例 ============================== では先ほど示したファサードを実際に組み込んでみよう。 1. ホームディレクトリにfacadeフォルダを作成 2. 個人ファサードファイルの作成 3. ファサード指定ファイルの作成 :: $ cd $ mkdir -p facade $ cd facade $ gedit PrivateFacades.py (先ほどのファサードファイルを記述) $ gedit Sequencer_facades_private.py __AnaFacades__ = ["PrivateFacades"] __VisFacades__ = [] を記述 $ cd $ Ana 実際にSequenceEditorを起動すると、コマンド欄に、別のPrivateFacadesというグループができ、その中に二つのファサード関数が見えているはずである。 まとめ ========== 以上、述べてきたように、 1. ファサード関数を書く 2. ファサード関数ファイルの形を作る( *_functions* ディクショナリと *_functionsOrder* リストの指定) 3. ファサード指定ファイルの作成 4. 以上のファイルをfacade以下に置く という、これらの作業により、自分自身のファサードを作成できる。どんどん利用していただきたい。