Commit b6c03bac authored by thomas's avatar thomas
Browse files

no message


git-svn-id: https://svn.grrrr.org/ext/trunk@392 4d9ac71a-51e6-0310-8455-cad1006bcd31
parent 96b262ae
/* flext - C++ layer for Max/MSP and pd (pure data) externals Copyright (c) 2001,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. */ /*! \file flatom.cpp \brief Definitions for handling the t_atom type and lists thereof. */ #include "flext.h" flext::AtomList::AtomList(int argc,const t_atom *argv): cnt(0),lst(NULL) { operator()(argc,argv); } flext::AtomList::AtomList(const AtomList &a): cnt(0),lst(NULL) { operator =(a); } flext::AtomList::~AtomList() { Clear(); } flext::AtomList &flext::AtomList::Set(int argc,const t_atom *argv,int offs,bool resize) { int ncnt = argc+offs; if(resize && lst && cnt != ncnt) { delete[] lst; lst = NULL; cnt = 0; } if(ncnt) { if(!lst) lst = new t_atom[cnt = ncnt]; if(argv) { for(int i = 0; i < argc; ++i) SetAtom(lst[offs+i],argv[i]); } } return *this; } int flext::AtomList::Get(t_atom *argv,int mxsz) const { int argc = Count(); if(mxsz >= 0 && argc > mxsz) argc = mxsz; for(int i = 0; i < argc; ++i) SetAtom(argv[i],lst[i]); return argc; } flext::AtomList &flext::AtomList::Append(const t_atom &a) { t_atom *nlst = new t_atom[cnt+1]; for(int i = 0; i < cnt; ++i) SetAtom(nlst[i],lst[i]); SetAtom(nlst[cnt],a); if(lst) delete[] lst; lst = nlst; ++cnt; return *this; } flext::AtomList &flext::AtomList::Append(int argc,const t_atom *argv) { if(argc) { t_atom *nlst = new t_atom[cnt+argc]; int i; for(i = 0; i < cnt; ++i) SetAtom(nlst[i],lst[i]); if(argv) for(i = 0; i < argc; ++i) SetAtom(nlst[cnt+i],argv[i]); if(lst) delete[] lst; lst = nlst; cnt += argc; } return *this; } flext::AtomList &flext::AtomList::Prepend(const t_atom &a) { t_atom *nlst = new t_atom[cnt+1]; for(int i = 0; i < cnt; ++i) SetAtom(nlst[i+1],lst[i]); SetAtom(nlst[0],a); if(lst) delete[] lst; lst = nlst; ++cnt; return *this; } flext::AtomList &flext::AtomList::Prepend(int argc,const t_atom *argv) { if(argc) { t_atom *nlst = new t_atom[cnt+argc]; int i; if(argv) for(i = 0; i < argc; ++i) SetAtom(nlst[i],argv[i]); for(i = 0; i < cnt; ++i) SetAtom(nlst[argc+i],lst[i]); if(lst) delete[] lst; lst = nlst; cnt += argc; } return *this; } flext::AtomList flext::AtomList::GetPart(int offs,int len) const { if(offs+len > Count()) { len = Count()-offs; if(len < 0) len = 0; } return AtomList(len,Atoms()+offs); } flext::AtomAnything::AtomAnything(const t_symbol *h,int argc,const t_atom *argv): AtomList(argc,argv),hdr(h?h:MakeSymbol("")) {} flext::AtomAnything::AtomAnything(const char *h,int argc,const t_atom *argv): AtomList(argc,argv),hdr(MakeSymbol(h)) {} flext::AtomAnything::AtomAnything(const AtomAnything &a): AtomList(a),hdr(a.hdr) {}
\ No newline at end of file
/*
flext - C++ layer for Max/MSP and pd (pure data) externals
Copyright (c) 2001,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.
*/
/*! \file flatom.cpp
\brief Definitions for handling the t_atom type and lists thereof.
*/
#include "flext.h"
flext::AtomList::AtomList(int argc,const t_atom *argv):
cnt(0),lst(NULL)
{
operator()(argc,argv);
}
flext::AtomList::AtomList(const AtomList &a):
cnt(0),lst(NULL)
{
operator =(a);
}
flext::AtomList::~AtomList() { Clear(); }
flext::AtomList &flext::AtomList::Set(int argc,const t_atom *argv,int offs,bool resize)
{
int ncnt = argc+offs;
if(resize && lst && cnt != ncnt) { delete[] lst; lst = NULL; cnt = 0; }
if(ncnt) {
if(!lst) lst = new t_atom[cnt = ncnt];
if(argv) {
for(int i = 0; i < argc; ++i) SetAtom(lst[offs+i],argv[i]);
}
}
return *this;
}
int flext::AtomList::Get(t_atom *argv,int mxsz) const
{
int argc = Count();
if(mxsz >= 0 && argc > mxsz) argc = mxsz;
for(int i = 0; i < argc; ++i) SetAtom(argv[i],lst[i]);
return argc;
}
flext::AtomList &flext::AtomList::Append(const t_atom &a)
{
t_atom *nlst = new t_atom[cnt+1];
for(int i = 0; i < cnt; ++i) SetAtom(nlst[i],lst[i]);
SetAtom(nlst[cnt],a);
if(lst) delete[] lst;
lst = nlst;
++cnt;
return *this;
}
flext::AtomList &flext::AtomList::Append(int argc,const t_atom *argv)
{
if(argc) {
t_atom *nlst = new t_atom[cnt+argc];
int i;
for(i = 0; i < cnt; ++i) SetAtom(nlst[i],lst[i]);
if(argv)
for(i = 0; i < argc; ++i) SetAtom(nlst[cnt+i],argv[i]);
if(lst) delete[] lst;
lst = nlst;
cnt += argc;
}
return *this;
}
flext::AtomList &flext::AtomList::Prepend(const t_atom &a)
{
t_atom *nlst = new t_atom[cnt+1];
for(int i = 0; i < cnt; ++i) SetAtom(nlst[i+1],lst[i]);
SetAtom(nlst[0],a);
if(lst) delete[] lst;
lst = nlst;
++cnt;
return *this;
}
flext::AtomList &flext::AtomList::Prepend(int argc,const t_atom *argv)
{
if(argc) {
t_atom *nlst = new t_atom[cnt+argc];
int i;
if(argv)
for(i = 0; i < argc; ++i) SetAtom(nlst[i],argv[i]);
for(i = 0; i < cnt; ++i) SetAtom(nlst[argc+i],lst[i]);
if(lst) delete[] lst;
lst = nlst;
cnt += argc;
}
return *this;
}
flext::AtomList flext::AtomList::GetPart(int offs,int len) const
{
if(offs+len > Count()) {
len = Count()-offs;
if(len < 0) len = 0;
}
return AtomList(len,Atoms()+offs);
}
flext::AtomAnything::AtomAnything(const t_symbol *h,int argc,const t_atom *argv):
AtomList(argc,argv),hdr(h?h:MakeSymbol(""))
{}
flext::AtomAnything::AtomAnything(const char *h,int argc,const t_atom *argv):
AtomList(argc,argv),hdr(MakeSymbol(h))
{}
flext::AtomAnything::AtomAnything(const AtomAnything &a):
AtomList(a),hdr(a.hdr)
{}
/* flext - C++ layer for Max/MSP and pd (pure data) externals Copyright (c) 2001,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. */ /*! \file flatom_pr.cpp \brief Definitions for printing and scanning the t_atom type. */ #include "flext.h" #include <ctype.h> #include <stdlib.h> #include <string.h> #include <stdio.h> #ifdef __MWERKS__ #define STD std #else #define STD #endif void flext::PrintAtom(const t_atom &a,char *buf) { switch(a.a_type) { case A_NULL: break; case A_FLOAT: #ifdef PD if(a.a_w.w_float == (int)a.a_w.w_float) STD::sprintf(buf,"%i",(int)GetFloat(a)); else #endif STD::sprintf(buf,"%f",GetFloat(a)); break; #ifdef MAXMSP case A_LONG: STD::sprintf(buf,"%i",GetInt(a)); break; #endif #ifdef PD case A_POINTER: STD::sprintf(buf,"%x",GetPointer(a)); break; #endif case A_SYMBOL: strcpy(buf,GetString(a)); break; #ifdef _DEBUG default: ERRINTERNAL(); #endif } } bool flext::ScanAtom(t_atom &a,const char *buf) { // skip whitespace while(*buf && isspace(*buf)) ++buf; if(!*buf) return false; char tmp[1024]; strcpy(tmp,buf); char *c = tmp; // check for word type (s = 0,1,2 ... int,float,symbol) int s = 0; for(; *c && !isspace(*c); ++c) { if(!isdigit(*c)) s = (*c != '.' || s == 1)?2:1; } switch(s) { case 0: // integer #ifdef MAXMSP SetInt(a,atol(tmp)); break; #endif case 1: // float SetFloat(a,(float)atof(tmp)); break; default: { // anything else is a symbol char t = *c; *c = 0; SetString(a,tmp); *c = t; break; } } return true; }
\ No newline at end of file
/*
flext - C++ layer for Max/MSP and pd (pure data) externals
Copyright (c) 2001,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.
*/
/*! \file flatom_pr.cpp
\brief Definitions for printing and scanning the t_atom type.
*/
#include "flext.h"
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#ifdef __MWERKS__
#define STD std
#else
#define STD
#endif
void flext::PrintAtom(const t_atom &a,char *buf)
{
switch(a.a_type) {
case A_NULL:
break;
case A_FLOAT:
#ifdef PD
if(a.a_w.w_float == (int)a.a_w.w_float)
STD::sprintf(buf,"%i",(int)GetFloat(a));
else
#endif
STD::sprintf(buf,"%f",GetFloat(a));
break;
#ifdef MAXMSP
case A_LONG:
STD::sprintf(buf,"%i",GetInt(a));
break;
#endif
#ifdef PD
case A_POINTER:
STD::sprintf(buf,"%x",GetPointer(a));
break;
#endif
case A_SYMBOL:
strcpy(buf,GetString(a));
break;
#ifdef _DEBUG
default:
ERRINTERNAL();
#endif
}
}
bool flext::ScanAtom(t_atom &a,const char *buf)
{
// skip whitespace
while(*buf && isspace(*buf)) ++buf;
if(!*buf) return false;
char tmp[1024];
strcpy(tmp,buf);
char *c = tmp;
// check for word type (s = 0,1,2 ... int,float,symbol)
int s = 0;
for(; *c && !isspace(*c); ++c) {
if(!isdigit(*c))
s = (*c != '.' || s == 1)?2:1;
}
switch(s) {
case 0: // integer
#ifdef MAXMSP
SetInt(a,atol(tmp));
break;
#endif
case 1: // float
SetFloat(a,(float)atof(tmp));
break;
default: { // anything else is a symbol
char t = *c; *c = 0;
SetString(a,tmp);
*c = t;
break;
}
}
return true;
}
/* flext - C++ layer for Max/MSP and pd (pure data) externals Copyright (c) 2001,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. */ /*! \file flattr.cpp \brief Attribute handling for the flext base class */ #include "flext.h" #include <string.h> #ifdef MAXMSP #define STD std #else #define STD #endif flext_base::attritem::attritem(const t_symbol *t,const t_symbol *gt,metharg tp,methfun gf,methfun sf): tag(t),gtag(gt),argtp(tp),gfun(gf),sfun(sf),nxt(NULL) {} flext_base::attritem::~attritem() { if(nxt) delete nxt; } void flext_base::AddAttrItem(attritem *m) { if(attrhead) { attritem *mi; for(mi = attrhead; mi->nxt; mi = mi->nxt) {} mi->nxt = m; } else attrhead = m; attrcnt++; } void flext_base::AddAttrib(const char *attr,metharg tp,methfun gfun,methfun sfun) { if(procattr) { char tmp[256] = "get"; strcpy(tmp+3,attr); AddAttrItem(new attritem(MakeSymbol(attr),MakeSymbol(tmp),tp,gfun,sfun)); AddMethod(0,attr,(methfun)cb_SetAttrib,a_any,a_null); AddMethod(0,tmp,(methfun)cb_GetAttrib,a_any,a_null); } else error("%s - attribute procession is not enabled!",thisName()); } int flext_base::CheckAttrib(int argc,const t_atom *argv) { int offs = 0; for(; offs < argc; ++offs) if(IsString(argv[offs]) && *GetString(argv[offs]) == '@') break; return offs; } bool flext_base::InitAttrib(int argc,const t_atom *argv) { int cur,nxt; for(cur = 0; cur < argc; cur = nxt) { // find next @symbol for(nxt = cur+1; nxt < argc; ++nxt) if(IsString(argv[nxt]) && *GetString(argv[nxt]) == '@') break; const t_symbol *tag = MakeSymbol(GetString(argv[cur])+1); SetAttrib(tag,nxt-cur-1,argv+cur+1); } return true; } bool flext_base::ListAttrib() { if(outattr) { AtomList la(attrcnt); attritem *a = attrhead; for(int i = 0; i < attrcnt; ++i,a = a->nxt) SetSymbol(la[i],a->tag); ToOutAnything(outattr,MakeSymbol("attributes"),la.Count(),la.Atoms()); return true; } else return false; } bool flext_base::SetAttrib(const t_symbol *tag,int argc,const t_atom *argv) { attritem *a = attrhead; for(; a && a->tag != tag; a = a->nxt) {} if(a) { if(a->sfun) { bool ok = true; AtomList la; t_any any; switch(a->argtp) { case a_float: if(argc == 1 && CanbeFloat(argv[0])) { any.ft = GetAFloat(argv[0]); ((methfun_1)a->sfun)(this,any); } else ok = false; break; case a_int: if(argc == 1 && CanbeInt(argv[0])) { any.it = GetAInt(argv[0]); ((methfun_1)a->sfun)(this,any); } else ok = false; break; case a_symbol: if(argc == 1 && IsSymbol(argv[0])) { any.st = GetSymbol(argv[0]); ((methfun_1)a->sfun)(this,any); } else ok = false; break; case a_LIST: any.vt = &(la(argc,argv)); ((methfun_1)a->sfun)(this,any); break; default: ERRINTERNAL(); } if(!ok) post("%s - wrong arguments for attribute %s",thisName(),GetString(tag)); } else post("%s - attribute %s has no get method",thisName(),GetString(tag)); } else error("%s - %s: attribute not found",thisName(),GetString(tag)); return true; } bool flext_base::GetAttrib(const t_symbol *tag,int argc,const t_atom *argv) { if(argc) post("%s - %s: arguments ignored",thisName(),GetString(tag)); attritem *a = attrhead; for(; a && a->gtag != tag; a = a->nxt) {} if(a) { if(a->gfun) { AtomList la; t_any any; switch(a->argtp) { case a_float: { ((methfun_1)a->gfun)(this,any); la(1); SetFloat(la[0],any.ft); break; } case a_int: { ((methfun_1)a->gfun)(this,any); la(1); SetInt(la[0],any.it); break; } case a_symbol: { ((methfun_1)a->gfun)(this,any); la(1); SetSymbol(la[0],any.st); break; } case a_LIST: { any.vt = &la; ((methfun_1)a->gfun)(this,any); break; } default: ERRINTERNAL(); } ToOutAnything(outattr,a->tag,la.Count(),la.Atoms()); } else post("%s - attribute %s has no set method",thisName(),GetString(tag)); } else error("%s - %s: attribute not found",thisName(),GetString(tag)); return true; }
\ No newline at end of file
/*
flext - C++ layer for Max/MSP and pd (pure data) externals
Copyright (c) 2001,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.
*/
/*! \file flattr.cpp
\brief Attribute handling for the flext base class
*/
#include "flext.h"
#include <string.h>
#ifdef MAXMSP
#define STD std
#else
#define STD
#endif
flext_base::attritem::attritem(const t_symbol *t,const t_symbol *gt,metharg tp,methfun gf,methfun sf):
tag(t),gtag(gt),argtp(tp),gfun(gf),sfun(sf),nxt(NULL)
{}
flext_base::attritem::~attritem()
{
if(nxt) delete nxt;
}
void flext_base::AddAttrItem(attritem *m)
{
if(attrhead) {
attritem *mi;
for(mi = attrhead; mi->nxt; mi = mi->nxt) {}
mi->nxt = m;
}
else
attrhead = m;
attrcnt++;
}
void flext_base::AddAttrib(const char *attr,metharg tp,methfun gfun,methfun sfun)
{
if(procattr) {
char tmp[256] = "get";
strcpy(tmp+3,attr);
AddAttrItem(new attritem(MakeSymbol(attr),MakeSymbol(tmp),tp,gfun,sfun));
AddMethod(0,attr,(methfun)cb_SetAttrib,a_any,a_null);
AddMethod(0,tmp,(methfun)cb_GetAttrib,a_any,a_null);
}
else
error("%s - attribute procession is not enabled!",thisName());
}
int flext_base::CheckAttrib(int argc,const t_atom *argv)
{
int offs = 0;
for(; offs < argc; ++offs)
if(IsString(argv[offs]) && *GetString(argv[offs]) == '@') break;
return offs;
}
bool flext_base::InitAttrib(int argc,const t_atom *argv)
{
int cur,nxt;
for(cur = 0; cur < argc; cur = nxt) {
// find next @symbol
for(nxt = cur+1; nxt < argc; ++nxt)
if(IsString(argv[nxt]) && *GetString(argv[nxt]) == '@') break;
const t_symbol *tag = MakeSymbol(GetString(argv[cur])+1);
SetAttrib(tag,nxt-cur-1,argv+cur+1);
}
return true;
}
bool flext_base::ListAttrib()
{
if(outattr) {
AtomList la(attrcnt);
attritem *a = attrhead;
for(int i = 0; i < attrcnt; ++i,a = a->nxt) SetSymbol(la[i],a->tag);
ToOutAnything(outattr,MakeSymbol("attributes"),la.Count(),la.Atoms());
return true;
}
else
return false;
}
bool flext_base::SetAttrib(const t_symbol *tag,int argc,const t_atom *argv)
{
attritem *a = attrhead;
for(; a && a->tag != tag; a = a->nxt) {}
if(a) {
if(a->sfun) {
bool ok = true;
AtomList la;
t_any any;
switch(a->argtp) {
case a_float:
if(argc == 1 && CanbeFloat(argv[0])) {
any.ft = GetAFloat(argv[0]);
((methfun_1)a->sfun)(this,any);
}
else ok = false;
break;
case a_int:
if(argc == 1 && CanbeInt(argv[0])) {
any.it = GetAInt(argv[0]);
((methfun_1)a->sfun)(this,any);
}
else ok = false;
break;
case a_symbol:
if(argc == 1 && IsSymbol(argv[0])) {
any.st = GetSymbol(argv[0]);
((methfun_1)a->sfun)(this,any);
}
else ok = false;
break;
case a_LIST:
any.vt = &(la(argc,argv));
((methfun_1)a->sfun)(this,any);
break;
default:
ERRINTERNAL();
}
if(!ok)
post("%s - wrong arguments for attribute %s",thisName(),GetString(tag));
}
else
post("%s - attribute %s has no get method",thisName(),GetString(tag));
}
else
error("%s - %s: attribute not found",thisName(),GetString(tag));
return true;
}
bool flext_base::GetAttrib(const t_symbol *tag,int argc,const t_atom *argv)
{
if(argc)
post("%s - %s: arguments ignored",thisName(),GetString(tag));
attritem *a = attrhead;
for(; a && a->gtag != tag; a = a->nxt) {}
if(a) {
if(a->gfun) {
AtomList la;
t_any any;
switch(a->argtp) {
case a_float: {
((methfun_1)a->gfun)(this,any);
la(1);
SetFloat(la[0],any.ft);
break;
}
case a_int: {
((methfun_1)a->gfun)(this,any);
la(1);
SetInt(la[0],any.it);
break;
}
case a_symbol: {
((methfun_1)a->gfun)(this,any);
la(1);
SetSymbol(la[0],any.st);
break;
}
case a_LIST: {
any.vt = &la;
((methfun_1)a->gfun)(this,any);
break;
}
default:
ERRINTERNAL();
}
ToOutAnything(outattr,a->tag,la.Count(),la.Atoms());
}
else
post("%s - attribute %s has no set method",thisName(),GetString(tag));
}
else
error("%s - %s: attribute not found",thisName(),GetString(tag));
return true;
}
/* flext - C++ layer for Max/MSP and pd (pure data) externals Copyright (c) 2001,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. */ /*! \file flbase.cpp \brief Implementation of the internal flext base classes. \remark This is all derived from GEM by Mark Danks */ #include "flbase.h" #include "flinternal.h" #include <string.h> ///////////////////////////////////////////////////////// // // flext_obj // ///////////////////////////////////////////////////////// flext_hdr *flext_obj::m_holder = NULL; const t_symbol *flext_obj::m_holdname = NULL; bool flext_obj::m_holdattr = false; int flext_obj::m_holdaargc = 0; const t_atom *flext_obj::m_holdaargv = NULL; bool flext_obj::process_attributes = false; ///////////////////////////////////////////////////////// // Constructor // ///////////////////////////////////////////////////////// flext_obj :: flext_obj() : x_obj(m_holder) , m_name(m_holdname) , procattr(m_holdattr) , init_ok(true) { #ifdef PD m_canvas = canvas_getcurrent(); #elif defined(MAXMSP) m_canvas = (t_patcher *)gensym("#P")->s_thing; x_obj->curinlet = 0; #endif } ///////////////////////////////////////////////////////// // Destructor // ///////////////////////////////////////////////////////// flext_obj :: ~flext_obj() {} void flext_obj::DefineHelp(t_class *c,const char *ref,const char *dir,bool addtilde) { #ifdef PD char tmp[256]; if(dir) { strcpy(tmp,dir); strcat(tmp,"/"); strcat(tmp,ref); if(addtilde) strcat(tmp,"~"); } else strcpy(tmp,ref); ::class_sethelpsymbol(c,gensym(const_cast<char *>(tmp))); #else // no solution for MaxMSP yet #endif } ///////////////////////////////////////////////////////// // overloaded new/delete memory allocation methods // ///////////////////////////////////////////////////////// void *flext_obj::operator new(size_t bytes) { bytes += sizeof(size_t); char *blk = (char *)getbytes(bytes); *(size_t *)blk = bytes; return blk+sizeof(size_t); } void flext_obj::operator delete(void *blk) { char *ori = (char *)blk-sizeof(size_t); size_t bytes = *(size_t *)ori; freebytes(ori,bytes); } void *flext_obj::NewAligned(size_t bytes,int bitalign) { const size_t ovh = sizeof(size_t)+sizeof(char *); const unsigned long alignovh = bitalign/8-1; bytes += ovh+alignovh; char *blk = (char *)getbytes(bytes); char *ablk = reinterpret_cast<char *>((reinterpret_cast<unsigned long>(blk)+ovh+alignovh) & ~alignovh); *(char **)(ablk-sizeof(size_t)-sizeof(char *)) = blk; *(size_t *)(ablk-sizeof(size_t)) = bytes; return ablk; } void flext_obj::FreeAligned(void *blk) { char *ori = *(char **)((char *)blk-sizeof(size_t)-sizeof(char *)); size_t bytes = *(size_t *)((char *)blk-sizeof(size_t)); freebytes(ori,bytes); }
\ No newline at end of file
/*
flext - C++ layer for Max/MSP and pd (pure data) externals
Copyright (c) 2001,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.
*/
/*! \file flbase.cpp
\brief Implementation of the internal flext base classes.
\remark This is all derived from GEM by Mark Danks
*/
#include "flbase.h"
#include "flinternal.h"
#include <string.h>
/////////////////////////////////////////////////////////
//
// flext_obj
//
/////////////////////////////////////////////////////////
flext_hdr *flext_obj::m_holder = NULL;
const t_symbol *flext_obj::m_holdname = NULL;
bool flext_obj::m_holdattr = false;
int flext_obj::m_holdaargc = 0;
const t_atom *flext_obj::m_holdaargv = NULL;
bool flext_obj::process_attributes = false;
/////////////////////////////////////////////////////////
// Constructor
//
/////////////////////////////////////////////////////////
flext_obj :: flext_obj()
: x_obj(m_holder)
, m_name(m_holdname)
, procattr(m_holdattr)
, init_ok(true)
{
#ifdef PD
m_canvas = canvas_getcurrent();
#elif defined(MAXMSP)
m_canvas = (t_patcher *)gensym("#P")->s_thing;
x_obj->curinlet = 0;
#endif
}
/////////////////////////////////////////////////////////
// Destructor
//
/////////////////////////////////////////////////////////
flext_obj :: ~flext_obj() {}
void flext_obj::DefineHelp(t_class *c,const char *ref,const char *dir,bool addtilde)
{
#ifdef PD
char tmp[256];
if(dir) {
strcpy(tmp,dir);
strcat(tmp,"/");
strcat(tmp,ref);
if(addtilde) strcat(tmp,"~");
}
else
strcpy(tmp,ref);
::class_sethelpsymbol(c,gensym(const_cast<char *>(tmp)));
#else
// no solution for MaxMSP yet
#endif
}
/////////////////////////////////////////////////////////
// overloaded new/delete memory allocation methods
//
/////////////////////////////////////////////////////////
void *flext_obj::operator new(size_t bytes)
{
bytes += sizeof(size_t);
char *blk = (char *)getbytes(bytes);
*(size_t *)blk = bytes;
return blk+sizeof(size_t);
}
void flext_obj::operator delete(void *blk)
{
char *ori = (char *)blk-sizeof(size_t);
size_t bytes = *(size_t *)ori;
freebytes(ori,bytes);
}
void *flext_obj::NewAligned(size_t bytes,int bitalign)
{
const size_t ovh = sizeof(size_t)+sizeof(char *);
const unsigned long alignovh = bitalign/8-1;
bytes += ovh+alignovh;
char *blk = (char *)getbytes(bytes);
char *ablk = reinterpret_cast<char *>((reinterpret_cast<unsigned long>(blk)+ovh+alignovh) & ~alignovh);
*(char **)(ablk-sizeof(size_t)-sizeof(char *)) = blk;
*(size_t *)(ablk-sizeof(size_t)) = bytes;
return ablk;
}
void flext_obj::FreeAligned(void *blk)
{
char *ori = *(char **)((char *)blk-sizeof(size_t)-sizeof(char *));
size_t bytes = *(size_t *)((char *)blk-sizeof(size_t));
freebytes(ori,bytes);
}
/* flext - C++ layer for Max/MSP and pd (pure data) externals Copyright (c) 2001,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. */ /*! \file flbuf.cpp \brief Implementation of the buffer abstraction class. */ #include "flext.h" #ifdef MAXMSP #include "flmspbuffer.h" // include inofficial buffer.h #endif #ifdef PD #define DIRTY_INTERVAL 0 // buffer dirty check in msec #endif flext::buffer::buffer(const t_symbol *bn,bool delayed): sym(NULL),data(NULL), chns(0),frames(0) { #ifdef PD arr = NULL; interval = DIRTY_INTERVAL; isdirty = false; ticking = false; tick = clock_new(this,(t_method)cb_tick); #endif if(bn) Set(bn,delayed); } flext::buffer::~buffer() { #ifdef PD clock_free(tick); #endif } int flext::buffer::Set(const t_symbol *s,bool nameonly) { int ret = 0; bool valid = data != NULL; // valid now? (before change) if(s && sym != s) { ret = -1; data = NULL; frames = 0; chns = 0; } if(s && *s->s_name) sym = s; if(!sym) { if(valid) ret = -1; } else if(!nameonly) { #ifdef PD int frames1; t_sample *data1; arr = (t_garray *)pd_findbyclass(const_cast<t_symbol *>(sym), garray_class); if(!arr) { if (*sym->s_name) error("buffer: no such array '%s'",sym->s_name); sym = NULL; if(valid) ret = -1; } else if(!garray_getfloatarray(arr, &frames1, &data1)) { error("buffer: bad template '%s'", sym->s_name); data = NULL; frames = 0; if(valid) ret = -1; } else { garray_usedindsp(arr); if(frames != frames1) { frames = frames1; if(!ret) ret = 1; } if(data != data1) { data = data1; if(!ret) ret = 1; } chns = 1; } #elif defined(MAXMSP) if(sym->s_thing) { const _buffer *p = (const _buffer *)sym->s_thing; if(NOGOOD(p)) { post("buffer: buffer object '%s' no good",sym->s_name); if(valid) ret = -1; } else { #ifdef DEBUG post("%s: buffer object '%s' - valid:%i samples:%i channels:%i frames:%i",thisName(),bufname->s_name,p->b_valid,p->b_frames,p->b_nchans,p->b_frames); #endif if(data != p->b_samples) { data = p->b_samples; if(!ret) ret = 1; } if(chns != p->b_nchans) { chns = p->b_nchans; if(!ret) ret = 1; } if(frames != p->b_frames) { frames = p->b_frames; if(!ret) ret = 1; } } } else { error("buffer: symbol '%s' not defined", sym->s_name); if(valid) ret = -1; } #endif } return ret; } bool flext::buffer::Update() { if(!Ok()) return false; #ifdef PD int frames1; t_sample *data1; if(!garray_getfloatarray(arr, &frames1, &data1)) { frames = 0; data = NULL; chns = 0; return true; } else if(data != data1 || frames != frames1) { frames = frames1; data = data1; return true; } else return false; #else // MAXMSP if(!sym->s_thing) return false; else { const _buffer *p = (const _buffer *)sym->s_thing; if(data != p->b_samples || chns != p->b_nchans || frames != p->b_frames) { data = p->b_samples; chns = p->b_nchans; frames = p->b_frames; return true; } else return false; } #endif } void flext::buffer::Frames(int fr,bool keep) { #ifdef PD ::garray_resize(arr,(float)fr); Update(); #else t_sample *tmp = NULL; int sz = frames; if(fr < sz) sz = fr; if(keep) { // copy buffer data to tmp storage tmp = new t_sample[sz]; if(tmp) BlockMoveData(data,tmp,sizeof(t_sample)*sz); else error("flext::buffer - not enough memory for keeping buffer~ contents"); } t_atom msg; _buffer *buf = (_buffer *)sym->s_thing; // b_msr reflects buffer sample rate... is this what we want? // Max bug: adding small value 0.001 to get right sample count float ms = fr/buf->b_msr+0.001; SetFloat(msg,ms); ::typedmess((object *)buf,gensym("size"),1,&msg); Update(); if(tmp) { // copy data back BlockMoveData(tmp,data,sizeof(t_sample)*sz); delete[] tmp; } #endif } #ifdef PD void flext::buffer::SetRefrIntv(float intv) { interval = intv; if(interval == 0 && ticking) { clock_unset(tick); ticking = false; } } #else void flext::buffer::SetRefrIntv(float) {} #endif void flext::buffer::Dirty(bool force) { if(sym) { #ifdef PD if((!ticking) && (interval || force)) { ticking = true; cb_tick(this); // immediately redraw } else { if(force) clock_delay(tick,0); isdirty = true; } #elif defined(MAXMSP) if(sym->s_thing) { _buffer *p = (_buffer *)sym->s_thing; if(NOGOOD(p)) { post("buffer: buffer object '%s' no good",sym->s_name); } else { p->b_modtime = gettime(); } } else { error("buffer: symbol '%s' not defined",sym->s_name); } #endif } } #ifdef PD void flext::buffer::cb_tick(buffer *b) { if(b->arr) garray_redraw(b->arr); #ifdef _DEBUG else error("buffer: array is NULL"); #endif if(b->isdirty && b->interval) { b->isdirty = false; b->ticking = true; clock_delay(b->tick,b->interval); } else b->ticking = false; } #endif
\ No newline at end of file
/*
flext - C++ layer for Max/MSP and pd (pure data) externals
Copyright (c) 2001,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.
*/
/*! \file flbuf.cpp
\brief Implementation of the buffer abstraction class.
*/
#include "flext.h"
#ifdef MAXMSP
#include "flmspbuffer.h" // include inofficial buffer.h
#endif
#ifdef PD
#define DIRTY_INTERVAL 0 // buffer dirty check in msec
#endif
flext::buffer::buffer(const t_symbol *bn,bool delayed):
sym(NULL),data(NULL),
chns(0),frames(0)
{
#ifdef PD
arr = NULL;
interval = DIRTY_INTERVAL;
isdirty = false;
ticking = false;
tick = clock_new(this,(t_method)cb_tick);
#endif
if(bn) Set(bn,delayed);
}
flext::buffer::~buffer()