/* prepend - just like in MaxMSP Copyright (c) 2002 Thomas Grill (xovo@gmx.net) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ #include #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 401) #error You need at least flext version 0.4.1 #endif #define PREPEND_VERSION "0.0.3" class prepend: public flext_base { FLEXT_HEADER_S(prepend, flext_base, Setup) public: prepend(int argc,t_atom *argv); protected: void m_bang(); void m_set(int argc,t_atom *argv) { reg[0].Store(NULL,argc,argv); } void m_any0(const t_symbol *s,int argc,t_atom *argv) { reg[1].Store(s,argc,argv); m_bang(); } void m_any1(const t_symbol *s,int argc,t_atom *argv) { reg[0].Store(s,argc,argv); } virtual void m_help(); private: static void Setup(t_class *c); class reg_t { public: reg_t(): cnt(0),lst(NULL) {} ~reg_t() { if(lst) delete[] lst; } bool Is() const { return cnt && lst; } bool IsSimple() const { return !IsSymbol(lst[0]); } bool IsList() const { return IsSymbol(lst[0]) && GetSymbol(lst[0]) == &s_list; } void Store(const t_symbol *s,int argc,t_atom *argv); int cnt; t_atom *lst; } reg[2]; FLEXT_CALLBACK(m_bang) FLEXT_CALLBACK_V(m_set) FLEXT_CALLBACK_A(m_any0) FLEXT_CALLBACK_A(m_any1) }; FLEXT_NEW_V("prepend",prepend) prepend::prepend(int argc,t_atom *argv) { AddInAnything(2); AddOutAnything(); m_set(argc,argv); } void prepend::Setup(t_class *c) { FLEXT_CADDMETHOD_(c,0,"bang",m_bang); // FLEXT_CADDMETHOD_(c,0,"set",m_set); FLEXT_CADDMETHOD(c,0,m_any0); FLEXT_CADDMETHOD(c,1,m_any1); } void prepend::reg_t::Store(const t_symbol *s,int argc,t_atom *argv) { if(lst) delete[] lst; cnt = 0; lst = new t_atom[argc+1]; if(s && s != &s_float) SetSymbol(lst[cnt++],s); else if(argc > 0 && !IsSymbol(argv[0])) SetSymbol(lst[cnt++],&s_list); for(int i = 0; i < argc; ++i,++cnt) lst[cnt] = argv[i]; } void prepend::m_bang() { t_atom *ret = new t_atom[reg[0].cnt+reg[1].cnt+1]; int i,rcnt = 0; if(reg[0].Is()) { if(reg[0].IsSimple()) SetSymbol(ret[rcnt++],&s_list); for(i = reg[0].IsList()?1:0; i < reg[0].cnt; ++i) ret[rcnt++] = reg[0].lst[i]; } else SetSymbol(ret[rcnt++],&s_list); if(reg[1].Is()) { for(i = reg[1].IsList()?1:0; i < reg[1].cnt; ++i) ret[rcnt++] = reg[1].lst[i]; } if(IsSymbol(ret[0])) ToOutAnything(0,GetSymbol(ret[0]),rcnt-1,ret+1); else ToOutList(0,rcnt,ret); delete[] ret; } void prepend::m_help() { post("%s - just like in Max/MSP, version " PREPEND_VERSION,thisName()); #ifdef _DEBUG post("compiled on " __DATE__ " " __TIME__); #endif post("(C) Thomas Grill, 2002"); post(""); post("Arguments: %s [atoms to prepend]",thisName()); post("Inlets: 1:triggering atoms"); post("Inlets: 2:atoms to prepend"); post("Outlets: 1:sum of prepend"); post("Methods:"); post("\thelp: shows this help"); // post("\tset [atoms]: set atoms to prepend"); post(""); }