最近 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;