Max 5 API Reference
00001 #include "ext.h" 00002 #include "ext_common.h" 00003 #include "ext_expr.h" 00004 #include "ext_obex.h" //for atom routines 00005 00006 void *vexpr_class; 00007 00008 #define MAXLIST 4096 00009 00010 typedef struct vexpr 00011 { 00012 t_object v_ob; 00013 t_expr *v_expr; 00014 void **v_proxy; 00015 void *v_outlet; 00016 long v_inReceive; 00017 t_atom *v_argv[10]; 00018 short v_argc[10]; 00019 short v_numargs; 00020 char v_scalarmode; 00021 } t_vexpr; 00022 00023 int main(void); 00024 void vexpr_bang (t_vexpr *x); 00025 void vexpr_scalarbang(t_vexpr *x); 00026 void vexpr_vectorbang(t_vexpr *x); 00027 void vexpr_int (t_vexpr *x, long n); 00028 void vexpr_float (t_vexpr *x, double f); 00029 void vexpr_list (t_vexpr *x, t_symbol *s, short ac, t_atom *av); 00030 void vexpr_scalarmode(t_vexpr *x, long n); 00031 void vexpr_assist(t_vexpr *x, void *b, long m, long a, char *s); 00032 void vexpr_inletinfo(t_vexpr *x, void *b, long a, char *t); 00033 void vexpr_free (t_vexpr *x); 00034 void *vexpr_new (t_symbol *s, short ac, t_atom *av); 00035 00036 00037 int main(void) 00038 { 00039 t_class *c; 00040 00041 c = class_new("vexpr",(method)vexpr_new,(method)vexpr_free,(long)sizeof(t_vexpr),0L,A_GIMME, 0); 00042 class_addmethod(c, (method)vexpr_bang, "bang", 0); 00043 class_addmethod(c, (method)vexpr_int, "int", A_LONG, 0); 00044 class_addmethod(c, (method)vexpr_float, "float", A_FLOAT, 0); 00045 class_addmethod(c, (method)vexpr_list, "list", A_GIMME,0); 00046 class_addmethod(c, (method)vexpr_assist, "assist", A_CANT,0); 00047 class_addmethod(c, (method)vexpr_inletinfo, "inletinfo", A_CANT, 0); 00048 00049 CLASS_ATTR_CHAR(c, "scalarmode", 0, t_vexpr, v_scalarmode); 00050 CLASS_ATTR_STYLE_LABEL(c, "scalarmode", 0, "onoff", "Scalar Mode"); 00051 00052 class_register(CLASS_BOX, c); 00053 vexpr_class = c; 00054 00055 return 0; 00056 } 00057 00058 void vexpr_bang(t_vexpr *x) 00059 { 00060 if (x->v_scalarmode) 00061 vexpr_scalarbang(x); 00062 else 00063 vexpr_vectorbang(x); 00064 } 00065 00066 void vexpr_scalarbang(t_vexpr *x) 00067 { 00068 long i,j,count,index; 00069 t_atom result[MAXLIST],input[10]; 00070 short scalar[10]; 00071 Boolean hadscalar = false; 00072 00073 count = MAXLIST+1; // count should be higher than the limit 00074 for (i=0; i <= x->v_numargs; i++) { 00075 scalar[i] = x->v_argc[i] == 1; 00076 if (scalar[i]) 00077 hadscalar = true; 00078 else 00079 count = MIN(x->v_argc[i],count); 00080 } 00081 if (count == (MAXLIST+1)) { 00082 if (hadscalar) 00083 count = 1; 00084 else 00085 return; 00086 } 00087 if (count > MAXLIST) 00088 count = MAXLIST; 00089 00090 for (i=0; i < count; i++) { 00091 for (j = 0; j <= x->v_numargs; j++) { 00092 index = scalar[j]? 0 : i; 00093 input[j] = *(x->v_argv[j]+index); 00094 } 00095 expr_eval(x->v_expr,x->v_numargs+1,input,result+i); 00096 } 00097 if (count > 1) 00098 outlet_list(x->v_outlet,0L,count,result); 00099 else { 00100 if (result[0].a_type == A_LONG) 00101 outlet_int(x->v_outlet,result[0].a_w.w_long); 00102 else if (result[0].a_type == A_FLOAT) 00103 outlet_float(x->v_outlet,result[0].a_w.w_float); 00104 } 00105 } 00106 00107 void vexpr_vectorbang(t_vexpr *x) 00108 { 00109 long i,j,count; 00110 t_atom result[MAXLIST],input[10]; 00111 00112 count = MAXLIST+1; // count should be higher than the limit 00113 for (i=0; i <= x->v_numargs; i++) 00114 count = MIN(x->v_argc[i],count); 00115 if (count == (MAXLIST+1)) 00116 return; 00117 if (count > MAXLIST) 00118 count = MAXLIST; 00119 00120 for (i=0; i < count; i++) { 00121 for (j = 0; j <= x->v_numargs; j++) 00122 input[j] = *(x->v_argv[j]+i); 00123 expr_eval(x->v_expr,x->v_numargs+1,input,result+i); 00124 } 00125 if (count > 1) 00126 outlet_list(x->v_outlet,0L,count,result); 00127 else if (count == 1) 00128 { 00129 if (result[0].a_type == A_LONG) 00130 outlet_int(x->v_outlet,result[0].a_w.w_long); 00131 else if (result[0].a_type == A_FLOAT) 00132 outlet_float(x->v_outlet,result[0].a_w.w_float); 00133 } 00134 } 00135 00136 void vexpr_int(t_vexpr *x, long number) 00137 { 00138 long i; 00139 00140 i = proxy_getinlet((t_object *)x); 00141 x->v_argc[i] = 1; 00142 if (x->v_expr->exp_var[i].ex_type==ET_FI) 00143 SETFLOAT(x->v_argv[i],(float)number); 00144 else 00145 SETLONG(x->v_argv[i],number); 00146 if (!i) 00147 vexpr_bang(x); 00148 } 00149 00150 void vexpr_float(t_vexpr *x, double number) 00151 { 00152 long i; 00153 00154 i = proxy_getinlet((t_object *)x); 00155 x->v_argc[i] = 1; 00156 if (x->v_expr->exp_var[i].ex_type==ET_II) 00157 SETLONG(x->v_argv[i],(long)number); 00158 else 00159 SETFLOAT(x->v_argv[i],number); 00160 if (!i) 00161 vexpr_bang(x); 00162 } 00163 00164 void vexpr_list(t_vexpr *x, t_symbol *s, short argc, t_atom *argv) 00165 { 00166 long i,j; 00167 00168 i = proxy_getinlet((t_object *)x); 00169 if (argc > MAXLIST) 00170 argc = MAXLIST; 00171 x->v_argc[i] = argc; 00172 00173 switch (x->v_expr->exp_var[i].ex_type) { 00174 case ET_II: 00175 for (j=0;j<argc;j++) 00176 SETLONG((x->v_argv[i])+j,atom_getlong(argv+j)); 00177 break; 00178 case ET_FI: 00179 for (j=0;j<argc;j++) 00180 SETFLOAT((x->v_argv[i])+j,atom_getfloat(argv+j)); 00181 break; 00182 default: 00183 sysmem_copyptr(argv,x->v_argv[i],argc * sizeof(t_atom)); 00184 } 00185 if (!i) 00186 vexpr_bang(x); 00187 } 00188 00189 void vexpr_inletinfo(t_vexpr *x, void *b, long a, char *t) 00190 { 00191 if (a) 00192 *t = 1; 00193 } 00194 00195 void vexpr_assist(t_vexpr *x, void *b, long m, long a, char *s) 00196 { 00197 if (m == ASSIST_INLET) 00198 if (a) 00199 sprintf(s,"int $i%ld, float $f%ld, table $s%ld", a+1, a+1, a+1); 00200 else 00201 sprintf(s,"Evaluate Expression, int $i1, float $f1, table $s1"); // leftmost inlet 00202 else 00203 sprintf(s,"Expression Result"); 00204 } 00205 00206 void vexpr_free(t_vexpr *x) 00207 { 00208 long i; 00209 00210 if (x->v_proxy) { 00211 for (i=0; i < x->v_numargs; i++) { 00212 if (x->v_proxy[i]) 00213 freeobject(x->v_proxy[i]); 00214 } 00215 freebytes(x->v_proxy,x->v_numargs * sizeof(void *)); 00216 } 00217 if (x->v_expr) 00218 freeobject((t_object *)x->v_expr); 00219 for (i=0; i < 10; i++) 00220 sysmem_freeptr(x->v_argv[i]); 00221 } 00222 00223 void *vexpr_new(t_symbol *s, short argc, t_atom *argv) 00224 { 00225 t_vexpr *x; 00226 t_atom result[10]; 00227 long i; 00228 long attroffset = attr_args_offset(argc, argv); 00229 00230 x = (t_vexpr *)object_alloc(vexpr_class); 00231 x->v_outlet = outlet_new(x,0L); 00232 x->v_proxy = 0; 00233 x->v_numargs = 0; 00234 x->v_scalarmode = 0; 00235 x->v_inReceive = 0; 00236 00237 for (i=0; i < 10; i++) { 00238 x->v_argv[i] = (t_atom *)sysmem_newptr(MAXLIST * sizeof(t_atom)); 00239 x->v_argc[i] = 0; 00240 } 00241 x->v_expr = expr_new(attroffset,argv,result); 00242 if (x->v_expr) { /* create an orphan object */ 00243 for (i=8; i >= 1; i--) { 00244 if (result[i].a_type) { 00245 if (!x->v_proxy) { 00246 x->v_proxy = (void **)getbytes(i * sizeof(void *)); 00247 x->v_numargs = i; 00248 } 00249 x->v_proxy[i-1] = proxy_new((Object *)x,(long)i,&x->v_inReceive); 00250 } else if (i < x->v_numargs) { 00251 x->v_proxy[i-1] = NULL; 00252 } 00253 } 00254 attr_args_process(x, argc, argv); 00255 } 00256 else { 00257 // rbs -- failed to create expr, we should be bogus. 00258 freeobject((t_object *)x); 00259 x = NULL; 00260 } 00261 return (x); 00262 } 00263
Copyright © 2008, Cycling '74