From 91c0003b158e5f0ed9d0677fb136ae8bb6f86ec5 Mon Sep 17 00:00:00 2001 From: "N.N." Date: Mon, 28 Apr 2008 18:10:15 +0000 Subject: this is an old gridflow, and there's already a svn repository at http://gridflow.ca/svn/trunk svn path=/trunk/; revision=9739 --- externals/gridflow/base/grid.c | 616 ----------------------------------------- 1 file changed, 616 deletions(-) delete mode 100644 externals/gridflow/base/grid.c (limited to 'externals/gridflow/base/grid.c') diff --git a/externals/gridflow/base/grid.c b/externals/gridflow/base/grid.c deleted file mode 100644 index c3ec5932..00000000 --- a/externals/gridflow/base/grid.c +++ /dev/null @@ -1,616 +0,0 @@ -/* - $Id: grid.c,v 1.2 2006-03-15 04:37:08 matju Exp $ - - GridFlow - Copyright (c) 2001,2002,2003,2004 by Mathieu Bouchard - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - See file ../COPYING for further informations on licensing terms. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include "grid.h.fcs" -#include - -/* copied from bridge/puredata.c (sorry: linkage issue) */ -struct Pointer : CObject { - void *p; - Pointer(void *_p) : p(_p) {} -}; - -#define Pointer_s_new Pointer_s_new_2 -#define Pointer_get Pointer_get_2 - -static Ruby Pointer_s_new (void *ptr) { - Pointer *self = new Pointer(ptr); - Ruby rself = Data_Wrap_Struct(EVAL("GridFlow::Pointer"), 0, CObject_free, self); - self->rself = rself; - return rself; -} -static void *Pointer_get (Ruby rself) { - DGS(Pointer); - return self->p; -} - -//#define TRACE fprintf(stderr,"%s %s [%s:%d]\n",INFO(parent),__PRETTY_FUNCTION__,__FILE__,__LINE__);assert(this); -#define TRACE assert(this); - -#define CHECK_TYPE(d) \ - if (NumberTypeE_type_of(d)!=this->nt) RAISE("%s(%s): " \ - "type mismatch during transmission (got %s expecting %s)", \ - INFO(parent), __PRETTY_FUNCTION__, \ - number_type_table[NumberTypeE_type_of(d)].name, \ - number_type_table[this->nt].name); - -#define CHECK_BUSY(s) \ - if (!dim) RAISE("%s: " #s " not busy",INFO(parent)); - -#define CHECK_ALIGN(d) \ - {int bytes = number_type_table[nt].size/8; \ - int align = ((long)(void*)d)%bytes; \ - if (align) {L;gfpost("%s(%s): Alignment Warning: %p is not %d-aligned: %d", \ - INFO(parent), __PRETTY_FUNCTION__, (void*)d,bytes,align);}} - -#define CHECK_ALIGN2(d,nt) \ - {int bytes = number_type_table[nt].size/8; \ - int align = ((long)(void*)d)%bytes; \ - if (align) {L;gfpost("Alignment Warning: %p is not %d-aligned: %d", \ - (void*)d,bytes,align);}} - -// **************** Grid ****************************************** - -#define FOO(S) static inline void NUM(Ruby x, S &y) {y=convert(x,(int32*)0);} -EACH_INT_TYPE(FOO) -#undef FOO - -#define FOO(S) \ -static inline void NUM(Ruby x, S &y) { \ - if (TYPE(x)==T_FLOAT) y = RFLOAT(x)->value; \ - else if (INTEGER_P(x)) y = convert(x,(S*)0); \ - else RAISE("expected Float (or at least Integer)");} -EACH_FLOAT_TYPE(FOO) -#undef FOO - -static inline void NUM(Ruby x, ruby &y) { y.r=x; } - -void Grid::init_from_ruby_list(int n, Ruby *a, NumberTypeE nt) { - Ruby delim = SYM(#); - for (int i=0; idata,nt); - if (a[i] != delim) i++; - i++; a+=i; n-=i; - goto fill; - } - } - if (n!=0 && TYPE(a[0])==T_SYMBOL) { - nt = NumberTypeE_find(a[0]); - a++, n--; - } - init(new Dim(n),nt); - CHECK_ALIGN2(this->data,nt); - fill: - int nn = dim->prod(); - n = min(n,nn); -#define FOO(type) { \ - Pt p = (Pt)*this; \ - if (n==0) CLEAR(p,nn); \ - else { \ - for (int i=0; idata,nt); - ((Pt)*this)[0] = INT(x); - } else { - rb_funcall( - EVAL("proc{|x| raise \"can't convert to grid: #{x.inspect}\"}"), - SI(call),1,x); - } -} - -// **************** GridInlet ************************************* - -// must be set before the end of GRID_BEGIN phase, and so cannot be changed -// afterwards. This is to allow some optimisations. Anyway there is no good reason -// why this would be changed afterwards. -void GridInlet::set_factor(int factor) { - if(!dim) RAISE("huh?"); - if(factor<=0) RAISE("%s: factor=%d should be >= 1",INFO(parent),factor); - if (dim->prod() && dim->prod() % factor) - RAISE("%s: set_factor: expecting divisor",INFO(parent)); - if (factor > 1) { - buf=new Grid(new Dim(factor), nt); - bufi=0; - } else { - buf=0; - } -} - -static Ruby GridInlet_begin_1(GridInlet *self) { -#define FOO(T) self->gh->flow(self,-1,Pt()); break; - TYPESWITCH(self->nt,FOO,) -#undef FOO - return Qnil; -} - -static Ruby GridInlet_begin_2(GridInlet *self) { - self->dim = 0; // hack - return (Ruby) 0; -} - -bool GridInlet::supports_type(NumberTypeE nt) { -#define FOO(T) return !! gh->flow_##T; - TYPESWITCH(nt,FOO,return false) -#undef FOO -} - -Ruby GridInlet::begin(int argc, Ruby *argv) {TRACE; - if (!argc) return PTR2FIX(this); - GridOutlet *back_out = (GridOutlet *) Pointer_get(argv[0]); - nt = (NumberTypeE) INT(argv[1]); - argc-=2, argv+=2; - PROF(parent) { - if (dim) RAISE("%s: grid inlet conflict; aborting %s in favour of %s", - INFO(parent), INFO(sender), INFO(back_out->parent)); - sender = back_out->parent; - if ((int)nt<0 || (int)nt>=(int)number_type_table_end) - RAISE("%s: inlet: unknown number type",INFO(parent)); - if (!supports_type(nt)) - RAISE("%s: number type %s not supported here", - INFO(parent), number_type_table[nt].name); - STACK_ARRAY(int32,v,argc); - for (int i=0; i dim = this->dim = new Dim(argc,v); - dex=0; - buf=0; - int r = rb_ensure( - (RMethod)GridInlet_begin_1,(Ruby)this, - (RMethod)GridInlet_begin_2,(Ruby)this); - if (!r) {abort(); goto hell;} - this->dim = dim; - back_out->callback(this); - hell:;} // PROF - return Qnil; -} - -template void GridInlet::flow(int mode, int n, Pt data) {TRACE; - CHECK_BUSY(inlet); - CHECK_TYPE(*data); - CHECK_ALIGN(data); - PROF(parent) { - if (this->mode==0) {dex += n; return;} // ignore data - if (n==0) return; // no data - switch(mode) { - case 4:{ - int d = dex + bufi; - if (d+n > dim->prod()) { - gfpost("grid input overflow: %d of %d from [%s] to [%s]", - d+n, dim->prod(), INFO(sender), 0); - n = dim->prod() - d; - if (n<=0) return; - } - int bufn = factor(); - if (buf && bufi) { - Pt bufd = (Pt)*buf; - int k = min(n,bufn-bufi); - COPY(bufd+bufi,data,k); - bufi+=k; data+=k; n-=k; - if (bufi==bufn) { - int newdex = dex+bufn; - if (this->mode==6) { - Pt data2 = ARRAY_NEW(T,bufn); - COPY(data2,bufd,bufn); - CHECK_ALIGN(data2); - gh->flow(this,bufn,data2); - } else { - CHECK_ALIGN(bufd); - gh->flow(this,bufn,bufd); - } - dex = newdex; - bufi = 0; - } - } - int m = (n/bufn)*bufn; - if (m) { - int newdex = dex + m; - if (this->mode==6) { - Pt data2 = ARRAY_NEW(T,m); - COPY(data2,data,m); - CHECK_ALIGN(data2); - gh->flow(this,m,data2); - } else { - gh->flow(this,m,data); - } - dex = newdex; - } - data += m; - n -= m; - if (buf && n>0) COPY((Pt)*buf+bufi,data,n), bufi+=n; - }break; - case 6:{ - assert(!buf); - int newdex = dex + n; - gh->flow(this,n,data); - if (this->mode==4) delete[] (T *)data; - dex = newdex; - }break; - case 0: break; // ignore data - default: RAISE("%s: unknown inlet mode",INFO(parent)); - }} // PROF -} - -void GridInlet::end() {TRACE; - assert(this); - if (!dim) RAISE("%s: inlet not busy",INFO(parent)); - if (dim->prod() != dex) { - gfpost("incomplete grid: %d of %d from [%s] to [%s]", - dex, dim->prod(), INFO(sender), INFO(parent)); - } - PROF(parent) { -#define FOO(T) gh->flow(this,-2,Pt()); - TYPESWITCH(nt,FOO,) -#undef FOO - } // PROF - dim=0; - buf=0; - dex=0; -} - -template void GridInlet::from_grid2(Grid *g, T foo) {TRACE; - nt = g->nt; - dim = g->dim; - int n = g->dim->prod(); - gh->flow(this,-1,Pt()); - if (n>0 && this->mode!=0) { - Pt data = (Pt)*g; - CHECK_ALIGN(data); - int size = g->dim->prod(); - if (this->mode==6) { - Pt d = data; - data = ARRAY_NEW(T,size); // problem with int64,float64 here. - COPY(data,d,size); - CHECK_ALIGN(data); - gh->flow(this,n,data); - } else { - int ntsz = number_type_table[nt].size; - int m = GridOutlet::MAX_PACKET_SIZE/*/ntsz*//factor(); - if (!m) m++; - m *= factor(); - while (n) { - if (m>n) m=n; - CHECK_ALIGN(data); - gh->flow(this,m,data); - data+=m; n-=m; dex+=m; - } - } - } - gh->flow(this,-2,Pt()); - //!@#$ add error handling. - // rescue; abort(); end ??? - dim = 0; - dex = 0; -} - -void GridInlet::from_grid(Grid *g) {TRACE; - if (!supports_type(g->nt)) - RAISE("%s: number type %s not supported here", - INFO(parent), number_type_table[g->nt].name); -#define FOO(T) from_grid2(g,(T)0); - TYPESWITCH(g->nt,FOO,) -#undef FOO -} - -/* **************** GridOutlet ************************************ */ - -void GridOutlet::begin(int woutlet, P dim, NumberTypeE nt) {TRACE; - int n = dim->count(); - this->nt = nt; - this->dim = dim; - Ruby a[n+4]; - a[0] = INT2NUM(woutlet); - a[1] = bsym._grid; - a[2] = Pointer_s_new(this); - a[3] = INT2NUM(nt); - for(int i=0; iget(i)); - parent->send_out(COUNT(a),a); - frozen=true; - if (!dim->prod()) {end(); return;} - int32 lcm_factor = 1; - for (uint32 i=0; ifactor()); - if (nt != buf->nt) { - // biggest packet size divisible by lcm_factor - int32 v = (MAX_PACKET_SIZE/lcm_factor)*lcm_factor; - if (v==0) v=MAX_PACKET_SIZE; // factor too big. don't have a choice. - buf=new Grid(new Dim(v),nt); - } -} - -// send modifies dex; send_direct doesn't -template -void GridOutlet::send_direct(int n, Pt data) {TRACE; - assert(data); assert(frozen); - CHECK_BUSY(outlet); CHECK_TYPE(*data); CHECK_ALIGN(data); - for (; n>0; ) { - int pn = min(n,MAX_PACKET_SIZE); - for (uint32 i=0; iflow(4,pn,data); - data+=pn, n-=pn; - } -} - -void GridOutlet::flush() {TRACE; - if (!bufi) return; -#define FOO(T) send_direct(bufi,(Pt)*buf); - TYPESWITCH(buf->nt,FOO,) -#undef FOO - bufi = 0; -} - -template -static void convert_number_type(int n, Pt out, Pt in) { - for (int i=0; i -void GridOutlet::send(int n, Pt data) {TRACE; - assert(data); assert(frozen); - if (!n) return; - CHECK_BUSY(outlet); CHECK_ALIGN(data); - if (NumberTypeE_type_of(*data)!=nt) { - int bs = MAX_PACKET_SIZE; -#define FOO(T) { \ - STACK_ARRAY(T,data2,bs); \ - for (;n>=bs;n-=bs,data+=bs) { \ - convert_number_type(bs,data2,data); send(bs,data2);} \ - convert_number_type(n,data2,data); \ - send(n,data2); } - TYPESWITCH(nt,FOO,) -#undef FOO - } else { - dex += n; - assert(dex <= dim->prod()); - if (n > MIN_PACKET_SIZE || bufi + n > MAX_PACKET_SIZE) flush(); - if (n > MIN_PACKET_SIZE) { - send_direct(n,data); - } else { - COPY((Pt)*buf+bufi,data,n); - bufi += n; - } - if (dex==dim->prod()) end(); - } -} - -template -void GridOutlet::give(int n, Pt data) {TRACE; - assert(data); CHECK_BUSY(outlet); assert(frozen); - assert(dex+n <= dim->prod()); CHECK_ALIGN(data); - if (NumberTypeE_type_of(*data)!=nt) { - send(n,data); - delete[] (T *)data; - return; - } - if (inlets.size()==1 && inlets[0]->mode == 6) { - // this is the copyless buffer passing - flush(); - inlets[0]->flow(6,n,data); - dex += n; - } else { - flush(); - send_direct(n,data); - dex += n; - delete[] (T *)data; - } - if (dex==dim->prod()) end(); -} - -void GridOutlet::callback(GridInlet *in) {TRACE; - CHECK_BUSY(outlet); assert(!frozen); - int mode = in->mode; - assert(mode==6 || mode==4 || mode==0); - inlets.push_back(in); -} - -\class GridObject < FObject - -//!@#$ does not handle types properly -//!@#$ most possibly a big hack -template -void GridObject_r_flow(GridInlet *in, int n, Pt data) { - GridObject *self = in->parent; - uint32 i; - for (i=0; iin.size(); i++) if (in==self->in[i].p) break; - if (i==self->in.size()) RAISE("inlet not found?"); - if (n==-1) { - rb_funcall(self->rself,SI(send_in),2,INT2NUM(i),SYM(rgrid_begin)); - } else if (n>=0) { - Ruby buf = rb_str_new((char *)((uint8 *)data),n*sizeof(T)); - rb_funcall(self->rself,SI(send_in),3,INT2NUM(i),SYM(rgrid_flow),buf); - } else { - rb_funcall(self->rself,SI(send_in),2,INT2NUM(i),SYM(rgrid_end)); - } -} - -\def Symbol inlet_nt (int inln) { - if (inln<0 || inln>=(int)in.size()) RAISE("bad inlet number"); - P inl = in[inln]; - if (!inl) RAISE("no such inlet #%d",inln); - if (!inl->dim) return Qnil; - return number_type_table[inl->nt].sym; -} - -\def Array inlet_dim (int inln) { - if (inln<0 || inln>=(int)in.size()) RAISE("bad inlet number"); - P inl = in[inln]; - if (!inl) RAISE("no such inlet #%d",inln); - if (!inl->dim) return Qnil; - int n=inl->dim->count(); - Ruby a = rb_ary_new2(n); - for(int i=0; idim->v[i])); - return a; -} - -\def void inlet_set_factor (int inln, int factor) { - if (inln<0 || inln>=(int)in.size()) RAISE("bad inlet number"); - P inl = in[inln]; - if (!inl) RAISE("no such inlet #%d",inln); - if (!inl->dim) RAISE("inlet #%d not active",inln); - inl->set_factor(factor); -} - -\def void send_out_grid_begin (int outlet, Array buf, NumberTypeE nt=int32_e) { - if (outlet<0) RAISE("bad outlet number"); - int n = rb_ary_len(buf); - Ruby *p = rb_ary_ptr(buf); - STACK_ARRAY(int32,v,n); - for (int i=0; i -void send_out_grid_flow_2(P go, Ruby s, T bogus) { - int n = rb_str_len(s) / sizeof(T); - Pt p = rb_str_pt(s,T); - go->send(n,p); -} - -\def void send_out_grid_flow (int outlet, String buf, NumberTypeE nt=int32_e) { - if (outlet<0) RAISE("bad outlet number"); -#define FOO(T) send_out_grid_flow_2(out,argv[1],(T)0); - TYPESWITCH(nt,FOO,) -#undef FOO -} - -// install_rgrid(Integer inlet, Boolean multi_type? = true) -static Ruby GridObject_s_install_rgrid(int argc, Ruby *argv, Ruby rself) { - if (argc<1 || argc>2) RAISE("er..."); - IEVAL(rself,"@handlers||=[]"); - Ruby handlers = rb_ivar_get(rself,SI(@handlers)); - GridHandler *gh = new GridHandler; - bool mt = argc>1 ? argv[1]==Qtrue : 0; /* multi_type? */ - if (mt) { -#define FOO(S) gh->flow_##S = GridObject_r_flow; -EACH_NUMBER_TYPE(FOO) -#undef FOO - } else { -#define FOO(S) gh->flow_##S = 0; -EACH_NUMBER_TYPE(FOO) -#undef FOO - } - gh->flow_int32 = GridObject_r_flow; - //IEVAL(rself,"self.class_eval { def _0_grid(*a) ___grid(0,*a) end }"); - rb_funcall(handlers,SI([]=),2,INT2NUM(INT(argv[0])),PTR2FIX(gh)); - return Qnil; -} - -static Ruby GridObject_s_instance_methods(int argc, Ruby *argv, Ruby rself) { - static const char *names[] = {"grid","list","float"}; - Ruby list = rb_class_instance_methods(argc,argv,rself); - Ruby handlers = rb_ivar_get(rself,SI(@handlers)); - if (handlers==Qnil) return list; - for (int i=0; i=rb_ary_len(handlers)) RAISE("BORK"); - GridHandler *gh = FIX2PTR(GridHandler, rb_ary_ptr(handlers)[i]); - if (in.size()<=(uint32)i) in.resize(i+1); - if (!in[i]) in[i]=new GridInlet((GridObject *)this,gh); - return in[i]->begin(argc-1,argv+1); - } - // we call the grid method recursively to ask it its GridInlet* - // don't do this before checking the missing method is exactly that =) - char foo[42]; - sprintf(foo,"_%d_grid",i); - P inl = FIX2PTR(GridInlet,rb_funcall(rself,rb_intern(foo),0)); - if (strcmp(endp,"list" )==0) return inl->from_ruby_list(argc-1,argv+1), Qnil; - if (strcmp(endp,"float")==0) return inl->from_ruby (argc-1,argv+1), Qnil; - } - hell: return rb_call_super(argc,argv); -} - -\classinfo { - IEVAL(rself,"install 'GridObject',0,0"); - // define in Ruby-metaclass - rb_define_singleton_method(rself,"instance_methods",(RMethod)GridObject_s_instance_methods,-1); - rb_define_singleton_method(rself,"install_rgrid",(RMethod)GridObject_s_install_rgrid,-1); - rb_enable_super(rb_singleton_class(rself),"instance_methods"); -} -\end class GridObject - -Ruby cGridObject; - -void startup_grid () { - \startall - cGridObject = rb_const_get(mGridFlow,SI(GridObject)); -} - -// never call this. this is a hack to make some things work. -// i'm trying to circumvent either a bug in the compiler or i don't have a clue. :-( -void make_gimmick () { - GridOutlet foo(0,0,0); -#define FOO(S) foo.give(0,Pt()); -EACH_NUMBER_TYPE(FOO) -#undef FOO -} - -- cgit v1.2.1