Max 5 API Reference
00001 /** 00002 @file 00003 match - triggering based on sequential input 00004 00005 updated 3/22/09 ajm: new API 00006 00007 @ingroup examples 00008 */ 00009 00010 #include "ext.h" 00011 #include "ext_obex.h" 00012 #include "ext_critical.h" 00013 00014 #define ANYONE MAGIC 00015 #define NOVALUE 0x80000000 00016 00017 typedef struct match 00018 { 00019 t_object m_ob; 00020 t_atom *m_seen,*m_want; 00021 short m_size; 00022 short m_where; 00023 void *m_out; 00024 t_critical m_critical; 00025 } t_match; 00026 00027 void *match_class; 00028 00029 void match_assist(t_match *x, void *b, long m, long a, char *s); 00030 void match_freebytes(t_match *x); 00031 void match_int(t_match *x, long n); 00032 void match_float(t_match *x, double f); 00033 void match_list(t_match *x, t_symbol *s, short argc, t_atom *argv); 00034 void match_anything(t_match *x, t_symbol *s, short argc, t_atom *argv); 00035 void match_atom(t_match *x, t_atom *a); 00036 void atom_compare(t_match *x); 00037 Boolean atom_equal(t_atom *a, t_atom *b); 00038 void outlet_atomlist(void *out, long argc, t_atom *argv); 00039 void match_clear(t_match *x); 00040 void match_set(t_match *x, t_symbol *s, short ac, t_atom *av); 00041 void match_setwant(t_atom *temp, short ac, t_atom *av); 00042 void match_free(t_match *x); 00043 void *match_new(t_symbol *s, short ac, t_atom *av); 00044 00045 t_atom atom_novalue = { A_LONG, {NOVALUE} }; 00046 t_symbol *ps_nn, *ps_list; 00047 00048 int main() 00049 { 00050 t_class *c; 00051 00052 c = class_new("match", (method)match_new, (method)match_free, 00053 (short)sizeof(t_match), 0L, A_GIMME, 0); 00054 class_addmethod(c, (method)match_int, "int", A_LONG, 0); 00055 class_addmethod(c, (method)match_float, "float", A_FLOAT, 0); 00056 class_addmethod(c, (method)match_list, "list", A_GIMME, 0); 00057 class_addmethod(c, (method)match_anything, "anything", A_GIMME, 0); 00058 class_addmethod(c, (method)match_set, "set", A_GIMME,0); 00059 class_addmethod(c, (method)match_clear, "clear", 0); 00060 class_addmethod(c, (method)match_assist, "assist",A_CANT,0); 00061 class_register(CLASS_BOX, c); 00062 match_class = c; 00063 00064 ps_nn = gensym("nn"); 00065 ps_list = gensym("list"); 00066 00067 return 0; 00068 } 00069 00070 void match_assist(t_match *x, void *b, long m, long a, char *s) 00071 { 00072 if (m == ASSIST_INLET) 00073 sprintf(s,"Input Sequence to be Matched"); 00074 else 00075 sprintf(s,"list of Matched Sequence"); 00076 } 00077 00078 void match_freebytes(t_match *x) 00079 { 00080 if (x->m_seen) 00081 sysmem_freeptr(x->m_seen);; 00082 if (x->m_want) 00083 sysmem_freeptr(x->m_want);; 00084 } 00085 00086 void match_int(t_match *x, long n) 00087 { 00088 t_atom a; 00089 00090 00091 atom_setlong(&a, n); 00092 if (x->m_size) 00093 match_atom(x,&a); 00094 } 00095 00096 void match_float(t_match *x, double f) 00097 { 00098 t_atom a; 00099 00100 00101 atom_setfloat(&a, f); 00102 if (x->m_size) 00103 match_atom(x,&a); 00104 } 00105 00106 void match_list(t_match *x, t_symbol *s, short argc, t_atom *argv) 00107 { 00108 long i; 00109 00110 if (!x->m_size) 00111 return; 00112 00113 for (i = 0; i < argc; i++) 00114 match_atom(x,argv+i); 00115 } 00116 00117 void match_anything(t_match *x, t_symbol *s, short argc, t_atom *argv) 00118 { 00119 t_atom a; 00120 00121 if (!x->m_size) 00122 return; 00123 00124 00125 atom_setsym(&a, s); 00126 match_atom(x,&a); 00127 match_list(x,s,argc,argv); 00128 } 00129 00130 void match_atom(t_match *x, t_atom *a) 00131 { 00132 long i; 00133 00134 for (i = 0; i < x->m_size-1; i++) 00135 x->m_seen[i] = x->m_seen[i+1]; 00136 x->m_seen[x->m_size-1] = *a; 00137 atom_compare(x); 00138 } 00139 00140 void atom_compare(t_match *x) 00141 { 00142 long i; 00143 00144 for (i = 0; i < x->m_size; i++) { 00145 if (!atom_equal(x->m_seen+i,x->m_want+i)) 00146 return; 00147 } 00148 outlet_atomlist(x->m_out,x->m_size,x->m_seen); 00149 } 00150 00151 Boolean atom_equal(t_atom *a, t_atom *b) 00152 { 00153 if (atom_gettype(b) == A_SYM) { 00154 if(atom_getsym(b) == ps_nn) // wild card match 00155 return true; 00156 else if(atom_gettype(a) == A_SYM) { 00157 return atom_getsym(a) == atom_getsym(b); 00158 } 00159 } 00160 00161 // matching type 00162 if (atom_gettype(a) == atom_gettype(b)) { 00163 if (atom_gettype(a) == A_FLOAT && atom_getfloat(a) == atom_getfloat(b)) 00164 return true; 00165 else if (atom_gettype(a) == A_LONG && atom_getlong(a) == atom_getlong(b)) 00166 return true; 00167 else 00168 return false; 00169 } else if (atom_gettype(a) == A_FLOAT && atom_gettype(b) == A_LONG) { // different types 00170 float temp = atom_getfloat(a); 00171 long itemp = (long)temp; 00172 if (temp == (float)itemp) { 00173 if (itemp == atom_getlong(b)) 00174 return true; 00175 } 00176 return false; 00177 } else if (atom_gettype(b) == A_FLOAT && atom_gettype(a) == A_LONG) { 00178 float temp = atom_getfloat(b); 00179 long itemp = (long)temp; 00180 if (temp == (float)itemp) { 00181 if (itemp == atom_getlong(a)) 00182 return true; 00183 } 00184 return false; 00185 } else 00186 return false; 00187 } 00188 00189 void outlet_atomlist(void *out, long argc, t_atom *argv) 00190 { 00191 if (argc == 1) { 00192 if (atom_gettype(argv) == A_LONG) 00193 outlet_int(out,atom_getlong(argv)); 00194 else if (atom_gettype(argv) == A_FLOAT) 00195 outlet_float(out,atom_getfloat(argv)); 00196 else if (atom_gettype(argv) == A_SYM) 00197 outlet_anything(out,atom_getsym(argv),0,0); 00198 } else if (atom_gettype(argv) == A_FLOAT || atom_gettype(argv) == A_LONG) 00199 outlet_list(out,ps_list,argc,argv); 00200 else if (atom_gettype(argv) == A_SYM) 00201 outlet_anything(out,atom_getsym(argv),argc-1,argv+1); 00202 } 00203 00204 void match_clear(t_match *x) 00205 { 00206 long i; 00207 00208 for (i = 0; i < x->m_size; i++) 00209 x->m_seen[i] = atom_novalue; 00210 } 00211 00212 void match_set(t_match *x, t_symbol *s, short ac, t_atom *av) 00213 { 00214 t_atom *temp; 00215 char savelock; 00216 00217 if (!ac) 00218 return; 00219 00220 if (ac != x->m_size) 00221 temp = (t_atom *)sysmem_newptr((long)ac * sizeof(t_atom)); 00222 else 00223 temp = x->m_want; 00224 match_setwant(temp,ac,av); 00225 savelock = lockout_set(1); 00226 critical_enter(x->m_critical); 00227 if (ac != x->m_size) { 00228 match_freebytes(x); 00229 x->m_want = temp; 00230 x->m_seen = (t_atom *)sysmem_newptr((long)ac * sizeof(t_atom)); 00231 } 00232 x->m_size = ac; 00233 match_clear(x); 00234 lockout_set(savelock); 00235 critical_exit(x->m_critical); 00236 } 00237 00238 void match_setwant(t_atom *temp, short ac, t_atom *av) 00239 { 00240 long i; 00241 00242 for (i = 0; i < ac; i++) 00243 temp[i] = av[i]; 00244 } 00245 00246 void match_free(t_match *x) 00247 { 00248 match_freebytes(x); 00249 critical_free(x->m_critical); 00250 } 00251 00252 void *match_new(t_symbol *s, short ac, t_atom *av) 00253 { 00254 t_match *x; 00255 00256 x = object_alloc(match_class); 00257 x->m_out = outlet_new((t_object *)x,0); 00258 critical_new(&x->m_critical); 00259 if (ac) { 00260 x->m_want = (t_atom *)sysmem_newptr((long)ac * sizeof(t_atom)); 00261 match_setwant(x->m_want,ac,av); 00262 x->m_seen = (t_atom *)sysmem_newptr((long)ac * sizeof(t_atom)); 00263 x->m_size = ac; 00264 match_clear(x); 00265 } else { 00266 x->m_seen = 0; 00267 x->m_want = 0; 00268 x->m_size = 0; 00269 } 00270 return x; 00271 }
Copyright © 2008, Cycling '74