最近 Max というビジュアルプログラミング言語を学んでいる。js / jsui オブジェクトというのがあり、その中で JavaScript が書ける、ということでドキュメントを読んでいる。
正直流行っていない言語なので情報が少なく、とにかく公式ドキュメントを読むしかないのである。
読んだドキュメントを備忘録的にエントリーしておく。その第1弾。
注意事項
- JavaScriptファイルを更新した場合、MAXパッチを開き直さないと変更が反映されない
Arguments
js オブジェクトに渡した引数は JavaScript 内では jsarguments[] 配列で参照できる。
- jsarguments[0] => ファイル名 (required)
- jsarguments[1] 以降 => その他の引数 (optional)
ということになる。
Test Code
function bang() {
post(jsarguments[0], jsarguments[1], jsarguments[2], jsarguments[3]);
}
How Input to the js Object is Handled
js オブジェクトの inlet に foo 1 2 3 というメッセージを送った場合、グローバルスコープの foo() 関数を引数 1,2,3 と共に実行するということになる。
Test Code
function foo(a, b, c) {
post(a, b, c);
}
なお、グローバルスコープは jsthis オブジェクト(ブラウザ JavaScript でいう
window オブジェクト)とドキュメントには書いてあるが、jsthisオブジェクトを呼び
出そうとしてもMAXウィンドウに Javascript ReferenceErrod: jsthis is not defined と出て怒られる。なんだこれは。
一方、一般的な this オブジェクトは機能している。
function foo() { }
post(this.foo === foo); // 1 (true)
Special Function Names
msg_int, msg_float
inlet に int が入力されると msg_int() が呼ばれる。inlet に float が入力されると msg_float() が呼ばれる。msg_float() が未定義の場合、 msg_int() が代用で呼ばれるが、少数点以下は切り飛ばされる。
なお msg_float() は少数点第3位以下を受け取ることができない。
Test Code 1
function msg_int(a) { // a == 1
post(a); // 1
}
Test Code 2
function msg_int(a) { // a == 1
post(a); // 1
}
function msg_float(a) { // a == 1.23456
post(a); // 1.23
}
list
inlet に最初の値が int もしくは float の list が入力されると list() が呼ばれる。
上記の例のように最初の値が String の list はその String 名の関数が呼ばれる。
Test Code 1
function list(a, b, c) { // a == 1, b == 2, c == hoge
post(a, b, c); // 1 2 hoge
post(arguments.length); // 3
}
anything
inlet に入力されたものに該当する function が定義されていなかった場合、anything() で受け取ることができる。例えば int が入力されたときに msg_int() が未定義だったら anything() が呼ばれる。float や list でも同様。
anything() 内部では messagename と inlet 変数が定義されており、それぞれ inlet に入ったメッセージの種類と、inlet 番号を参照できる。
Test Code 1
function anything(a, b, c) { // a == 1, b == 2, c == hoge
post("messagename", messagename); // messagename list
post("inlet", inlet); // inlet 0
post("anything", a, b, c); // anything 1 2 hoge
}
loadbang
loadbang() はパッチ起動時に呼ばれる。js オブジェクトや jsui オブジェクトを追加した時ではなく、あくまでそれを予め含むパッチ起動時に呼ばれることに注意。
Cmd+Shiftを押しながらパッチを起動すると loadbang を無効化できるが、無効になっているかどうかは max.loadbangdisabled プロパティに 1 が入っているかどうかで分かる。
Test Code 1
function loadbang() {
if (max.loadbangdisabled == 1) {
post("no loadbang");
} else {
post("loadbang!");
}
}
function bang() {
post("bang!");
}
getvalueof
JavaScript 内で定義した変数の値(String か Number)を pattr 関連オブジェクトから呼び出せるようにする関数。
→ pattr オブジェクトのことがよく分からないので、テストコードが書けない。後で復習する。
setvalueof
pattr 関連オブジェクトから JavaScript 内に変数(Number か String)をパスできるインターフェースを提供する関数。
value が複数の場合、jsthis オブジェクトの arrayfromargs() メソッドで引数を扱うと良いとのこと。
→ pattr オブジェクトのことがよく分からないので、テストコードが書けない。後で復習する。
save
save() を定義すると、JavaScript 内の状態をパッチに保持することができる。
パッチが再読み込みされると、JavaScript 内の状態が復元される。
save() 内だけで使える embedmessage() を使い、値を保存する。
-
embedmessage()の第1引数には保存された値を渡したいコールバック関数名を文字列で渡す -
embedmessage()の第2引数以降には保存したい値を渡し、これがコールバック関数の引数に渡される
Test Code 1
var valuetosave = 0;
function foo(v) {
valuetosave = v;
}
function save() {
embedmessage("callback", valuetosave);
}
function callback(v) {
valuetosave = v;
post(v);
}
notifydeleted
js オブジェクトが削除されたときに呼ばれる
Test Code 1
function notifydeleted() {
post('js object was deleted.');
}
Global Code
グローバルスコープに書かれたコードは編集された後、スクリプトがロードされるかコンパイルされたタイミングで評価される。
js / jsui オブジェクトが完全に作られる前に評価される。
js オブジェクトがいくつ inlet / outlet を持つかはグローバルコードからは分からない。これはグローバルコードから inlet / outlet をいくつにするか定義できることを意味する。しかし言い換えれば、まだ outlet が存在しなければ、使うことはできない。
初期化処理を書きたい場合は loadbang() の中に書くべし。
グローバルコードでやるべきこと
- inlet / outlet の数を定義する
-
jsarguments[]プロパティ(jsオブジェクトの引数)にアクセスする - inlet / outlet の値の操作
- グローバル変数の定義と初期化
- グローバルアプリケーション環境にアクセス&操作するため、Max オブジェクトを使う
グローバルコードでやるべきでないこと
- outlet から何か出力すること
-
jsオブジェクトが置かれたパッチ側を参照しようとすること
Private (Local) Function
js オブジェクトへの inlet メッセージから参照されたくないローカル関数を作りたい場合、local プロパティに 1 をセットする。
Test Code 1
function foo() {
post("Welcome to 'foo' method!");
}
foo.local = 1;











