Node For Max ~MaxAPI のインターフェースを見る~

ここ最近 Node For Max ばかりやってますが、少し前の情報を見ると、max-api ライブラリの型情報は提供されていなかったようですね。
TypeScript 好きな私としては、今 @types/max-api が公開されているのはとてもありがたいです。

今回は実装を少し離れて、max-api のインターフェースを見ていこうと思います。


外観

index.d.ts ファイルにいくつかの定義がありますが、今回はEnumとFunctionの一部を取り上げます。

Enum

いわゆる列挙型の定数です。
MESSAGE_TYPES, POST_LEVELS はよくお世話になります。

/** Predefined generic MaxFunctionSelector types */
enum MESSAGE_TYPES {
    /** Generic Type for *all* kinds of messages */
    ALL = "all",
    /** Bang message type */
    BANG = "bang",
    /** Dictionary message type */
    DICT = "dict",
    /** Number message type */
    NUMBER = "number",
    /** List message type */
    LIST = "list"
}

/** Log Levels used in maxAPI.post */
enum POST_LEVELS {
    /** error level messages */
    ERROR = "error",
    /** info level messages */
    INFO = "info",
    /** warn level messages */
    WARN = "warn"
}

どこで使うかというと、
まず、MESSAGE_TYPES はイベントリスナーのアタッチ時に利用します。(イベントリスナーについては後ほど)

MaxAPI.addHandler(MaxAPIStatic.MESSAGE_TYPES.BANG, async (...args: any) => {
    console.log('Receive Bang');
    console.log(args);
});
bangを受け取ってコンソールに出力する例

このように、MESSAGE_TYPES.BANG が 'bang' を表しているので、Bangのイベントに対して反応するイベントリスナーが作られました。
当然、Enum を使わずに以下のように書いても全く同じように動作します。

MaxAPI.addHandler('bang', async (...args: any) => {
    console.log('Receive Bang');
    console.log(args);
});

地味ですが、単純に打ち間違いが減るし、VSCodeなどのエディタを使っていれば予測で候補を出してくれるのでありがたいです。

POST_MESSAGE の方は、コンソールにデータをプリントするときのレベル設定に利用できます。

Function

ここが Node For Max の肝の部分です。
Max のインターフェースに関わるところだけとりあえず解説します。

addHandler

こちらは、node.script のインレットに対して何らかの入力があった場合に、指定されたコールバック関数を実行します。
さっそく例を見て見ましょう。

MaxAPI.addHandler(MaxAPIStatic.MESSAGE_TYPES.BANG, async (...args: any) => {
    MaxAPI.post('Receive Bang', MaxAPIStatic.POST_LEVELS.INFO);
    console.log(args);
});

MaxAPI.addHandler(MaxAPIStatic.MESSAGE_TYPES.NUMBER, async (...args: any) => {
    MaxAPI.post('Receive Number', MaxAPIStatic.POST_LEVELS.INFO);
    console.log(args);
});

MaxAPI.addHandler(MaxAPIStatic.MESSAGE_TYPES.DICT, async (...args: any) => {
    MaxAPI.post('Receive Dict', MaxAPIStatic.POST_LEVELS.INFO);
    console.log(args);
});

MaxAPI.addHandler(MaxAPIStatic.MESSAGE_TYPES.LIST, async (...args: any) => {
    MaxAPI.post('Receive List', MaxAPIStatic.POST_LEVELS.INFO);
    console.log(args);
});

こちらの例では、Bang, Number, List, Dict それぞれの入力を受け付けたときに設定された関数が実行されます。
第一引数では、 どのタイプの入力があったときに実行するかを定義しています(ここでEnum使ってます)。

実行例

コールバックの引数には、入力された値が入ります。
Nodeのコンソールに出力されている値がそれです。

post

続いて、post メソッドです。
こちらは、max consoleに出力するためのメソッドです。
出力する文字列と、表示のレベルを指定できます。
以下実行例です。表示レベルにはEnumの値を使っています。

MaxAPI.addHandler(MaxAPIStatic.MESSAGE_TYPES.BANG, async (...args: any) => {
    MaxAPI.post('bang', MaxAPIStatic.POST_LEVELS.INFO);
    MaxAPI.post('bang', MaxAPIStatic.POST_LEVELS.WARN);
    MaxAPI.post('bang', MaxAPIStatic.POST_LEVELS.ERROR);
});

outlet / outletBang

node.script のアウトレットから、指定した値、もしくは B¥ang を出力します。
Bangを受け取ったら、アウトレットからBangを、Number を受け取ったら、アウトレットからNumberを出力する例

MaxAPI.addHandler(MaxAPIStatic.MESSAGE_TYPES.BANG, async (...args: any) => {
    MaxAPI.outletBang();
});

MaxAPI.addHandler(MaxAPIStatic.MESSAGE_TYPES.NUMBER, async (...args: any) => {
    MaxAPI.outlet(args);
});

おわりに

これだけあれば、とりあえずNodeのプロセスとMaxの連携を十分に取れると思います。
Max - Node 間のI/Fは基本的にJSONの形式でやり取りすることが多そうです。バイナリデータなどの扱いは工夫が必要になりますね。

この記事が気に入ったらサポートをしてみませんか?