今天终于将A_GIMME方法部分的描述看懂了,上周因为太赶时间加上这文档很抽象一直没看懂。也就那么一回事,记录一下。
A_GIMME方法用于接收多个参数:
#include "ext.h" // standard Max include, always required
#include "ext_obex.h" // required for new style Max object
typedef struct _gimme {
t_object ob; // the object itself (must be first)
/* 自定义属性 */
} t_gimme;
void* gimme_new(t_symbol* s, long argc, t_atom* argv);
void gimme_free(t_gimme* x);
void gimme_assist(t_gimme* x, void* b, long m, long a, char* s);
// 自定义函数
void gimme_printArgs(t_gimme* x, t_symbol* s, long argc, t_atom* argv);
void* gimme_class;
void ext_main(void* r) {
t_class* c;
// "gimme" 建议和项目名一样,否则在max/msp中创建自定义组件会出问题
c = class_new("gimme", (method)gimme_new, (method)gimme_free, (long)sizeof(t_gimme),
0L /* leave NULL!! */, A_GIMME, 0);
/* you CAN'T call this from the patcher */
class_addmethod(c, (method)gimme_assist, "assist", A_CANT, 0);
// 注意:这里的"gimme"为自定义的消息选择器,会被加入消息选择器表中;而"anything"为消息选择器表内置
// 自定义消息选择器
class_addmethod(c, (method)gimme_printArgs, "gimme", A_GIMME, 0);
class_register(CLASS_BOX, c); /* CLASS_NOBOX */
gimme_class = c;
post("I am the gimme object");
}
void gimme_assist(t_gimme* 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 gimme_free(t_gimme* x) {
;
}
/* argc指在创建组件时,直接跟在组件后面的参数个数;argv存储参数具体值*/
void* gimme_new(t_symbol* s, long argc, t_atom* argv) {
t_gimme* x = NULL;
long i;
x = (t_gimme*)object_alloc(gimme_class);
return (x);
}
// 接收多个参数,并打印所有参数
void gimme_printArgs(t_gimme* x, t_symbol* s, long argc, t_atom* argv) {
long i;
t_atom* ap = argv;
for (int i = 0; i < argc; i++) {
switch (atom_gettype(ap)) {
case A_LONG:
post("arg %ld: %ld", i, atom_getlong(ap));
break;
case A_FLOAT:
post("arg %ld: %lf", i, atom_getfloat(ap));
break;
case A_SYM:
post("arg %ld: %s", i, atom_getsym(ap)->s_name);
break;
default:
post("%ld, unknown atom type: %ld", i, atom_gettype(ap));
break;
}
ap++;
}
}
运行结果: