今天终于把Message消息选择器看得有点头绪了,主要是这个官方英文文档理解起来有点抽象。
编写IsMatchABC自定义Object,要求:
①若左入口(入口0)收到 "int" 型消息,则从出口发送数值 "888";
②若左入口(入口0)收到 "ABC" 消息,则从出口发送 "Message match!!!(Send)";
③若右入口(入口1)收到 "int" 型消息,则打印该int数值;
- #include "ext.h" // standard Max include, always required
- #include "ext_obex.h" // required for new style Max object
-
- typedef struct _IsMatchABC {
- t_object ob; // the object itself (must be first)
- // 可把t_symbol看成字符串类型
- t_symbol* messagePrintSymbol; // 若消息选择器匹配,则打印messagePrintSymbol
- t_symbol* messageSendSymbol; // 若消息选择器匹配,则从出口发送messageSendSymbol
- t_atom messageSendInt; // 若消息选择器匹配,则从出口发送messageSendInt
- // t_atom类型可存储整型、浮点型、t_symbol类型、指针
- void* outLet;
- } t_IsMatchABC;
-
- // function prototypes
- // 必备函数
- void* IsMatchABC_new(t_symbol* s, long argc, t_atom* argv);
- void IsMatchABC_free(t_IsMatchABC* x);
- void IsMatchABC_assist(t_IsMatchABC* x, void* b, long m, long a, char* s);
- // 自定义函数
- void IsMatchABC_testMessageSelector(t_IsMatchABC* x);
- void handleInt(t_IsMatchABC* x);
- void handleIn1(t_IsMatchABC* x, long n);
-
- // global class pointer variable
- void* IsMatchABC_class;
-
- void ext_main(void* r) {
- t_class* c;
-
- // "IsMatchABC" 建议和项目名一样,否则在max/msp中创建自定义组件会出问题
- c = class_new("IsMatchABC", (method)IsMatchABC_new, (method)IsMatchABC_free, (long)sizeof(t_IsMatchABC),
- 0L /* leave NULL!! */, A_GIMME, 0);
-
- /* you CAN'T call this from the patcher */
- class_addmethod(c, (method)IsMatchABC_assist, "assist", A_CANT, 0);
- // 收到"ABC"消息,则调用IsMatchABC_testMessageSelector方法
- class_addmethod(c, (method)IsMatchABC_testMessageSelector, "ABC", 0);
- class_addmethod(c, (method)handleInt, "int", A_LONG, 0);
- class_addmethod(c, (method)handleIn1, "in1", A_LONG, 0);
-
- class_register(CLASS_BOX, c); /* CLASS_NOBOX */
- IsMatchABC_class = c;
-
- post("I am the IsMatchABC object");
- }
-
- void IsMatchABC_assist(t_IsMatchABC* x, void* b, long m, long a, char* s) {
- if (m == ASSIST_INLET) { // inlet
- sprintf(s, "I am inlet %ld", a);
- } else { // outlet
- sprintf(s, "I am outlet %ld", a);
- }
- }
-
- void IsMatchABC_free(t_IsMatchABC* x) {
- ;
- }
-
- /* argc指在创建组件时,直接跟在组件后面的参数个数;argv存储参数具体值 */
- void* IsMatchABC_new(t_symbol* s, long argc, t_atom* argv) {
- t_IsMatchABC* x = NULL;
- long i;
-
- if ((x = (t_IsMatchABC*)object_alloc(IsMatchABC_class))) {
- intin(x, 1); // 创建入口1(入口0默认存在)
- x->outLet = outlet_new(x, NULL); // 创建通用出口
-
- // t_symbol型数据得使用gensym函数进行赋值,返回t_symbol型指针
- x->messagePrintSymbol = gensym("Message match!!!(Print)");
- x->messageSendSymbol = gensym("Message match!!!(Send)");
-
- atom_setlong(&(x->messageSendInt), 888);
- }
- return (x);
- }
-
- // 入口0收到"ABC"消息,则调用IsMatchABC_testMessageSelector方法
- void IsMatchABC_testMessageSelector(t_IsMatchABC* x) {
- post("%s", x->messagePrintSymbol->s_name);
- outlet_anything(x->outLet, gensym(x->messageSendSymbol->s_name), 0, 0);
- }
-
- // 入口0收到int型消息,则发送"888"
- void handleInt(t_IsMatchABC* x) {
- outlet_anything(x->outLet, gensym("int"), 1, &(x->messageSendInt));
- }
-
- // 入口1收到int型消息,则发送收到的int数值
- void handleIn1(t_IsMatchABC* x, long n) {
- t_atom t_int;
- atom_setlong(&t_int, n);
- outlet_anything(x->outLet, gensym("int"), 1, &t_int);
- }
运行结果:




补充:outlet_anything的使用。
- // outlet_anything发送bang消息
- outlet_anything(myOutlet, gensym("bang"), 0, NIL);
-
- // outlet_anything发送整型数据
- t_atom myNumber;
- atom_setlong(&myNumber, 432);
- outlet_anything(myOutlet, gensym("int"), 1, &myNumber);