/* maximum.c -- output the maximum of a group of numbers ------- */ // Japanese comments by Masayuki Akamatsu // ヘッダの読み込み #include "ext.h" // 【必須】 // 定数宣言 #define MAXSIZE 256 // オブジェクト構造体(インスタンス変数)の宣言 typedef struct _maximum { struct object m_ob; // インスタンスの基本部分【必須】 t_atom m_args[MAXSIZE]; // 以下は任意 long m_count; short m_incount; short m_outtype; void *m_out; // アウトレットへのポインタ } t_maximum; // グローバル変数(クラス変数)の宣言 void *maximum_class; // オブジェクトクラスへのポインタ【必須】 // 関数プロトタイプ宣言 void maximum_compare(t_atom *max, t_atom *newone); void maximum_bang(t_maximum *x); void maximum_int(t_maximum *x, long n); void maximum_in1(t_maximum *x, long n); void maximum_float(t_maximum *x, double f); void maximum_ft1(t_maximum *x, double f); void maximum_list(t_maximum *x, t_symbol *s, short ac, t_atom *av); void maximum_assist(t_maximum *x, void *b, long m, long a, char *s); void *maximum_new(t_symbol *s, short ac, t_atom *av); // メイン関数【必須】 // Max起動時などオブジェクトファイル読み込み時に呼び出される // クラスとして必要な初期化などの設定を行う void main() { // クラスの設定【必須】 setup((t_messlist **)&maximum_class, (method)maximum_new,0L, (short)sizeof(t_maximum), 0L, A_GIMME, 0); // &maximum_class クラスへのポインタへのポインタ、Maxがクラスを生成する // maximum_new newメッセージ処理関数(オブジェクト生成関数)を指定 // 0L freeメッセージ処理関数(オブジェクト消滅関数)を指定〜ここでは必要ないので指定していない // sizeof(t_maximum) オブジェクト構造体のサイズを指定 // 0L メニュー処理関数を指定〜ここでは使用しないので指定していない // A_GIMME アーギュメントのデータタイプを指定、A_GIMMEは任意のアーギュメントを受け入れる指定 // 0 アーギュメントのデータタイプの指定の終わり // メッセージ処理関数の登録〜対応するメッセージに応じて登録【ほぼ必須】 addbang((method)maximum_bang); addint((method)maximum_int); addinx((method)maximum_in1,1); addfloat((method)maximum_float); addftx((method)maximum_ft1,1); addmess((method)maximum_list,"list",A_GIMME,0); addmess((method)maximum_assist,"assist",A_CANT,0); // オブジェクトリストへの登録 finder_addclass("Arith/Logic/Bitwise","maximum"); // 使用するリソースのコピー rescopy('STR#',3007); } // 特定処理(サブルーチン)関数...という名前があるわけではないが... // 引数のmaxとnewoneを比べてより大きな数値をmaxに代入する void maximum_compare(t_atom *max, t_atom *newone) { if (max->a_type==A_NOTHING) { *max = *newone; return; } if (max->a_type==A_FLOAT) { if (newone->a_type==A_FLOAT) { if (newone->a_w.w_float > max->a_w.w_float) max->a_w.w_float = newone->a_w.w_float; } else { if ((float)newone->a_w.w_long > max->a_w.w_float) max->a_w.w_float = (float)newone->a_w.w_long; } } else { if (newone->a_type==A_LONG) { if (newone->a_w.w_long > max->a_w.w_long) max->a_w.w_long = newone->a_w.w_long; } else { if ((long)newone->a_w.w_float > max->a_w.w_long) max->a_w.w_long = (long)newone->a_w.w_float; } } } // 以下は、メッセージ処理関数【ほぼ必須】 // main()で登録したメッセージ処理関数はすべて必要 // オブジェクトにメッセージが送られた時に対応する関数が呼び出される // bangメッセージ処理関数 // インスタンス変数のt_atom配列m_args、有効要素数m_countから最大値を探して出力する void maximum_bang(t_maximum *x) { short i; t_atom theMax; long res; double fres; theMax.a_type = A_NOTHING; for (i=0; i < x->m_count; i++) maximum_compare(&theMax,x->m_args+i); if (x->m_outtype==A_LONG) { if (theMax.a_type==A_LONG) res = theMax.a_w.w_long; else res = (long)theMax.a_w.w_float; outlet_int(x->m_out,res); // 整数を出力 } else { if (theMax.a_type==A_FLOAT) fres = theMax.a_w.w_float; else fres = (float)theMax.a_w.w_long; outlet_float(x->m_out,fres); // 実数を出力 } } // 整数メッセージ処理関数 void maximum_int(t_maximum *x, long n) { SETLONG(x->m_args,n); maximum_bang(x); } // 第2インレットへの整数メッセージ処理関数 void maximum_in1(t_maximum *x, long n) { SETLONG(x->m_args+1,n); x->m_count = 2; } // 実数メッセージ処理関数 void maximum_float(t_maximum *x, double f) { SETFLOAT(x->m_args,f); maximum_bang(x); } // 第2インレットへの実数メッセージ処理関数 void maximum_ft1(t_maximum *x, double f) { SETFLOAT(x->m_args+1,f); x->m_count = 2; } // リストメッセージ処理関数 void maximum_list(t_maximum *x, t_symbol *s, short ac, t_atom *av) { short i; if (ac > MAXSIZE) ac = MAXSIZE; for (i=0; i < ac; i++,av++) { if (av->a_type==A_LONG) SETLONG(x->m_args+i,av->a_w.w_long); else if (av->a_type==A_FLOAT) SETFLOAT(x->m_args+i,av->a_w.w_float); } x->m_count = ac; maximum_bang(x); } // assistメッセージ処理関数 void maximum_assist(t_maximum *x, void *b, long m, long a, char *s) { // STR#リソースを使ってアシスタンスを表示 assist_string(3007,m,a,1,3,s); } // newメッセージ処理関数【必須】 // オブジェクト生成時に呼び出される // インスタンスとして必要な初期化などの設定を行う void *maximum_new(t_symbol *s, short ac, t_atom *av) { t_maximum *x; // オブジェクト(インスタンス)へのポインタ〜必須 // オブジェクトを生成【必須】 x = (t_maximum *)newobject(maximum_class); x->m_count = 2; if (ac) { // アーギュメントが指定されていれば... x->m_args[1] = *av; if (av->a_type==A_LONG) { // アーギュメントが整数なら... x->m_args[0].a_type = x->m_outtype = A_LONG; x->m_out = intout(x); // 整数のアウトレットを作成 x->m_args[0].a_w.w_long = 0; intin(x,1); // 整数の第2インレットを作成 } else if (av->a_type==A_FLOAT) { // アーギュメントが実数なら... x->m_args[0].a_type = x->m_outtype = A_FLOAT; x->m_out = floatout(x); // 実数のアウトレットを生成 x->m_args[0].a_w.w_float = 0; floatin(x,1); // 実数の第2インレットを作成 } } else { // アーギュメントが指定されていなければ... x->m_outtype = A_LONG; intin(x,1); // 整数の第2インレットを作成 x->m_out = intout(x); // 整数のアウトレットを作成 SETLONG(x->m_args+1,0L); SETLONG(x->m_args,0L); } return x; // 生成したオブジェクトへのポインタを返す【必須】 }