bool flext_base::ItemCont::Remove(Item *item,const t_symbol *tag,int inlet,bool free) { FLEXT_ASSERT(tag); if(Contained(inlet)) { ItemSet &set = GetInlet(inlet); Item *lit = set.find(tag); for(Item *prv = NULL; lit; prv = lit,lit = lit->nxt) { if(lit == item) { if(prv) prv->nxt = lit->nxt; else if(lit->nxt) { Item *old = set.insert(tag,lit->nxt); FLEXT_ASSERT(!old); } else { Item *l = set.remove(tag); FLEXT_ASSERT(l == lit); } lit->nxt = NULL; if(free) delete lit; return true; } } } return false; }
FLEXT_TEMPIMPL(void TableAnyMap)::iterator::forward() { FLEXT_ASSERT(map || ix >= map->n); if(++ix >= map->n) { TableAnyMap *nmap; // we reached the end of the slots if(map->right) { // climb up one map = map->right; leftmost(); ix = 0; } else { // fall back for(;;) { nmap = map->parent; if(!nmap) break; // no parent if(nmap->left == map) { // ok, we are in front of the slots now ix = 0; map = nmap; break; } else { FLEXT_ASSERT(nmap->right == map); ix = (map = nmap)->n; } } } } }
FLEXT_TEMPIMPL(void *FLEXT_CLASSDEF(flext_root))::operator new(size_t bytes) { bytes += sizeof(size_t); #ifdef FLEXT_DEBUGMEM bytes += sizeof(memtest)*2; #endif char *blk; if(UNLIKELY(bytes >= LARGEALLOC)) { #if FLEXT_SYS == FLEXT_SYS_MAX && defined(_SYSMEM_H_) blk = (char *)sysmem_newptr(bytes); #else // use C library function for large memory blocks blk = (char *)malloc(bytes); #endif } else { //! We need system locking here for secondary threads! SYSLOCK(); blk = (char *)getbytes(bytes); SYSUNLOCK(); } FLEXT_ASSERT(blk); *(size_t *)blk = bytes; #ifdef FLEXT_DEBUGMEM *(size_t *)(blk+sizeof(size_t)) = memtest; *(size_t *)(blk+bytes-sizeof(memtest)) = memtest; return blk+sizeof(size_t)+sizeof(memtest); #else return blk+sizeof(size_t); #endif }
FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_root))::operator delete(void *blk) { if(!blk) return; FLEXT_ASSERT(MemCheck(blk)); #ifdef FLEXT_DEBUGMEM char *ori = (char *)blk-sizeof(size_t)-sizeof(memtest); #else char *ori = (char *)blk-sizeof(size_t); #endif size_t bytes = *(size_t *)ori; if(UNLIKELY(bytes >= LARGEALLOC)) { #if FLEXT_SYS == FLEXT_SYS_MAX && defined(_SYSMEM_H_) sysmem_freeptr(ori); #else // use C library function for large memory blocks free(ori); #endif } else { //! We need system locking here for secondary threads! SYSLOCK(); freebytes(ori,bytes); SYSUNLOCK(); } }
void VSTPlugin::StartEditing(WHandle h) { FLEXT_ASSERT(h != NULL); Dispatch(effEditOpen,0,0,hwnd = h); TitleEditor(this,title.c_str()); }
FLEXT_TEMPIMPL(void *FLEXT_CLASSDEF(flext_root))::NewAligned(size_t bytes,int bitalign) { const size_t ovh = sizeof(size_t)+sizeof(char *); const size_t alignovh = bitalign/8-1; bytes += ovh+alignovh; char *blk; if(UNLIKELY(bytes >= LARGEALLOC)) { #if FLEXT_SYS == FLEXT_SYS_MAX && defined(_SYSMEM_H_) blk = (char *)sysmem_newptr(bytes); #else // use C library function for large memory blocks blk = (char *)malloc(bytes); #endif } else { //! We need system locking here for secondary threads! SYSLOCK(); #if defined(FLEXT_USE_CMEM) blk = (char *)malloc(bytes); #else blk = (char *)getbytes(bytes); #endif SYSUNLOCK(); } FLEXT_ASSERT(blk); char *ablk = reinterpret_cast<char *>((reinterpret_cast<size_t>(blk)+ovh+alignovh) & ~alignovh); *(char **)(ablk-sizeof(size_t)-sizeof(char *)) = blk; *(size_t *)(ablk-sizeof(size_t)) = bytes; return ablk; }
void Idle(bool (*idlefun)(int argc,const t_atom *argv),int argc,const t_atom *argv) { FLEXT_ASSERT(idlefun); th = NULL; fun = idlefun; SetMsg(NULL,argc,argv); }
FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_root))::FreeAligned(void *blk) { FLEXT_ASSERT(blk); char *ori = *(char **)((char *)blk-sizeof(size_t)-sizeof(char *)); size_t bytes = *(size_t *)((char *)blk-sizeof(size_t)); if(UNLIKELY(bytes >= LARGEALLOC)) { #if FLEXT_SYS == FLEXT_SYS_MAX && defined(_SYSMEM_H_) sysmem_freeptr(ori); #else // use C library function for large memory blocks free(ori); #endif } else { //! We need system locking here for secondary threads! SYSLOCK(); #if defined(FLEXT_USE_CMEM) free(ori); #else freebytes(ori,bytes); #endif SYSUNLOCK(); } }
void Set(const t_symbol *r,const t_symbol *s,int ac,const t_atom *av) { FLEXT_ASSERT(r); th = NULL; recv = r; SetMsg(s,ac,av); }
void Set(flext_base *t,int o,const t_symbol *s,int ac,const t_atom *av) { FLEXT_ASSERT(t); th = t; out = o; SetMsg(s,ac,av); }
void Free() { if(argc > STATSIZE) { FLEXT_ASSERT(argv); delete[] argv; } }
void flext_base::cb_anything(flext_hdr *c,const t_symbol *s,int argc,t_atom *argv) { Locker lock(c); if(UNLIKELY(!s)) { // apparently, this happens only in one case... object is a DSP object, but has no main DSP inlet... // interpret tag from args if(!argc) s = sym_bang; else if(argc == 1) { if(IsFloat(*argv)) s = sym_float; else if(IsSymbol(*argv)) s = sym_symbol; else if(IsPointer(*argv)) s = sym_pointer; else FLEXT_ASSERT(false); } else s = sym_list; } thisObject(c)->CbMethodHandler(0,s,argc,argv); }
void flext_base::ItemCont::Add(Item *item,const t_symbol *tag,int inlet) { FLEXT_ASSERT(tag); if(!Contained(inlet)) Resize(inlet+2); ItemSet &set = GetInlet(inlet); Item *lst = set.find(tag); if(!lst) { Item *old = set.insert(tag,lst = item); FLEXT_ASSERT(!old); } else for(;;) if(!lst->nxt) { lst->nxt = item; break; } else lst = lst->nxt; members++; }
FLEXT_TEMPIMPL(void *TableAnyMap)::_set(int tsize,size_t k,void *t) { FLEXT_ASSERT(n); if(n < tsize) { // fall through } else if(k < data[0].key) return _toleft(tsize,k,t); else if(k > data[tsize-1].key) return _toright(tsize,k,t); int ix = _tryix(k); if(ix >= n) { FLEXT_ASSERT(ix == n); // after last entry data[n++](k,t); return NULL; } size_t dk = data[ix].key; if(k == dk) { // update data in existing slot (same key) void *a = data[ix].value; data[ix] = t; return a; } else { // insert new slot by shifting the higher ones FLEXT_ASSERT(k < dk); void *a; if(n == tsize) a = _toright(tsize,data[tsize-1]); else { ++n; a = NULL; } Data *tg = data+ix; for(Data *d = data+n-1; d > tg; d--) d[0] = d[-1]; (*tg)(k,t); return a; } }
/*! 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_MAX // according to David Z. one should do that first... if(NeedDSP()) dsp_free(thisHdr()); #endif #if FLEXT_SYS == FLEXT_SYS_PD && !defined(FLEXT_NOATTREDIT) // attribute editor window may still be open -> close it gfxstub_deleteforkey(thisHdr()); #endif #ifdef FLEXT_THREADS StopThreads(); #endif // send remaining pending messages for this object QFlush(this); // delete message lists if(bindhead) delete bindhead; // ATTENTION: the object must free all memory associated to bindings itself if(methhead) delete methhead; if(attrhead) delete attrhead; if(attrdata) delete attrdata; #if FLEXT_SYS == FLEXT_SYS_PD || FLEXT_SYS == FLEXT_SYS_MAX if(outlets) delete[] outlets; if(inlets) { FLEXT_ASSERT(incnt > 1); for(int ix = 1; ix < incnt; ++ix) if(inlets[ix-1]) { // release proxy object #if FLEXT_SYS == FLEXT_SYS_PD pd_free(&inlets[ix-1]->obj.ob_pd); #elif FLEXT_SYS == FLEXT_SYS_MAX freeobject((object *)inlets[ix-1]); #endif } delete[] inlets; } #endif #if FLEXT_SYS == FLEXT_SYS_MAX if(indesc) { for(int i = 0; i < incnt; ++i) if(indesc[i]) delete[] indesc[i]; delete[] indesc; } if(outdesc) { for(int i = 0; i < outcnt; ++i) if(outdesc[i]) delete[] outdesc[i]; delete[] outdesc; } #endif flext_obj::Exit(); }
void VSTPlugin::Delete(VSTPlugin *p) { FLEXT_ASSERT(p); // tell plugin to close editor! StopEditor(p); // transfer to deletion thread todel.Push(new DelPlugin(p)); thrcond.Signal(); }
void m_bundleclose() { if(!bundle) throw std::runtime_error("No open bundle"); FLEXT_ASSERT(packet); --bundle; *packet << osc::EndBundle; if(!bundle && autosend) Send(true); }
void pybase::Reload() { ThrLock lock; PyObject *reg = GetRegistry(REGNAME); if(reg) { PyObject *key; Py_ssize_t pos = 0; while(PyDict_Next(reg,&pos,&key,NULL)) { pybase *th = (pybase *)PyLong_AsLong(key); FLEXT_ASSERT(th); th->Unload(); } UnloadModule(); } bool ok = ReloadModule(); if(ok) { LoadModule(); if(reg) { SetRegistry(REGNAME,reg); PyObject *key; Py_ssize_t pos = 0; while(PyDict_Next(reg,&pos,&key,NULL)) { pybase *th = (pybase *)PyLong_AsLong(key); FLEXT_ASSERT(th); th->Load(); } } else Load(); } Report(); }
FLEXT_TEMPIMPL(void TableAnyMap)::_check(int tsize) { FLEXT_ASSERT(n); size_t k = data[0].key; for(int i = 1; i < n; ++i) { size_t k2 = data[i].key; FLEXT_ASSERT(k < k2); k = k2; } if(left || right) FLEXT_ASSERT(n == tsize); if(left) { FLEXT_ASSERT(flext::MemCheck(left)); left->_check(tsize); } if(right) { FLEXT_ASSERT(flext::MemCheck(right)); right->_check(tsize); } }
virtual bool Seek(double pos) { FLEXT_ASSERT(movie); FLEXT_ASSERT(extractionSessionRef != nil); QTThread qt(movie); TimeRecord timeRec; timeRec.scale = GetMovieTimeScale(movie); timeRec.base = NULL; unsigned long long fpos = (long long)(pos*timeRec.scale); timeRec.value.hi = int(fpos>>32); timeRec.value.lo = int(fpos&((1LL<<32)-1)); // Set the extraction current time. The duration will // be determined by how much is pulled. OSStatus err = MovieAudioExtractionSetProperty(extractionSessionRef, kQTPropertyClass_MovieAudioExtraction_Movie, kQTMovieAudioExtractionMoviePropertyID_CurrentTime, sizeof(TimeRecord), &timeRec); return err == 0; }
FLEXT_TEMPIMPL(void *TableAnyMap)::_find(int tsize,size_t k) const { FLEXT_ASSERT(n); if(n < tsize) { // fall through } else if(k < data[0].key) return left?left->_find(tsize,k):NULL; else if(k > data[n-1].key) return right?right->_find(tsize,k):NULL; const int ix = _tryix(k); return ix < n && data[ix].key == k?data[ix].value:NULL; }
/*! Disconnect from stream */ void m_disconnect() { if(stream) { // utmost care, as DSP thread accesses stream Stream *s = stream; stream = NULL; s->doExit(); delete s; url = sym__; } else FLEXT_ASSERT(url == sym__); }
std::string Convert(const char *txt,const char *var,int &argc,const t_atom *&argv) { FLEXT_ASSERT(txt); std::string ret; for(;;) { if(var) ret.append(txt,var-txt); else { ret.append(txt); break; } char typetag = var[1]; // part of a symbol switch(typetag) { case osc::INT32_TYPE_TAG: { char tmp[10]; int z = (argc--)?GetAInt(*argv++):0; sprintf(tmp,"%i",z); ret += tmp; break; } case osc::CHAR_TYPE_TAG: { Symbol s = (argc--)?GetASymbol(*argv++):NULL; ret += (s?*GetString(s):'\0'); break; } case osc::SYMBOL_TYPE_TAG: case osc::STRING_TYPE_TAG: { Symbol s = (argc--)?GetASymbol(*argv++):NULL; ret += (s?GetString(s):""); break; } case '%': ret += '%'; break; default: post("%s %s - Type tag %s not handled in string",thisName(),GetString(thisTag()),typetag); } if(!typetag) break; // find next one txt = var+2; var = strchr(txt,'%'); } return ret; }
// \note PD sys lock must already be held by caller inline bool Send() const { if(!msg.Ok()) return false; // Empty! const Msg *m = &msg; do { if(m->Send()) { // we should re-enqeue the message... it can't be a real bundle then, only a solo message FLEXT_ASSERT(!m->nxt); return true; } m = m->nxt; } while(m); return false; }
void pybase::UnimportModule() { if(module) { FLEXT_ASSERT(dict && module_obj && module_dict); Py_DECREF(module); // reference count to module is not 0 here, altough probably the last instance was unloaded // Python retains one reference to the module all the time // we don't care module = NULL; dict = NULL; } }
void pybase::thrworker(thr_params *p) { FLEXT_ASSERT(p); pybase *th = (pybase *)p->cl; work_data *w = (work_data *)p->var->_ext; ++th->thrcount; // \todo this should be atomic { ThrLock lock; // call worker th->docall(w->fun,w->args); delete w; } --th->thrcount; // \todo this should be atomic }
void m_bundleopen(int argc,const t_atom *argv) { double t = 0; if(argc--) t += GetAFloat(*argv++); if(argc--) t += GetAFloat(*argv++); osc::uint64 timetag = GetTimetag(t); FLEXT_ASSERT(packet); ++bundle; if(timetag <= 1) // here immediate timetag can also be 0... but do OSC a favor *packet << osc::BeginBundleImmediate; else *packet << osc::BeginBundle(timetag); }
/*! Connect to stream \param s URL of stream */ void m_connect(const t_symbol *s) { m_disconnect(); FLEXT_ASSERT(!stream); url = s; stream = new StreamOGG; stream->debug = debug; stream->setStreamBufSize(strbuf); stream->setStreamBufChunk(strchunk); stream->setStreamBufThresh(strthresh); stream->setWaitGrain(waitgrain); stream->setWaitReconnect(waitreconnect); stream->doInit(GetString(s)); }
void VSTPlugin::Free() { // This should only also in destruction try { if(effect) { FLEXT_ASSERT(!IsEdited()); // shut down plugin Dispatch(effMainsChanged, 0, 0); Dispatch(effClose); } } catch(...) {} FreePlugin(); }
void pybase::GetDir(PyObject *obj,AtomList &lst) { if(obj) { ThrLock lock; PyObject *pvar = PyObject_Dir(obj); if(!pvar) PyErr_Print(); // no method found else { const t_symbol *sym = GetPyArgs(lst,pvar); if(!sym) post("py/pyext - Argument list could not be created"); else FLEXT_ASSERT(sym == sym_list); Py_DECREF(pvar); } } }