From 0f849641afd27b4e7c9326fbcd402105fd62ced0 Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Mon, 26 Sep 2005 13:59:34 +0000 Subject: - better handling of click callback bugfixes and optimizations, especially for DSP under Max/MSP - more compatible handling of attributes in patcher (hiding is now an option - define FLEXT_ATTRHIDE) svn path=/trunk/; revision=3636 --- externals/grill/flext/source/flbase.cpp | 13 ++- externals/grill/flext/source/flbase.h | 2 +- externals/grill/flext/source/flclass.h | 5 +- externals/grill/flext/source/fldsp.cpp | 134 +++++++++---------------------- externals/grill/flext/source/fldsp.h | 42 +++------- externals/grill/flext/source/flext.cpp | 63 ++++++++------- externals/grill/flext/source/flout.cpp | 46 +++++------ externals/grill/flext/source/flproxy.cpp | 18 +---- 8 files changed, 123 insertions(+), 200 deletions(-) (limited to 'externals/grill/flext/source') diff --git a/externals/grill/flext/source/flbase.cpp b/externals/grill/flext/source/flbase.cpp index c3d94d83..cbb46aec 100644 --- a/externals/grill/flext/source/flbase.cpp +++ b/externals/grill/flext/source/flbase.cpp @@ -52,6 +52,10 @@ bool flext_obj::init_ok; void flext_obj::ProcessAttributes(bool attr) { process_attributes = attr; } +#if FLEXT_SYS == FLEXT_SYS_MAX +static const t_symbol *sym__shP = NULL; +#endif + ///////////////////////////////////////////////////////// // Constructor // @@ -64,7 +68,7 @@ flext_obj :: FLEXT_CLASSDEF(flext_obj)() #if FLEXT_SYS == FLEXT_SYS_PD m_canvas = canvas_getcurrent(); #elif FLEXT_SYS == FLEXT_SYS_MAX - m_canvas = (t_patcher *)gensym("#P")->s_thing; + m_canvas = (t_patcher *)sym__shP->s_thing; x_obj->curinlet = 0; #endif } @@ -78,6 +82,13 @@ flext_obj :: ~FLEXT_CLASSDEF(flext_obj)() x_obj = NULL; } +void flext_obj::__setup__(t_classid) +{ +#if FLEXT_SYS == FLEXT_SYS_MAX + sym__shP = MakeSymbol("#P"); +#endif + flext::Setup(); +} bool flext_obj::Init() { return true; } bool flext_obj::Finalize() { return true; } diff --git a/externals/grill/flext/source/flbase.h b/externals/grill/flext/source/flbase.h index 664dc15b..46c53949 100644 --- a/externals/grill/flext/source/flbase.h +++ b/externals/grill/flext/source/flbase.h @@ -210,7 +210,7 @@ class FLEXT_SHARE FLEXT_CLASSDEF(flext_obj): public: //! Creation callback - static void __setup__(t_classid) { flext::Setup(); } + static void __setup__(t_classid); /*! \brief This is a temporary holder \warning don't touch it! diff --git a/externals/grill/flext/source/flclass.h b/externals/grill/flext/source/flclass.h index cf7cec62..63dbc4d1 100644 --- a/externals/grill/flext/source/flclass.h +++ b/externals/grill/flext/source/flclass.h @@ -518,12 +518,15 @@ public: // needed by VC++ 6 protected: FLEXT_CLASSDEF(flext_base)(); - virtual ~FLEXT_CLASSDEF(flext_base)(); /*! \brief Set up inlets and outlets, method and attribute lists */ virtual bool Init(); + /*! \brief Deallocate all kinds of stuff + */ + virtual void Exit(); + /*! \defgroup FLEXT_C_ATTR Attribute handling methods (object scope) @{ diff --git a/externals/grill/flext/source/fldsp.cpp b/externals/grill/flext/source/fldsp.cpp index fa9ac506..f6f109ad 100644 --- a/externals/grill/flext/source/fldsp.cpp +++ b/externals/grill/flext/source/fldsp.cpp @@ -18,10 +18,6 @@ WARRANTIES, see the file, "license.txt," in this distribution. // === flext_dsp ============================================== -#if FLEXT_SYS == FLEXT_SYS_JMAX -const t_symbol *flext_dsp::dspsym = MakeSymbol("__flext_dspfun__"); -#endif - void flext_dsp::Setup(t_classid id) { t_class *c = getClass(id); @@ -33,52 +29,45 @@ void flext_dsp::Setup(t_classid id) CLASS_MAINSIGNALIN(c,flext_hdr,defsig); // float messages going into the left inlet are converted to signal add_dsp(c,cb_dsp); add_method1(c,cb_enable,"enable",A_FLOAT); -#elif FLEXT_SYS == FLEXT_SYS_JMAX - fts_dsp_declare_function(dspsym,dspmeth); - fts_class_message_varargs(c, fts_s_put, cb_dsp); - fts_class_message_varargs(c, MakeSymbol("enable"), cb_enable); +#else +#error Platform not supported! #endif } -flext_dsp::FLEXT_CLASSDEF(flext_dsp)(): -#if FLEXT_SYS == FLEXT_SYS_JMAX - srate(fts_dsp_get_sample_rate()), // should we set it? - blksz(fts_dsp_get_tick_size()), -#else - srate(sys_getsr()),blksz(sys_getblksize()), -#endif - chnsin(0),chnsout(0), +flext_dsp::FLEXT_CLASSDEF(flext_dsp)() + : srate(sys_getsr()),blksz(sys_getblksize()) + , vecs(NULL) #if FLEXT_SYS != FLEXT_SYS_MAX - dspon(true), + , dspon(true) #endif - invecs(NULL),outvecs(NULL) +{} + +#if FLEXT_SYS == FLEXT_SYS_MAX +bool flext_dsp::Init() { -#if FLEXT_SYS == FLEXT_SYS_JMAX - fts_dsp_object_init(thisHdr()); -#endif -} + if(!flext_base::Init()) + return false; + // according to the Max/MSP SDK this should be prior to any inlet creation, BUT + // that doesn't seem to be true... multiple signal ins and additional inlets don't seem to work then + dsp_setup(thisHdr(),CntInSig()); // signal inlets + return true; +} +#endif -flext_dsp::~FLEXT_CLASSDEF(flext_dsp)() +void flext_dsp::Exit() { -#if FLEXT_SYS == FLEXT_SYS_JMAX - fts_dsp_object_delete(thisHdr()); -#endif - #if FLEXT_SYS == FLEXT_SYS_MAX - // switch off dsp as the dsp function might get called afterwards (different thread) - thisHdr()->z_disabled = true; + // according to David Z. one should do that first... + dsp_free(thisHdr()); #endif - if(invecs) delete[] invecs; - if(outvecs) delete[] outvecs; + flext_base::Exit(); + + if(vecs) delete[] vecs; } -#if FLEXT_SYS == FLEXT_SYS_JMAX -void flext_dsp::dspmeth(fts_word_t *w) -{ -} -#else + t_int *flext_dsp::dspmeth(t_int *w) { flext_dsp *obj = (flext_dsp *)(size_t)w[1]; @@ -95,11 +84,8 @@ t_int *flext_dsp::dspmeth(t_int *w) } return w+2; } -#endif -#if FLEXT_SYS == FLEXT_SYS_JMAX -void flext_dsp::cb_dsp(fts_object_t *c, int winlet, fts_symbol_t s, int ac, const fts_atom_t *at) -#elif FLEXT_SYS == FLEXT_SYS_MAX +#if FLEXT_SYS == FLEXT_SYS_MAX void flext_dsp::cb_dsp(t_class *c,t_signal **sp,short *count) #else void flext_dsp::cb_dsp(t_class *c,t_signal **sp) @@ -113,94 +99,52 @@ void flext_dsp::cb_dsp(t_class *c,t_signal **sp) #if FLEXT_SYS == FLEXT_SYS_PD // min. 1 input channel! (CLASS_MAININLET in pd...) if(!in) in = 1; -#else - if(in+out == 0) return; #endif // store current dsp parameters -#if FLEXT_SYS == FLEXT_SYS_JMAX - fts_dsp_descr_t *dsp = (fts_dsp_descr_t *)fts_get_pointer(at+0); - obj->srate = fts_dsp_get_input_srate(dsp,0); - obj->blksz = fts_dsp_get_input_size(dsp,0); // is this guaranteed to be the same as sys_getblksize() ? -#else obj->srate = sp[0]->s_sr; obj->blksz = sp[0]->s_n; // is this guaranteed to be the same as sys_getblksize() ? -#endif // store in and out signal vectors - if(in != obj->chnsin) { - if(obj->invecs) delete[] obj->invecs; - obj->invecs = in?new t_signalvec[in]:NULL; - obj->chnsin = in; - } - for(i = 0; i < in; ++i) - obj->invecs[i] = -#if FLEXT_SYS == FLEXT_SYS_JMAX - fts_dsp_get_input_name(dsp,i); -#else - sp[i]->s_vec; -#endif + if((in+out) && !obj->vecs) + obj->vecs = new t_signalvec[in+out]; - if(out != obj->chnsout) { - if(obj->outvecs) delete[] obj->outvecs; - obj->outvecs = out?new t_signalvec[out]:NULL; - obj->chnsout = out; - } + for(i = 0; i < in; ++i) + obj->vecs[i] = sp[i]->s_vec; for(i = 0; i < out; ++i) - obj->outvecs[i] = -#if FLEXT_SYS == FLEXT_SYS_JMAX - fts_dsp_get_output_name(dsp,i); -#else - sp[in+i]->s_vec; -#endif + obj->vecs[in+i] = sp[in+i]->s_vec; // with the following call derived classes can do their eventual DSP setup if(obj->CbDsp()) { // set the DSP function -#if FLEXT_SYS == FLEXT_SYS_JMAX - fts_atom_t args; - fts_set_pointer(args,obj); - fts_dsp_add_function(dspsym,1,args); -#else dsp_add((t_dspmethod)dspmeth,1,obj); -#endif } } -/* -#if FLEXT_SYS == FLEXT_SYS_JMAX -void flext_dsp::cb_dsp_init(fts_object_t *c, int winlet, fts_symbol_t *s, int ac, const fts_atom_t *at) -{ - fts_dsp_add_object(c); -} - -void flext_dsp::cb_dsp_delete(fts_object_t *c, int winlet, fts_symbol_t *s, int ac, const fts_atom_t *at) -{ - fts_dsp_remove_object(c); -} -#endif -*/ void flext_dsp::m_dsp(int /*n*/,t_signalvec const * /*insigs*/,t_signalvec const * /*outsigs*/) {} bool flext_dsp::CbDsp() { - m_dsp(Blocksize(),invecs,outvecs); + // invoke legacy method + m_dsp(Blocksize(),InSig(),OutSig()); return true; } +// this function will be overridden anyway - the probably useless default is clearing all outputs void flext_dsp::m_signal(int n,t_sample *const * /*insigs*/,t_sample *const *outs) { for(int i = 0; i < CntOutSig(); ++i) ZeroSamples(outs[i],n); } -void flext_dsp::CbSignal() { m_signal(Blocksize(),invecs,outvecs); } +void flext_dsp::CbSignal() +{ + // invoke legacy method + m_signal(Blocksize(),InSig(),OutSig()); +} #if FLEXT_SYS == FLEXT_SYS_PD void flext_dsp::cb_enable(t_class *c,t_float on) { thisObject(c)->dspon = on != 0; } -#elif FLEXT_SYS == FLEXT_SYS_JMAX -void flext_dsp::cb_enable(fts_object_t *c, int winlet, fts_symbol_t s, int ac, const fts_atom_t *at) -{ thisObject(c)->dspon = fts_get_int(at+0) != 0; } #endif diff --git a/externals/grill/flext/source/fldsp.h b/externals/grill/flext/source/fldsp.h index 19b4b3cb..91cbccb0 100644 --- a/externals/grill/flext/source/fldsp.h +++ b/externals/grill/flext/source/fldsp.h @@ -52,23 +52,19 @@ public: int Blocksize() const { return blksz; } //! returns array of input vectors (CntInSig() vectors) - t_sample *const *InSig() const { return invecs; } + t_sample *const *InSig() const { return vecs; } //! returns input vector - t_sample *InSig(int i) const { return invecs[i]; } + t_sample *InSig(int i) const { return vecs[i]; } //! returns array of output vectors (CntOutSig() vectors) - t_sample *const *OutSig() const { return outvecs; } + t_sample *const *OutSig() const { return vecs+CntInSig(); } //! returns output vector - t_sample *OutSig(int i) const { return outvecs[i]; } + t_sample *OutSig(int i) const { return vecs[CntInSig()+i]; } //! typedef describing a signal vector -#if FLEXT_SYS == FLEXT_SYS_JMAX - typedef fts_symbol_t t_signalvec; -#else typedef t_sample *t_signalvec; -#endif //! @} @@ -145,48 +141,34 @@ public: protected: FLEXT_CLASSDEF(flext_dsp)(); - virtual ~FLEXT_CLASSDEF(flext_dsp)(); + +#if FLEXT_SYS == FLEXT_SYS_MAX + virtual bool Init(); +#endif + + virtual void Exit(); private: // not static, could be different in different patchers.. float srate; int blksz; - int chnsin,chnsout; + t_signalvec *vecs; // setup function static void Setup(t_classid c); // callback functions - -#if FLEXT_SYS == FLEXT_SYS_JMAX - static void cb_dsp(fts_object_t *o, int winlet, fts_symbol_t s, int ac, const fts_atom_t *at); -// static void cb_dsp_init(fts_object_t *o, int winlet, fts_symbol_t *s, int ac, const fts_atom_t *at); -// static void cb_dsp_delete(fts_object_t *o, int winlet, fts_symbol_t *s, int ac, const fts_atom_t *at); -#elif FLEXT_SYS == FLEXT_SYS_MAX +#if FLEXT_SYS == FLEXT_SYS_MAX static void cb_dsp(t_class *c,t_signal **s,short *count); #else static void cb_dsp(t_class *c,t_signal **s); -#endif - -#if FLEXT_SYS != FLEXT_SYS_MAX -#if FLEXT_SYS == FLEXT_SYS_JMAX - static void cb_enable(fts_object_t *o, int winlet, fts_symbol_t s, int ac, const fts_atom_t *at); -#else static void cb_enable(t_class *c,t_float on); -#endif bool dspon; #endif // dsp stuff - -#if FLEXT_SYS == FLEXT_SYS_JMAX - static void dspmeth(fts_word_t *); - static const t_symbol *dspsym; -#else static t_int *dspmeth(t_int *w); -#endif - t_signalvec *invecs,*outvecs; }; #endif diff --git a/externals/grill/flext/source/flext.cpp b/externals/grill/flext/source/flext.cpp index 70184bef..4d62633e 100644 --- a/externals/grill/flext/source/flext.cpp +++ b/externals/grill/flext/source/flext.cpp @@ -48,19 +48,42 @@ flext_base::FLEXT_CLASSDEF(flext_base)() } } -flext_base::~FLEXT_CLASSDEF(flext_base)() +/*! This virtual function is called after the object has been created, that is, + after the constructor has been processed. + It creates the inlets and outlets and the message and attribute lists. + \note You can override it in your own class, but be sure to call it, + \note otherwise no inlets/outlets will be created + \note All inlet, outlets, method and attribute declarations must be made before a call to Init! + \remark Creation of inlets/outlets can't be done upon declaration, as Max/MSP needs creation + \remark in reverse. +*/ +bool flext_base::Init() +{ + bool ok = flext_obj::Init(); + + if(ok) ok = InitInlets() && InitOutlets(); + + if(ok) { + if(HasAttributes() && m_holdaargc && m_holdaargv) { + // initialize creation attributes + ok = InitAttrib(m_holdaargc,m_holdaargv); + } + } + + return ok; +} + + +/*! This virtual function is called before the destructor. + We do this because here we can still call virtual methods. +*/ +void flext_base::Exit() { #if FLEXT_SYS == FLEXT_SYS_PD && !defined(FLEXT_NOATTREDIT) // attribute editor window may still be open -> close it gfxstub_deleteforkey(thisHdr()); #endif -#if FLEXT_SYS == FLEXT_SYS_MAX - // according to David Z. one should do that first... - if(insigs) dsp_free(thisHdr()); -// if(insigs) dsp_freebox(thisHdr()); -#endif - #ifdef FLEXT_THREADS StopThreads(); #endif @@ -101,33 +124,11 @@ flext_base::~FLEXT_CLASSDEF(flext_base)() delete[] outdesc; } #endif -} -/*! This virtual function is called after the object has been created, that is, - after the constructor has been processed. - It creates the inlets and outlets and the message and attribute lists. - \note You can override it in your own class, but be sure to call it, - \note otherwise no inlets/outlets will be created - \note All inlet, outlets, method and attribute declarations must be made before a call to Init! - \remark Creation of inlets/outlets can't be done upon declaration, as Max/MSP needs creation - \remark in reverse. -*/ -bool flext_base::Init() -{ - bool ok = flext_obj::Init(); - - if(ok) ok = InitInlets() && InitOutlets(); - - if(ok) { - if(HasAttributes() && m_holdaargc && m_holdaargv) { - // initialize creation attributes - ok = InitAttrib(m_holdaargc,m_holdaargv); - } - } - - return ok; + flext_obj::Exit(); } + /*! Set up proxy classes and basic methods at class creation time This ensures that they are processed before the registered flext messages */ diff --git a/externals/grill/flext/source/flout.cpp b/externals/grill/flext/source/flout.cpp index 7f3130e8..d09b4e55 100644 --- a/externals/grill/flext/source/flout.cpp +++ b/externals/grill/flext/source/flout.cpp @@ -191,24 +191,25 @@ bool flext_base::InitInlets() error("%s: All signal inlets must be left-aligned",thisName()); ok = false; break; - case xlet_float: - inlets[ix] = NULL; - if(ix >= 10) { - post("%s: Only 9 float inlets possible",thisName()); - ok = false; - } - else - floatin(x_obj,ix); - break; - case xlet_int: - inlets[ix] = NULL; - if(ix >= 10) { - post("%s: Only 9 int inlets possible",thisName()); - ok = false; - } - else - intin(x_obj,ix); - break; + case xlet_float: { + if(ix < 10) { + inlets[ix] = NULL; + floatin(x_obj,ix); + break; + } + else + goto makeproxy; + } + case xlet_int: { + if(ix < 10) { + inlets[ix] = NULL; + intin(x_obj,ix); + break; + } + else + goto makeproxy; + } + makeproxy: case xlet_any: // non-leftmost case xlet_sym: case xlet_list: @@ -221,12 +222,9 @@ bool flext_base::InitInlets() } } } - -// incnt = cnt; - - if(insigs) - dsp_setup(thisHdr(),insigs); // signal inlets - } + + while(ix >= 0) inlets[ix--] = NULL; + } #else #error #endif diff --git a/externals/grill/flext/source/flproxy.cpp b/externals/grill/flext/source/flproxy.cpp index ffecd405..b25fb0fd 100755 --- a/externals/grill/flext/source/flproxy.cpp +++ b/externals/grill/flext/source/flproxy.cpp @@ -42,14 +42,12 @@ add_method1(c,cb_px_ft ## IX,"ft" #IX,A_FLOAT) void flext_base::cb_px_anything(t_class *c,const t_symbol *s,short argc,t_atom *argv) { - // check if inlet allows anything (or list) int ci = ((flext_hdr *)c)->curinlet; thisObject(c)->CbMethodHandler(ci,s,argc,argv); } void flext_base::cb_px_int(t_class *c,long v) { - // check if inlet allows int type t_atom atom; SetInt(atom,v); int ci = ((flext_hdr *)c)->curinlet; thisObject(c)->CbMethodHandler(ci,sym_int,1,&atom); @@ -57,7 +55,6 @@ void flext_base::cb_px_int(t_class *c,long v) void flext_base::cb_px_float(t_class *c,double v) { - // check if inlet allows float type t_atom atom; SetFloat(atom,v); int ci = ((flext_hdr *)c)->curinlet; thisObject(c)->CbMethodHandler(ci,sym_float,1,&atom); @@ -65,7 +62,6 @@ void flext_base::cb_px_float(t_class *c,double v) void flext_base::cb_px_bang(t_class *c) { - // check if inlet allows bang int ci = ((flext_hdr *)c)->curinlet; thisObject(c)->CbMethodHandler(ci,sym_bang,0,NULL); } @@ -105,7 +101,7 @@ void flext_base::SetProxies(t_class *c) add_bang(c,cb_px_bang); add_method1(c,cb_px_int,"int",A_INT); add_method1(c,cb_px_float,"float",A_FLOAT); - add_methodG(c,cb_px_anything,"list"); +// add_methodG(c,cb_px_anything,"list"); add_anything(c,cb_px_anything); #else #error Not implemented! @@ -122,16 +118,4 @@ void flext_base::SetProxies(t_class *c) ADD_IN_FT(8); ADD_IN_FT(9); } - -#elif FLEXT_SYS == FLEXT_SYS_JMAX -void flext_base::jmax_proxy(fts_object_t *c, int winlet, fts_symbol_t s, int argc, const fts_atom_t *argv) -{ - thisObject(c)->CbMethodHandler(winlet,s,argc,argv); -} - -void flext_base::SetProxies(t_class *c) -{ - fts_class_set_default_handler(c, jmax_proxy); -} - #endif -- cgit v1.2.1