aboutsummaryrefslogtreecommitdiff
path: root/externals/gridflow/base
diff options
context:
space:
mode:
Diffstat (limited to 'externals/gridflow/base')
-rw-r--r--externals/gridflow/base/bitpacking.c313
-rw-r--r--externals/gridflow/base/flow_objects.c1195
-rw-r--r--externals/gridflow/base/flow_objects.rb1457
-rw-r--r--externals/gridflow/base/flow_objects_for_image.c619
-rw-r--r--externals/gridflow/base/flow_objects_for_matrix.c77
-rw-r--r--externals/gridflow/base/grid.c616
-rw-r--r--externals/gridflow/base/grid.h1146
-rw-r--r--externals/gridflow/base/main.c648
-rw-r--r--externals/gridflow/base/main.rb384
-rw-r--r--externals/gridflow/base/number.c374
-rw-r--r--externals/gridflow/base/source_filter.rb276
-rw-r--r--externals/gridflow/base/test.rb1074
12 files changed, 0 insertions, 8179 deletions
diff --git a/externals/gridflow/base/bitpacking.c b/externals/gridflow/base/bitpacking.c
deleted file mode 100644
index cb09a812..00000000
--- a/externals/gridflow/base/bitpacking.c
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- $Id: bitpacking.c,v 1.2 2006-03-15 04:37:06 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 "grid.h.fcs"
-#include <math.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-//#define CONVERT0(z) (((in[z] << hb[z]) >> 7) & mask[z])
-#define CONVERT0(z) ((in[z] >> chop[z]) << slide[z])
-
-#define CONVERT1 t = \
- CONVERT0(0) | CONVERT0(1) | CONVERT0(2)
-
-#define CONVERT2 \
- for (t=0,i=0; i<self->size; i++) t |= CONVERT0(i);
-
-#define CONVERT3 \
- for (t=0,i=0; i<self->size; i++) \
- t |= (((unsigned)in[i]>>(7-hb[i]))|(in[i]<<(hb[i]-7))) & mask[i];
-
-#define WRITE_LE \
- for (int bytes = self->bytes; bytes; bytes--, t>>=8) *out++ = t;
-
-#define WRITE_BE { int bytes; \
- bytes = self->bytes; \
- while (bytes--) { out[bytes] = t; t>>=8; }\
- out += self->bytes; }
-
-/* this macro would be faster if the _increment_
- was done only once every loop. or maybe gcc does it, i dunno */
-#define NTIMES(_x_) \
- for (; n>=4; n-=4) { _x_ _x_ _x_ _x_ } \
- for (; n; n--) { _x_ }
-
-/* this could be faster (use asm) */
-void swap32 (int n, Pt<uint32> data) {
- NTIMES({
- uint32 x = *data;
- x = (x<<16) | (x>>16);
- x = ((x&0xff00ff)<<8) | ((x>>8)&0xff00ff);
- *data++ = x;
- })
-}
-
-/* this could be faster (use asm or do it in int32 chunks) */
-void swap16 (int n, Pt<uint16> data) {
- NTIMES({ uint16 x = *data; *data++ = (x<<8) | (x>>8); })
-}
-
-/* **************************************************************** */
-
-template <class T>
-static void default_pack(BitPacking *self, int n, Pt<T> in, Pt<uint8> out) {
- uint32 t;
- int i;
- int sameorder = self->endian==2 || self->endian==::is_le();
- int size = self->size;
- uint32 mask[4]; memcpy(mask,self->mask,size*sizeof(uint32));
- uint32 hb[4]; for (i=0; i<size; i++) hb[i] = highest_bit(mask[i]);
- uint32 span[4]; for (i=0; i<size; i++) span[i] = hb[i] - lowest_bit(mask[i]);
- uint32 chop[4]; for (i=0; i<size; i++) chop[i] = 7-span[i];
- uint32 slide[4]; for (i=0; i<size; i++) slide[i] = hb[i]-span[i];
-
- if (sameorder && size==3) {
- switch(self->bytes) {
- case 2: NTIMES(CONVERT1; *((int16 *)out)=t; out+=2; in+=3;) return;
- case 4: NTIMES(CONVERT1; *((int32 *)out)=t; out+=4; in+=3;) return;
- }
- }
- if (self->is_le()) {
- switch (size) {
- case 3: for (; n--; in+=3) {CONVERT1; WRITE_LE;} break;
- case 4: for (; n--; in+=4) {CONVERT1; WRITE_LE;} break;
- default:for (; n--; in+=size) {CONVERT2; WRITE_LE;}}
- } else {
- switch (size) {
- case 3: for (; n--; in+=3) {CONVERT1; WRITE_BE;} break;
- case 4: for (; n--; in+=4) {CONVERT1; WRITE_BE;} break;
- default:for (; n--; in+=size) {CONVERT2; WRITE_BE;}}
- }
-}
-
-#define LOOP_UNPACK(_reader_) \
- for (; n; n--) { \
- int bytes=0; uint32 temp=0; _reader_; \
- for (int i=0; i<self->size; i++, out++) { \
- uint32 t=temp&self->mask[i]; \
- *out = (t<<(7-hb[i]))|(t>>(hb[i]-7)); \
- } \
- }
-// *out++ = ((temp & self->mask[i]) << 7) >> hb[i];
-
-template <class T>
-static void default_unpack(BitPacking *self, int n, Pt<uint8> in, Pt<T> out) {
- int hb[4];
- for (int i=0; i<self->size; i++) hb[i] = highest_bit(self->mask[i]);
- if (is_le()) { // smallest byte first
- LOOP_UNPACK(
- for(; self->bytes>bytes; bytes++, in++) temp |= *in<<(8*bytes);
- )
- } else { // biggest byte first
- LOOP_UNPACK(
- bytes=self->bytes; for (; bytes; bytes--, in++) temp=(temp<<8)|*in;
- )
- }
-}
-
-/* **************************************************************** */
-
-template <class T>
-static void pack2_565(BitPacking *self, int n, Pt<T> in, Pt<uint8> out) {
- const int hb[3] = {15,10,4};
- const uint32 mask[3] = {0x0000f800,0x000007e0,0x0000001f};
- uint32 span[3] = {4,5,4};
- uint32 chop[3] = {3,2,3};
- uint32 slide[3] = {11,5,0};
- uint32 t;
- NTIMES(CONVERT1; *((short *)out)=t; out+=2; in+=3;)
-}
-
-template <class T>
-static void pack3_888(BitPacking *self, int n, Pt<T> in, Pt<uint8> out) {
- Pt<int32> o32 = (Pt<int32>)out;
- while (n>=4) {
- o32[0] = (in[5]<<24) | (in[ 0]<<16) | (in[ 1]<<8) | in[2];
- o32[1] = (in[7]<<24) | (in[ 8]<<16) | (in[ 3]<<8) | in[4];
- o32[2] = (in[9]<<24) | (in[10]<<16) | (in[11]<<8) | in[6];
- o32+=3; in+=12;
- n-=4;
- }
- out = (Pt<uint8>)o32;
- NTIMES( out[2]=in[0]; out[1]=in[1]; out[0]=in[2]; out+=3; in+=3; )
-}
-
-/*
-template <>
-static void pack3_888(BitPacking *self, int n, Pt<uint8> in, Pt<uint8> out) {
- Pt<uint32> o32 = Pt<uint32>((uint32 *)out.p,n*3/4);
- Pt<uint32> i32 = Pt<uint32>((uint32 *)in.p,n*3/4);
- while (n>=4) {
-#define Z(w,i) ((word##w>>(i*8))&255)
- uint32 word0 = i32[0];
- uint32 word1 = i32[1];
- uint32 word2 = i32[2];
- o32[0] = (Z(1,1)<<24) | (Z(0,0)<<16) | (Z(0,1)<<8) | Z(0,2);
- o32[1] = (Z(1,3)<<24) | (Z(2,0)<<16) | (Z(0,3)<<8) | Z(1,0);
- o32[2] = (Z(2,1)<<24) | (Z(2,2)<<16) | (Z(2,3)<<8) | Z(1,2);
- o32+=3; i32+=3;
- n-=4;
- }
-#undef Z
- out = (Pt<uint8>)o32;
- in = (Pt<uint8>)i32;
- NTIMES( out[2]=in[0]; out[1]=in[1]; out[0]=in[2]; out+=3; in+=3; )
-}
-*/
-
-template <class T>
-static void pack3_888b(BitPacking *self, int n, Pt<T> in, Pt<uint8> out) {
- Pt<int32> o32 = (Pt<int32>)out;
- while (n>=4) {
- o32[0] = (in[0]<<16) | (in[1]<<8) | in[2];
- o32[1] = (in[3]<<16) | (in[4]<<8) | in[5];
- o32[2] = (in[6]<<16) | (in[7]<<8) | in[8];
- o32[3] = (in[9]<<16) | (in[10]<<8) | in[11];
- o32+=4; in+=12;
- n-=4;
- }
- NTIMES( o32[0] = (in[0]<<16) | (in[1]<<8) | in[2]; o32++; in+=3; )
-}
-
-// (R,G,B,?) -> B:8,G:8,R:8,0:8
-// fishy
-template <class T>
-static void pack3_bgrn8888(BitPacking *self, int n, Pt<T> in, Pt<uint8> out) {
-/* NTIMES( out[2]=in[0]; out[1]=in[1]; out[0]=in[2]; out+=4; in+=4; ) */
- Pt<int32> i32 = (Pt<int32>)in;
- Pt<int32> o32 = (Pt<int32>)out;
- while (n>=4) {
- o32[0] = ((i32[0]&0xff)<<16) | (i32[0]&0xff00) | ((i32[0]>>16)&0xff);
- o32[1] = ((i32[1]&0xff)<<16) | (i32[1]&0xff00) | ((i32[1]>>16)&0xff);
- o32[2] = ((i32[2]&0xff)<<16) | (i32[2]&0xff00) | ((i32[2]>>16)&0xff);
- o32[3] = ((i32[3]&0xff)<<16) | (i32[3]&0xff00) | ((i32[3]>>16)&0xff);
- o32+=4; i32+=4; n-=4;
- }
- NTIMES( o32[0] = ((i32[0]&0xff)<<16) | (i32[0]&0xff00) | ((i32[0]>>16)&0xff); o32++; i32++; )
-}
-
-static uint32 bp_masks[][4] = {
- {0x0000f800,0x000007e0,0x0000001f,0},
- {0x00ff0000,0x0000ff00,0x000000ff,0},
-};
-
-static Packer bp_packers[] = {
- {default_pack, default_pack, default_pack},
- {pack2_565, pack2_565, pack2_565},
- {pack3_888, pack3_888, pack3_888},
- {pack3_888b, default_pack, default_pack},
- {pack3_bgrn8888, default_pack, default_pack},
-};
-
-static Unpacker bp_unpackers[] = {
- {default_unpack, default_unpack, default_unpack},
-};
-
-static BitPacking builtin_bitpackers[] = {
- BitPacking(2, 2, 3, bp_masks[0], &bp_packers[1], &bp_unpackers[0]),
- BitPacking(1, 3, 3, bp_masks[1], &bp_packers[2], &bp_unpackers[0]),
- BitPacking(1, 4, 3, bp_masks[1], &bp_packers[3], &bp_unpackers[0]),
- BitPacking(1, 4, 4, bp_masks[1], &bp_packers[4], &bp_unpackers[0]),
-};
-
-/* **************************************************************** */
-
-bool BitPacking::eq(BitPacking *o) {
- if (!(bytes == o->bytes)) return false;
- if (!(size == o->size)) return false;
- for (int i=0; i<size; i++) {
- if (!(mask[i] == o->mask[i])) return false;
- }
- if (endian==o->endian) return true;
- /* same==little on a little-endian; same==big on a big-endian */
- return (endian ^ o->endian ^ ::is_le()) == 2;
-}
-
-BitPacking::BitPacking(int endian, int bytes, int size, uint32 *mask,
-Packer *packer, Unpacker *unpacker) {
- this->endian = endian;
- this->bytes = bytes;
- this->size = size;
- for (int i=0; i<size; i++) this->mask[i] = mask[i];
- if (packer) {
- this->packer = packer;
- this->unpacker = unpacker;
- return;
- }
- int packeri=-1;
- this->packer = &bp_packers[0];
- this->unpacker = &bp_unpackers[0];
-
- for (int i=0; i<(int)(sizeof(builtin_bitpackers)/sizeof(BitPacking)); i++) {
- BitPacking *bp = &builtin_bitpackers[i];
- if (this->eq(bp)) {
- this->packer = bp->packer;
- this->unpacker = bp->unpacker;
- packeri=i;
- goto end;
- }
- }
-end:;
-/*
- ::gfpost("Bitpacking: endian=%d bytes=%d size=%d packeri=%d",
- endian, bytes, size, packeri);
- ::gfpost(" packer=0x%08x unpacker=0x%08x",this->packer,this->unpacker);
- ::gfpost(" mask=[0x%08x,0x%08x,0x%08x,0x%08x]",mask[0],mask[1],mask[2],mask[3]);
-*/
-}
-
-bool BitPacking::is_le() {
- return endian==1 || (endian ^ ::is_le())==3;
-}
-
-template <class T>
-void BitPacking::pack(int n, Pt<T> in, Pt<uint8> out) {
- switch (NumberTypeE_type_of(*in)) {
- case uint8_e: packer->as_uint8(this,n,(Pt<uint8>)in,out); break;
- case int16_e: packer->as_int16(this,n,(Pt<int16>)in,out); break;
- case int32_e: packer->as_int32(this,n,(Pt<int32>)in,out); break;
- default: RAISE("argh");
- }
-}
-
-template <class T>
-void BitPacking::unpack(int n, Pt<uint8> in, Pt<T> out) {
- switch (NumberTypeE_type_of(*out)) {
- case uint8_e: unpacker->as_uint8(this,n,in,(Pt<uint8>)out); break;
- case int16_e: unpacker->as_int16(this,n,in,(Pt<int16>)out); break;
- case int32_e: unpacker->as_int32(this,n,in,(Pt<int32>)out); break;
- default: RAISE("argh");
- }
-}
-
-// i'm sorry... see the end of grid.c for an explanation...
-//static
-void make_hocus_pocus () {
-// exit(1);
-#define FOO(S) \
- ((BitPacking*)0)->pack(0,Pt<S>(),Pt<uint8>()); \
- ((BitPacking*)0)->unpack(0,Pt<uint8>(),Pt<S>());
-EACH_NUMBER_TYPE(FOO)
-#undef FOO
-}
diff --git a/externals/gridflow/base/flow_objects.c b/externals/gridflow/base/flow_objects.c
deleted file mode 100644
index f971553d..00000000
--- a/externals/gridflow/base/flow_objects.c
+++ /dev/null
@@ -1,1195 +0,0 @@
-/*
- $Id: flow_objects.c,v 1.2 2006-03-15 04:37:08 matju Exp $
-
- GridFlow
- Copyright (c) 2001,2002,2003,2004,2005 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 <sys/time.h>
-#include <stdlib.h>
-#include <math.h>
-#include "grid.h.fcs"
-
-// BAD HACK: GCC complains: unimplemented (--debug|--debug-harder mode only)
-#ifdef HAVE_DEBUG
-#define SCOPY(a,b,n) COPY(a,b,n)
-#else
-#define SCOPY(a,b,n) SCopy<n>::f(a,b)
-#endif
-
-template <int n> class SCopy {
-public: template <class T> static inline void __attribute__((always_inline)) f(Pt<T> a, Pt<T> b) {
- *a=*b; SCopy<n-1>::f(a+1,b+1);}};
-template <> class SCopy<0> {
-public: template <class T> static inline void __attribute__((always_inline)) f(Pt<T> a, Pt<T> b) {}};
-
-/*template <> class SCopy<4> {
-public: template <class T>
- static inline void __attribute__((always_inline)) f(Pt<T> a, Pt<T> b) {
- *a=*b; SCopy<3>::f(a+1,b+1);}
- // wouldn't gcc 2.95 complain here?
- static inline void __attribute__((always_inline)) f(Pt<uint8> a, Pt<uint8> b)
- { *(int32 *)a=*(int32 *)b; }
-};*/
-
-Numop *op_add, *op_sub, *op_mul, *op_div, *op_mod, *op_shl, *op_and, *op_put;
-
-static void expect_dim_dim_list (P<Dim> d) {
- if (d->n!=1) RAISE("dimension list should be Dim[n], not %s",d->to_s());}
-//static void expect_min_one_dim (P<Dim> d) {
-// if (d->n<1) RAISE("minimum 1 dimension");}
-static void expect_max_one_dim (P<Dim> d) {
- if (d->n>1) { RAISE("expecting Dim[] or Dim[n], got %s",d->to_s()); }}
-//static void expect_exactly_one_dim (P<Dim> d) {
-// if (d->n!=1) { RAISE("expecting Dim[n], got %s",d->to_s()); }}
-
-//****************************************************************
-\class GridCast < GridObject
-struct GridCast : GridObject {
- \attr NumberTypeE nt;
- \decl void initialize (NumberTypeE nt);
- \grin 0
-};
-
-GRID_INLET(GridCast,0) {
- out = new GridOutlet(this,0,in->dim,nt);
-} GRID_FLOW {
- out->send(n,data);
-} GRID_END
-
-\def void initialize (NumberTypeE nt) {
- rb_call_super(argc,argv);
- this->nt = nt;
-}
-
-\classinfo { IEVAL(rself,"install '#cast',1,1"); }
-\end class GridCast
-
-//****************************************************************
-//{ ?,Dim[B] -> Dim[*Cs] }
-// out0 nt to be specified explicitly
-\class GridImport < GridObject
-struct GridImport : GridObject {
- \attr NumberTypeE cast;
- \attr P<Dim> dim; // size of grids to send
- PtrGrid dim_grid;
- GridImport() { dim_grid.constrain(expect_dim_dim_list); }
- ~GridImport() {}
- \decl void initialize(Ruby x, NumberTypeE cast=int32_e);
- \decl void _0_cast(NumberTypeE cast);
- \decl void _0_reset();
- \decl void _0_symbol(Symbol x);
- \decl void _0_list(...);
- \decl void _1_per_message();
- \grin 0
- \grin 1 int32
- template <class T> void process (int n, Pt<T> data) {
- while (n) {
- if (!out || !out->dim) out = new GridOutlet(this,0,dim?dim:in[0]->dim,cast);
- int32 n2 = min((int32)n,out->dim->prod()-out->dex);
- out->send(n2,data);
- n-=n2; data+=n2;
- }
- }
-};
-
-GRID_INLET(GridImport,0) {} GRID_FLOW { process(n,data); } GRID_END
-GRID_INPUT(GridImport,1,dim_grid) { dim = dim_grid->to_dim(); } GRID_END
-
-\def void _0_symbol(Symbol x) {
- const char *name = rb_sym_name(argv[0]);
- int n = strlen(name);
- if (!dim) out=new GridOutlet(this,0,new Dim(n));
- process(n,Pt<uint8>((uint8 *)name,n));
-}
-
-\def void _0_cast(NumberTypeE cast) { this->cast = cast; }
-
-\def void _0_list(...) {
- if (in.size()<1 || !in[0]) _0_grid(0,0); //HACK: enable grid inlet...
- in[0]->from_ruby_list(argc,argv,cast);
-}
-
-\def void _1_per_message() { dim=0; dim_grid=0; }
-
-\def void initialize(Ruby x, NumberTypeE cast) {
- rb_call_super(argc,argv);
- this->cast = cast;
- if (argv[0]!=SYM(per_message)) {
- dim_grid=new Grid(argv[0]);
- dim = dim_grid->to_dim();
- }
-}
-
-\def void _0_reset() {
- STACK_ARRAY(int32,foo,1); *foo=0;
- while (out->dim) out->send(1,foo);
-}
-
-\classinfo { IEVAL(rself,"install '#import',2,1"); }
-\end class GridImport
-
-//****************************************************************
-/*{ Dim[*As] -> ? }*/
-/* in0: integer nt */
-\class GridExport < GridObject
-struct GridExport : GridObject {
- \grin 0
-};
-
-template <class T>
-static Ruby INTORFLOAT2NUM(T value) {return INT2NUM(value);}
-static Ruby INTORFLOAT2NUM(int64 value) {return gf_ll2num(value);}
-static Ruby INTORFLOAT2NUM(float32 value) {return rb_float_new(value);}
-static Ruby INTORFLOAT2NUM(float64 value) {return rb_float_new(value);}
-static Ruby INTORFLOAT2NUM(ruby value) {return value.r;}
-
-GRID_INLET(GridExport,0) {
-} GRID_FLOW {
- for (int i=0; i<n; i++) {
- Ruby a[] = { INT2NUM(0), INTORFLOAT2NUM(data[i]) };
- send_out(COUNT(a),a);
- }
-} GRID_END
-\classinfo { IEVAL(rself,"install '#export',1,1"); }
-\end class GridExport
-
-/* **************************************************************** */
-/*{ Dim[*As] -> ? }*/
-/* in0: integer nt */
-\class GridExportList < GridObject
-struct GridExportList : GridObject {
- Ruby /*Array*/ list;
- int n;
- \grin 0
-};
-
-GRID_INLET(GridExportList,0) {
- int n = in->dim->prod();
- if (n>250000) RAISE("list too big (%d elements)", n);
- list = rb_ary_new2(n+2);
- this->n = n;
- rb_ivar_set(rself,SI(@list),list); // keep
- rb_ary_store(list,0,INT2NUM(0));
- rb_ary_store(list,1,bsym._list);
-} GRID_FLOW {
- for (int i=0; i<n; i++, data++)
- rb_ary_store(list,in->dex+i+2,INTORFLOAT2NUM(*data));
-} GRID_FINISH {
- send_out(rb_ary_len(list),rb_ary_ptr(list));
- list = 0;
- rb_ivar_set(rself,SI(@list),Qnil); // unkeep
-} GRID_END
-
-\classinfo { IEVAL(rself,"install '#export_list',1,1"); }
-\end class GridExportList
-
-/* **************************************************************** */
-// GridStore ("@store") is the class for storing a grid and restituting
-// it on demand. The right inlet receives the grid. The left inlet receives
-// either a bang (which forwards the whole image) or a grid describing what
-// to send.
-//{ Dim[*As,B],Dim[*Cs,*Ds] -> Dim[*As,*Ds] }
-// in0: integer nt
-// in1: whatever nt
-// out0: same nt as in1
-\class GridStore < GridObject
-struct GridStore : GridObject {
- PtrGrid r; // can't be \attr
- PtrGrid put_at; // can't be //\attr
- \attr Numop *op;
- int32 wdex [Dim::MAX_DIM]; // temporary buffer, copy of put_at
- int32 fromb[Dim::MAX_DIM];
- int32 to2 [Dim::MAX_DIM];
- int lsd; // lsd = Last Same Dimension (for put_at)
- int d; // goes with wdex
- \decl void initialize (Grid *r=0);
- \decl void _0_bang ();
- \decl void _0_op (Numop *op);
- \decl void _1_reassign ();
- \decl void _1_put_at (Grid *index);
- \grin 0 int
- \grin 1
- GridStore() { put_at.constrain(expect_max_one_dim); }
- template <class T> void compute_indices(Pt<T> v, int nc, int nd);
-};
-
-// takes the backstore of a grid and puts it back into place. a backstore
-// is a grid that is filled while the grid it would replace has not
-// finished being used.
-static void snap_backstore (PtrGrid &r) {
- if (r.next) {r=r.next.p; r.next=0;}
-}
-
-template <class T> void GridStore::compute_indices(Pt<T> v, int nc, int nd) {
- for (int i=0; i<nc; i++) {
- uint32 wrap = r->dim->v[i];
- bool fast = lowest_bit(wrap)==highest_bit(wrap); // is power of two?
- if (i) {
- if (fast) op_shl->map(nd,v,(T)highest_bit(wrap));
- else op_mul->map(nd,v,(T)wrap);
- }
- if (fast) op_and->map(nd,v+nd*i,(T)(wrap-1));
- else op_mod->map(nd,v+nd*i,(T)(wrap));
- if (i) op_add->zip(nd,v,v+nd*i);
- }
-}
-
-// !@#$ i should ensure that n is not exceedingly large
-// !@#$ worse: the size of the foo buffer may still be too large
-GRID_INLET(GridStore,0) {
- // snap_backstore must be done before *anything* else
- snap_backstore(r);
- int na = in->dim->n;
- int nb = r->dim->n;
- int nc = in->dim->get(na-1);
- STACK_ARRAY(int32,v,Dim::MAX_DIM);
- if (na<1) RAISE("must have at least 1 dimension.",na,1,1+nb);
- int lastindexable = r->dim->prod()/r->dim->prod(nc) - 1;
- int ngreatest = nt_greatest((T *)0);
- if (lastindexable > ngreatest) {
- RAISE("lastindexable=%d > ngreatest=%d (ask matju)",lastindexable,ngreatest);
- }
- if (nc > nb)
- RAISE("wrong number of elements in last dimension: "
- "got %d, expecting <= %d", nc, nb);
- int nd = nb - nc + na - 1;
- COPY(v,in->dim->v,na-1);
- COPY(v+na-1,r->dim->v+nc,nb-nc);
- out=new GridOutlet(this,0,new Dim(nd,v),r->nt);
- if (nc>0) in->set_factor(nc);
-} GRID_FLOW {
- int na = in->dim->n;
- int nc = in->dim->get(na-1);
- int size = r->dim->prod(nc);
- assert((n % nc) == 0);
- int nd = n/nc;
- STACK_ARRAY(T,w,n);
- Pt<T> v=w;
- if (sizeof(T)==1 && nc==1 && r->dim->v[0]<=256) {
- // bug? shouldn't modulo be done here?
- v=data;
- } else {
- COPY(v,data,n);
- for (int k=0,i=0; i<nc; i++) for (int j=0; j<n; j+=nc) v[k++] = data[i+j];
- compute_indices(v,nc,nd);
- }
-#define FOO(type) { \
- Pt<type> p = (Pt<type>)*r; \
- if (size<=16) { \
- Pt<type> foo = ARRAY_NEW(type,nd*size); \
- int i=0; \
- switch (size) { \
- case 1: for (; i<nd&-4; i+=4, foo+=4) { \
- foo[0] = p[v[i+0]]; \
- foo[1] = p[v[i+1]]; \
- foo[2] = p[v[i+2]]; \
- foo[3] = p[v[i+3]]; \
- } break; \
- case 2: for (; i<nd; i++, foo+=2) SCOPY(foo,p+2*v[i],2); break; \
- case 3: for (; i<nd; i++, foo+=3) SCOPY(foo,p+3*v[i],3); break; \
- case 4: for (; i<nd; i++, foo+=4) SCOPY(foo,p+4*v[i],4); break; \
- default:; }; \
- for (; i<nd; i++, foo+=size) COPY(foo,p+size*v[i],size); \
- out->give(size*nd,foo-size*nd); \
- } else { \
- for (int i=0; i<nd; i++) out->send(size,p+size*v[i]); \
- } \
-}
- TYPESWITCH(r->nt,FOO,)
-#undef FOO
-} GRID_FINISH {
- if (in->dim->prod()==0) {
- int n = in->dim->prod(0,-2);
- int size = r->dim->prod();
-#define FOO(T) while (n--) out->send(size,(Pt<T>)*r);
- TYPESWITCH(r->nt,FOO,)
-#undef FOO
- }
-} GRID_END
-
-GRID_INLET(GridStore,1) {
- NumberTypeE nt = NumberTypeE_type_of(*data);
- if (!put_at) { // reassign
- if (in[0].dim)
- r.next = new Grid(in->dim,nt);
- else
- r = new Grid(in->dim,nt);
- return;
- }
- // put_at ( ... )
- //!@#$ should check types. if (r->nt!=in->nt) RAISE("shoo");
- int nn=r->dim->n, na=put_at->dim->v[0], nb=in->dim->n;
- STACK_ARRAY(int32,sizeb,nn);
- for (int i=0; i<nn; i++) { fromb[i]=0; sizeb[i]=1; }
- COPY(Pt<int32>(wdex,nn) ,(Pt<int32>)*put_at ,put_at->dim->prod());
- COPY(Pt<int32>(fromb,nn)+nn-na,(Pt<int32>)*put_at ,na);
- COPY(Pt<int32>(sizeb,nn)+nn-nb,(Pt<int32>)in->dim->v,nb);
- for (int i=0; i<nn; i++) to2[i] = fromb[i]+sizeb[i];
- d=0;
- // find out when we can skip computing indices
- //!@#$ should actually also stop before blowing up packet size
- lsd=nn;
- while (lsd>=nn-in->dim->n) {
- lsd--;
- int cs = in->dim->prod(lsd-nn+in->dim->n);
- if (cs>GridOutlet::MAX_PACKET_SIZE || fromb[lsd]!=0 || sizeb[lsd]!=r->dim->v[lsd]) break;
- }
- lsd++;
- int cs = in->dim->prod(lsd-nn+in->dim->n);
- in->set_factor(cs);
-} GRID_FLOW {
- if (!put_at) { // reassign
- COPY(((Pt<T>)*(r.next ? r.next.p : &*r.p))+in->dex, data, n);
- return;
- }
- // put_at ( ... )
- int nn=r->dim->n;
- int cs = in->factor(); // chunksize
- STACK_ARRAY(int32,v,lsd);
- Pt<int32> x = Pt<int32>(wdex,nn);
- while (n) {
- // here d is the dim# to reset; d=n for none
- for(;d<lsd;d++) x[d]=fromb[d];
- COPY(v,x,lsd);
- compute_indices(v,lsd,1);
- op->zip(cs,(Pt<T>)*r+v[0]*cs,data);
- data+=cs;
- n-=cs;
- // find next set of indices; here d is the dim# to increment
- for(;;) {
- d--;
- if (d<0) goto end;
- x[d]++;
- if (x[d]<to2[d]) break;
- }
- end:; // why here ??? or why at all?
- d++;
- }
- //end:; // why not here ???
-} GRID_END
-\def void _0_op(Numop *op) { this->op=op; }
-\def void _0_bang () { rb_funcall(rself,SI(_0_list),3,INT2NUM(0),SYM(#),INT2NUM(0)); }
-\def void _1_reassign () { put_at=0; }
-\def void _1_put_at (Grid *index) { put_at=index; }
-\def void initialize (Grid *r) {
- rb_call_super(argc,argv);
- this->r = r?r:new Grid(new Dim(),int32_e,true);
- op = op_put;
-}
-\classinfo { IEVAL(rself,"install '#store',2,1"); }
-\end class GridStore
-
-//****************************************************************
-//{ Dim[*As]<T> -> Dim[*As]<T> } or
-//{ Dim[*As]<T>,Dim[*Bs]<T> -> Dim[*As]<T> }
-\class GridOp < GridObject
-struct GridOp : GridObject {
- \attr Numop *op;
- PtrGrid r;
- \decl void initialize(Numop *op, Grid *r=0);
- \grin 0
- \grin 1
- \decl void _0_op(Numop *op);
-};
-
-GRID_INLET(GridOp,0) {
- snap_backstore(r);
- SAME_TYPE(in,r);
- out=new GridOutlet(this,0,in->dim,in->nt);
- in->set_mode(6);
-} GRID_ALLOC {
- //out->ask(in->allocn,(Pt<T> &)in->alloc,in->allocfactor,in->allocmin,in->allocmax);
-} GRID_FLOW {
- Pt<T> rdata = (Pt<T>)*r;
- int loop = r->dim->prod();
- if (sizeof(T)==8) {
- fprintf(stderr,"1: data=%p rdata=%p\n",data.p,rdata.p);
- WATCH(n,data);
- }
- if (loop>1) {
- if (in->dex+n <= loop) {
- op->zip(n,data,rdata+in->dex);
- } else {
- // !@#$ should prebuild and reuse this array when "loop" is small
- STACK_ARRAY(T,data2,n);
- int ii = mod(in->dex,loop);
- int m = min(loop-ii,n);
- COPY(data2,rdata+ii,m);
- int nn = m+((n-m)/loop)*loop;
- for (int i=m; i<nn; i+=loop) COPY(data2+i,rdata,loop);
- if (n>nn) COPY(data2+nn,rdata,n-nn);
- if (sizeof(T)==8) {
- fprintf(stderr,"2: data=%p data2=%p\n",data.p,data2.p);
- WATCH(n,data); WATCH(n,data2);
- }
- op->zip(n,data,data2);
- if (sizeof(T)==8) {WATCH(n,data); WATCH(n,data2);}
- }
- } else {
- op->map(n,data,*rdata);
- }
- out->give(n,data);
-} GRID_END
-
-GRID_INPUT2(GridOp,1,r) {} GRID_END
-\def void _0_op(Numop *op) { this->op=op; }
-
-\def void initialize(Numop *op, Grid *r=0) {
- rb_call_super(argc,argv);
- this->op=op;
- this->r = r?r:new Grid(new Dim(),int32_e,true);
-}
-
-\classinfo { IEVAL(rself,"install '#',2,1"); }
-\end class GridOp
-
-//****************************************************************
-\class GridFold < GridObject
-struct GridFold : GridObject {
- \attr Numop *op;
- \attr PtrGrid seed;
- \decl void initialize (Numop *op);
- \decl void _0_op (Numop *op);
- \decl void _0_seed (Grid *seed);
- \grin 0
-};
-
-GRID_INLET(GridFold,0) {
- //{ Dim[*As,B,*Cs]<T>,Dim[*Cs]<T> -> Dim[*As,*Cs]<T> }
- if (seed) SAME_TYPE(in,seed);
- int an = in->dim->n;
- int bn = seed?seed->dim->n:0;
- if (an<=bn) RAISE("minimum 1 more dimension than the seed (%d vs %d)",an,bn);
- STACK_ARRAY(int32,v,an-1);
- int yi = an-bn-1;
- COPY(v,in->dim->v,yi);
- COPY(v+yi,in->dim->v+an-bn,bn);
- if (seed) SAME_DIM(an-(yi+1),in->dim,(yi+1),seed->dim,0);
- out=new GridOutlet(this,0,new Dim(an-1,v),in->nt);
- int k = seed ? seed->dim->prod() : 1;
- in->set_factor(in->dim->get(yi)*k);
-} GRID_FLOW {
- int an = in->dim->n;
- int bn = seed?seed->dim->n:0;
- int yn = in->dim->v[an-bn-1];
- int zn = in->dim->prod(an-bn);
- STACK_ARRAY(T,buf,n/yn);
- int nn=n;
- int yzn=yn*zn;
- for (int i=0; n; i+=zn, data+=yzn, n-=yzn) {
- if (seed) COPY(buf+i,((Pt<T>)*seed),zn);
- else CLEAR(buf+i,zn);
- op->fold(zn,yn,buf+i,data);
- }
- out->send(nn/yn,buf);
-} GRID_END
-
-\def void _0_op (Numop *op ) { this->op =op; }
-\def void _0_seed (Grid *seed) { this->seed=seed; }
-\def void initialize (Numop *op) { rb_call_super(argc,argv); this->op=op; }
-\classinfo { IEVAL(rself,"install '#fold',1,1"); }
-\end class GridFold
-
-\class GridScan < GridObject
-struct GridScan : GridObject {
- \attr Numop *op;
- \attr PtrGrid seed;
- \decl void initialize (Numop *op);
- \decl void _0_op (Numop *op);
- \decl void _0_seed (Grid *seed);
- \grin 0
-};
-
-GRID_INLET(GridScan,0) {
- //{ Dim[*As,B,*Cs]<T>,Dim[*Cs]<T> -> Dim[*As,B,*Cs]<T> }
- if (seed) SAME_TYPE(in,seed);
- int an = in->dim->n;
- int bn = seed?seed->dim->n:0;
- if (an<=bn) RAISE("minimum 1 more dimension than the right hand");
- if (seed) SAME_DIM(bn,in->dim,an-bn,seed->dim,0);
- out=new GridOutlet(this,0,in->dim,in->nt);
- in->set_factor(in->dim->prod(an-bn-1));
-} GRID_FLOW {
- int an = in->dim->n;
- int bn = seed?seed->dim->n:0;
- int yn = in->dim->v[an-bn-1];
- int zn = in->dim->prod(an-bn);
- int factor = in->factor();
- STACK_ARRAY(T,buf,n);
- COPY(buf,data,n);
- if (seed) {
- for (int i=0; i<n; i+=factor) op->scan(zn,yn,(Pt<T>)*seed,buf+i);
- } else {
- STACK_ARRAY(T,seed,zn);
- CLEAR(seed,zn);
- for (int i=0; i<n; i+=factor) op->scan(zn,yn,seed,buf+i);
- }
- out->send(n,buf);
-} GRID_END
-
-\def void _0_op (Numop *op ) { this->op =op; }
-\def void _0_seed (Grid *seed) { this->seed=seed; }
-\def void initialize (Numop *op) { rb_call_super(argc,argv); this->op = op; }
-\classinfo { IEVAL(rself,"install '#scan',1,1"); }
-\end class GridScan
-
-//****************************************************************
-//{ Dim[*As,C]<T>,Dim[C,*Bs]<T> -> Dim[*As,*Bs]<T> }
-\class GridInner < GridObject
-struct GridInner : GridObject {
- \attr Numop *op_para;
- \attr Numop *op_fold;
- \attr PtrGrid seed;
- PtrGrid r;
- PtrGrid r2;
- GridInner() {}
- \decl void initialize (Grid *r=0);
- \decl void _0_op (Numop *op);
- \decl void _0_fold (Numop *op);
- \decl void _0_seed (Grid *seed);
- \grin 0
- \grin 1
-};
-
-template <class T> void inner_child_a (Pt<T> buf, Pt<T> data, int rrows, int rcols, int chunk) {
- Pt<T> bt = buf, dt = data;
- for (int j=0; j<chunk; j++, bt+=rcols, dt+=rrows) op_put->map(rcols,bt,*dt);
-}
-template <class T, int rcols> void inner_child_b (Pt<T> buf, Pt<T> data, int rrows, int chunk) {
- Pt<T> bt = buf, dt = data;
- for (int j=0; j<chunk; j++, bt+=rcols, dt+=rrows) {
- for (int k=0; k<rcols; k++) bt[k] = *dt;
- }
-}
-GRID_INLET(GridInner,0) {
- SAME_TYPE(in,r);
- SAME_TYPE(in,seed);
- P<Dim> a = in->dim;
- P<Dim> b = r->dim;
- if (a->n<1) RAISE("a: minimum 1 dimension");
- if (b->n<1) RAISE("b: minimum 1 dimension");
- if (seed->dim->n != 0) RAISE("seed must be a scalar");
- int a_last = a->get(a->n-1);
- int n = a->n+b->n-2;
- SAME_DIM(1,a,a->n-1,b,0);
- STACK_ARRAY(int32,v,n);
- COPY(v,a->v,a->n-1);
- COPY(v+a->n-1,b->v+1,b->n-1);
- out=new GridOutlet(this,0,new Dim(n,v),in->nt);
- in->set_factor(a_last);
-
- int rrows = in->factor();
- int rsize = r->dim->prod();
- int rcols = rsize/rrows;
- Pt<T> rdata = (Pt<T>)*r;
- int chunk = GridOutlet::MAX_PACKET_SIZE/rsize;
- r2=new Grid(new Dim(chunk*rsize),r->nt);
- Pt<T> buf3 = (Pt<T>)*r2;
- for (int i=0; i<rrows; i++)
- for (int j=0; j<chunk; j++)
- COPY(buf3+(j+i*chunk)*rcols,rdata+i*rcols,rcols);
-} GRID_FLOW {
- int rrows = in->factor();
- int rsize = r->dim->prod();
- int rcols = rsize/rrows;
- int chunk = GridOutlet::MAX_PACKET_SIZE/rsize;
- STACK_ARRAY(T,buf ,chunk*rcols);
- STACK_ARRAY(T,buf2,chunk*rcols);
- int off = chunk;
- while (n) {
- if (chunk*rrows>n) chunk=n/rrows;
- op_put->map(chunk*rcols,buf2,*(T *)*seed);
- for (int i=0; i<rrows; i++) {
- switch (rcols) {
- case 1: inner_child_b<T,1>(buf,data+i,rrows,chunk); break;
- case 2: inner_child_b<T,2>(buf,data+i,rrows,chunk); break;
- case 3: inner_child_b<T,3>(buf,data+i,rrows,chunk); break;
- case 4: inner_child_b<T,4>(buf,data+i,rrows,chunk); break;
- default: inner_child_a(buf,data+i,rrows,rcols,chunk);
- }
- op_para->zip(chunk*rcols,buf,(Pt<T>)*r2+i*off*rcols);
- op_fold->zip(chunk*rcols,buf2,buf);
- }
- out->send(chunk*rcols,buf2);
- n-=chunk*rrows;
- data+=chunk*rrows;
- }
-} GRID_FINISH {
- r2=0;
-} GRID_END
-
-GRID_INPUT(GridInner,1,r) {} GRID_END
-
-\def void initialize (Grid *r) {
- rb_call_super(argc,argv);
- this->op_para = op_mul;
- this->op_fold = op_add;
- this->seed = new Grid(new Dim(),int32_e,true);
- this->r = r ? r : new Grid(new Dim(),int32_e,true);
-}
-
-\def void _0_op (Numop *op ) { this->op_para=op; }
-\def void _0_fold (Numop *op ) { this->op_fold=op; }
-\def void _0_seed (Grid *seed) { this->seed=seed; }
-\classinfo { IEVAL(rself,"install '#inner',2,1"); }
-\end class GridInner
-
-/* **************************************************************** */
-/*{ Dim[*As]<T>,Dim[*Bs]<T> -> Dim[*As,*Bs]<T> }*/
-\class GridOuter < GridObject
-struct GridOuter : GridObject {
- \attr Numop *op;
- PtrGrid r;
- \decl void initialize (Numop *op, Grid *r=0);
- \grin 0
- \grin 1
-};
-
-GRID_INLET(GridOuter,0) {
- SAME_TYPE(in,r);
- P<Dim> a = in->dim;
- P<Dim> b = r->dim;
- int n = a->n+b->n;
- STACK_ARRAY(int32,v,n);
- COPY(v,a->v,a->n);
- COPY(v+a->n,b->v,b->n);
- out=new GridOutlet(this,0,new Dim(n,v),in->nt);
-} GRID_FLOW {
- int b_prod = r->dim->prod();
- if (b_prod > 4) {
- STACK_ARRAY(T,buf,b_prod);
- while (n) {
- for (int j=0; j<b_prod; j++) buf[j] = *data;
- op->zip(b_prod,buf,(Pt<T>)*r);
- out->send(b_prod,buf);
- data++; n--;
- }
- return;
- }
- n*=b_prod;
- Pt<T> buf = ARRAY_NEW(T,n);
- STACK_ARRAY(T,buf2,b_prod*64);
- for (int i=0; i<64; i++) COPY(buf2+i*b_prod,(Pt<T>)*r,b_prod);
- switch (b_prod) {
- #define Z buf[k++]=data[i]
- case 1: for (int i=0,k=0; k<n; i++) {Z;} break;
- case 2: for (int i=0,k=0; k<n; i++) {Z;Z;} break;
- case 3: for (int i=0,k=0; k<n; i++) {Z;Z;Z;} break;
- case 4: for (int i=0,k=0; k<n; i++) {Z;Z;Z;Z;} break;
- default:for (int i=0,k=0; k<n; i++) for (int j=0; j<b_prod; j++, k++) Z;
- }
- #undef Z
- int ch=64*b_prod;
- int nn=(n/ch)*ch;
- for (int j=0; j<nn; j+=ch) op->zip(ch,buf+j,buf2);
- op->zip(n-nn,buf+nn,buf2);
- out->give(n,buf);
-} GRID_END
-
-GRID_INPUT(GridOuter,1,r) {} GRID_END
-
-\def void initialize (Numop *op, Grid *r) {
- rb_call_super(argc,argv);
- this->op = op;
- this->r = r ? r : new Grid(new Dim(),int32_e,true);
-}
-
-\classinfo { IEVAL(rself,"install '#outer',2,1"); }
-\end class GridOuter
-
-//****************************************************************
-//{ Dim[]<T>,Dim[]<T>,Dim[]<T> -> Dim[A]<T> } or
-//{ Dim[B]<T>,Dim[B]<T>,Dim[B]<T> -> Dim[*As,B]<T> }
-\class GridFor < GridObject
-struct GridFor : GridObject {
- \attr PtrGrid from;
- \attr PtrGrid to;
- \attr PtrGrid step;
- GridFor () {
- from.constrain(expect_max_one_dim);
- to .constrain(expect_max_one_dim);
- step.constrain(expect_max_one_dim);
- }
- \decl void initialize (Grid *from, Grid *to, Grid *step);
- \decl void _0_set (Grid *r=0);
- \decl void _0_bang ();
- \grin 0 int
- \grin 1 int
- \grin 2 int
- template <class T> void trigger (T bogus);
-};
-
-\def void initialize (Grid *from, Grid *to, Grid *step) {
- rb_call_super(argc,argv);
- this->from=from;
- this->to =to;
- this->step=step;
-}
-
-template <class T>
-void GridFor::trigger (T bogus) {
- int n = from->dim->prod();
- int32 nn[n+1];
- STACK_ARRAY(T,x,64*n);
- Pt<T> fromb = (Pt<T>)*from;
- Pt<T> tob = (Pt<T>)*to ;
- Pt<T> stepb = (Pt<T>)*step;
- STACK_ARRAY(T,to2,n);
-
- for (int i=step->dim->prod()-1; i>=0; i--)
- if (!stepb[i]) RAISE("step must not contain zeroes");
- for (int i=0; i<n; i++) {
- nn[i] = (tob[i] - fromb[i] + stepb[i] - cmp(stepb[i],(T)0)) / stepb[i];
- if (nn[i]<0) nn[i]=0;
- to2[i] = fromb[i]+stepb[i]*nn[i];
- }
- P<Dim> d;
- if (from->dim->n==0) { d = new Dim(*nn); }
- else { nn[n]=n; d = new Dim(n+1,nn); }
- int total = d->prod();
- out=new GridOutlet(this,0,d,from->nt);
- if (total==0) return;
- int k=0;
- for(int d=0;;d++) {
- // here d is the dim# to reset; d=n for none
- for(;d<n;d++) x[k+d]=fromb[d];
- k+=n;
- if (k==64*n) {out->send(k,x); k=0; COPY(x,x+63*n,n);}
- else { COPY(x+k,x+k-n,n);}
- d--;
- // here d is the dim# to increment
- for(;;d--) {
- if (d<0) goto end;
- x[k+d]+=stepb[d];
- if (x[k+d]!=to2[d]) break;
- }
- }
- end: if (k) out->send(k,x);
-}
-
-\def void _0_bang () {
- SAME_TYPE(from,to);
- SAME_TYPE(from,step);
- if (!from->dim->equal(to->dim) || !to->dim->equal(step->dim))
- RAISE("dimension mismatch");
-#define FOO(T) trigger((T)0);
- TYPESWITCH_JUSTINT(from->nt,FOO,);
-#undef FOO
-}
-
-\def void _0_set (Grid *r) { from=new Grid(argv[0]); }
-GRID_INPUT(GridFor,2,step) {} GRID_END
-GRID_INPUT(GridFor,1,to) {} GRID_END
-GRID_INPUT(GridFor,0,from) {_0_bang(0,0);} GRID_END
-\classinfo { IEVAL(rself,"install '#for',3,1"); }
-\end class GridFor
-
-//****************************************************************
-\class GridFinished < GridObject
-struct GridFinished : GridObject {
- \grin 0
-};
-GRID_INLET(GridFinished,0) {
- in->set_mode(0);
-} GRID_FINISH {
- Ruby a[] = { INT2NUM(0), bsym._bang };
- send_out(COUNT(a),a);
-} GRID_END
-\classinfo { IEVAL(rself,"install '#finished',1,1"); }
-\end class GridFinished
-
-\class GridDim < GridObject
-struct GridDim : GridObject {
- \grin 0
-};
-GRID_INLET(GridDim,0) {
- GridOutlet out(this,0,new Dim(in->dim->n));
- out.send(in->dim->n,Pt<int32>(in->dim->v,in->dim->n));
- in->set_mode(0);
-} GRID_END
-\classinfo { IEVAL(rself,"install '#dim',1,1"); }
-\end class GridDim
-
-\class GridType < GridObject
-struct GridType : GridObject {
- \grin 0
-};
-GRID_INLET(GridType,0) {
- Ruby a[] = { INT2NUM(0), SYM(symbol), number_type_table[in->nt].sym };
- send_out(COUNT(a),a);
- in->set_mode(0);
-} GRID_END
-\classinfo { IEVAL(rself,"install '#type',1,1"); }
-\end class GridType
-
-//****************************************************************
-//{ Dim[*As]<T>,Dim[B] -> Dim[*Cs]<T> }
-\class GridRedim < GridObject
-struct GridRedim : GridObject {
- \attr P<Dim> dim;
- PtrGrid dim_grid;
- PtrGrid temp; // temp->dim is not of the same shape as dim
- GridRedim() { dim_grid.constrain(expect_dim_dim_list); }
- ~GridRedim() {}
- \decl void initialize (Grid *d);
- \grin 0
- \grin 1 int32
-};
-
-GRID_INLET(GridRedim,0) {
- int a = in->dim->prod(), b = dim->prod();
- if (a<b) temp=new Grid(new Dim(a),in->nt);
- out=new GridOutlet(this,0,dim,in->nt);
-} GRID_FLOW {
- int i = in->dex;
- if (!temp) {
- int b = dim->prod();
- int n2 = min(n,b-i);
- if (n2>0) out->send(n2,data);
- // discard other values if any
- } else {
- int a = in->dim->prod();
- int n2 = min(n,a-i);
- COPY((Pt<T>)*temp+i,data,n2);
- if (n2>0) out->send(n2,data);
- }
-} GRID_FINISH {
- if (!!temp) {
- int a = in->dim->prod(), b = dim->prod();
- if (a) {
- for (int i=a; i<b; i+=a) out->send(min(a,b-i),(Pt<T>)*temp);
- } else {
- STACK_ARRAY(T,foo,1);
- foo[0]=0;
- for (int i=0; i<b; i++) out->send(1,foo);
- }
- }
- temp=0;
-} GRID_END
-
-GRID_INPUT(GridRedim,1,dim_grid) { dim = dim_grid->to_dim(); } GRID_END
-
-\def void initialize (Grid *d) {
- rb_call_super(argc,argv);
- dim_grid=d;
- dim = dim_grid->to_dim();
-}
-
-\classinfo { IEVAL(rself,"install '#redim',2,1"); }
-\end class GridRedim
-
-//****************************************************************
-\class GridJoin < GridObject
-struct GridJoin : GridObject {
- \attr int which_dim;
- PtrGrid r;
- \grin 0
- \grin 1
- \decl void initialize (int which_dim=-1, Grid *r=0);
-};
-
-GRID_INLET(GridJoin,0) {
- NOTEMPTY(r);
- SAME_TYPE(in,r);
- P<Dim> d = in->dim;
- if (d->n != r->dim->n) RAISE("wrong number of dimensions");
- int w = which_dim;
- if (w<0) w+=d->n;
- if (w<0 || w>=d->n)
- RAISE("can't join on dim number %d on %d-dimensional grids",
- which_dim,d->n);
- STACK_ARRAY(int32,v,d->n);
- for (int i=0; i<d->n; i++) {
- v[i] = d->get(i);
- if (i==w) {
- v[i]+=r->dim->v[i];
- } else {
- if (v[i]!=r->dim->v[i]) RAISE("dimensions mismatch: dim #%i, left is %d, right is %d",i,v[i],r->dim->v[i]);
- }
- }
- out=new GridOutlet(this,0,new Dim(d->n,v),in->nt);
- if (d->prod(w)) in->set_factor(d->prod(w));
-} GRID_FLOW {
- int w = which_dim;
- if (w<0) w+=in->dim->n;
- int a = in->factor();
- int b = r->dim->prod(w);
- Pt<T> data2 = (Pt<T>)*r + in->dex*b/a;
- if (a==3 && b==1) {
- int m = n+n*b/a;
- STACK_ARRAY(T,data3,m);
- Pt<T> data4 = data3;
- while (n) {
- SCOPY(data4,data,3); SCOPY(data4+3,data2,1);
- n-=3; data+=3; data2+=1; data4+=4;
- }
- out->send(m,data3);
- } else if (a+b<=16) {
- int m = n+n*b/a;
- STACK_ARRAY(T,data3,m);
- int i=0;
- while (n) {
- COPY(data3+i,data,a); data+=a; i+=a; n-=a;
- COPY(data3+i,data2,b); data2+=b; i+=b;
- }
- out->send(m,data3);
- } else {
- while (n) {
- out->send(a,data);
- out->send(b,data2);
- data+=a; data2+=b; n-=a;
- }
- }
-} GRID_FINISH {
- if (in->dim->prod()==0) out->send(r->dim->prod(),(Pt<T>)*r);
-} GRID_END
-
-GRID_INPUT(GridJoin,1,r) {} GRID_END
-
-\def void initialize (int which_dim, Grid *r) {
- rb_call_super(argc,argv);
- this->which_dim = which_dim;
- if (r) this->r=r;
-}
-
-\classinfo { IEVAL(rself,"install '@join',2,1"); }
-\end class GridJoin
-
-//****************************************************************
-\class GridGrade < GridObject
-struct GridGrade : GridObject {
- \grin 0
-};
-
-template <class T> struct GradeFunction {
- static int comparator (const void *a, const void *b) {
- return **(T**)a - **(T**)b;}};
-#define FOO(S) \
-template <> struct GradeFunction<S> { \
- static int comparator (const void *a, const void *b) { \
- S x = **(S**)a - **(S**)b; \
- return x<0 ? -1 : x>0;}};
-FOO(int64)
-FOO(float32)
-FOO(float64)
-#undef FOO
-
-GRID_INLET(GridGrade,0) {
- out=new GridOutlet(this,0,in->dim,in->nt);
- in->set_factor(in->dim->get(in->dim->n-1));
-} GRID_FLOW {
- int m = in->factor();
- STACK_ARRAY(T*,foo,m);
- STACK_ARRAY(T,bar,m);
- for (; n; n-=m,data+=m) {
- for (int i=0; i<m; i++) foo[i] = &data[i];
- qsort(foo,m,sizeof(T),GradeFunction<T>::comparator);
- for (int i=0; i<m; i++) bar[i] = foo[i]-(T *)data;
- out->send(m,bar);
- }
-} GRID_END
-
-\classinfo { IEVAL(rself,"install '#grade',1,1"); }
-\end class GridGrade
-
-//****************************************************************
-//\class GridMedian < GridObject
-//****************************************************************
-
-\class GridTranspose < GridObject
-struct GridTranspose : GridObject {
- \attr int dim1;
- \attr int dim2;
- int d1,d2,na,nb,nc,nd; // temporaries
- \decl void initialize (int dim1=0, int dim2=1);
- \decl void _1_float (int dim1);
- \decl void _2_float (int dim2);
- \grin 0
-};
-
-\def void _1_float (int dim1) { this->dim1=dim1; }
-\def void _2_float (int dim2) { this->dim2=dim2; }
-
-GRID_INLET(GridTranspose,0) {
- STACK_ARRAY(int32,v,in->dim->n);
- COPY(v,in->dim->v,in->dim->n);
- d1=dim1; d2=dim2;
- if (d1<0) d1+=in->dim->n;
- if (d2<0) d2+=in->dim->n;
- if (d1>=in->dim->n || d2>=in->dim->n || d1<0 || d2<0)
- RAISE("would swap dimensions %d and %d but this grid has only %d dimensions",
- dim1,dim2,in->dim->n);
- memswap(v+d1,v+d2,1);
- if (d1==d2) {
- out=new GridOutlet(this,0,new Dim(in->dim->n,v), in->nt);
- } else {
- nd = in->dim->prod(1+max(d1,d2));
- nc = in->dim->v[max(d1,d2)];
- nb = in->dim->prod(1+min(d1,d2))/nc/nd;
- na = in->dim->v[min(d1,d2)];
- out=new GridOutlet(this,0,new Dim(in->dim->n,v), in->nt);
- in->set_factor(na*nb*nc*nd);
- }
- // Turns a Grid[*,na,*nb,nc,*nd] into a Grid[*,nc,*nb,na,*nd].
-} GRID_FLOW {
- STACK_ARRAY(T,res,na*nb*nc*nd);
- if (dim1==dim2) { out->send(n,data); return; }
- int prod = na*nb*nc*nd;
- for (; n; n-=prod, data+=prod) {
- for (int a=0; a<na; a++)
- for (int b=0; b<nb; b++)
- for (int c=0; c<nc; c++)
- COPY(res +((c*nb+b)*na+a)*nd,
- data+((a*nb+b)*nc+c)*nd,nd);
- out->send(na*nb*nc*nd,res);
- }
-} GRID_END
-
-\def void initialize (int dim1=0, int dim2=1) {
- rb_call_super(argc,argv);
- this->dim1 = dim1;
- this->dim2 = dim2;
-}
-
-\classinfo { IEVAL(rself,"install '#transpose',3,1"); }
-\end class GridTranspose
-
-//****************************************************************
-\class GridReverse < GridObject
-struct GridReverse : GridObject {
- \attr int dim1; // dimension to act upon
- int d; // temporaries
- \decl void initialize (int dim1=0);
- \decl void _1_float (int dim1);
- \grin 0
-};
-
-\def void _1_float (int dim1) { this->dim1=dim1; }
-
-GRID_INLET(GridReverse,0) {
- d=dim1;
- if (d<0) d+=in->dim->n;
- if (d>=in->dim->n || d<0)
- RAISE("would reverse dimension %d but this grid has only %d dimensions",
- dim1,in->dim->n);
- out=new GridOutlet(this,0,new Dim(in->dim->n,in->dim->v), in->nt);
- in->set_factor(in->dim->prod(d));
-} GRID_FLOW {
- int f1=in->factor(), f2=in->dim->prod(d+1);
- while (n) {
- int hf1=f1/2;
- Pt<T> data2 = data+f1-f2;
- for (int i=0; i<hf1; i+=f2) memswap(data+i,data2-i,f2);
- out->send(f1,data);
- data+=f1; n-=f1;
- }
-} GRID_END
-
-\def void initialize (int dim1=0) {
- rb_call_super(argc,argv);
- this->dim1 = dim1;
-}
-
-\classinfo { IEVAL(rself,"install '#reverse',2,1"); }
-\end class GridReverse
-
-//****************************************************************
-\class GridCentroid < GridObject
-struct GridCentroid : GridObject {
- \decl void initialize ();
- \grin 0 int
- int sumx,sumy,sum,y; // temporaries
-};
-
-GRID_INLET(GridCentroid,0) {
- if (in->dim->n != 3) RAISE("expecting 3 dims");
- if (in->dim->v[2] != 1) RAISE("expecting 1 channel");
- in->set_factor(in->dim->prod(1));
- out=new GridOutlet(this,0,new Dim(2), in->nt);
- sumx=0; sumy=0; sum=0; y=0;
-} GRID_FLOW {
- int sx = in->dim->v[1];
- while (n) {
- for (int x=0; x<sx; x++) {
- sumx+=x*data[x];
- sumy+=y*data[x];
- sum += data[x];
- }
- n-=sx;
- data+=sx;
- y++;
- }
-} GRID_FINISH {
- STACK_ARRAY(int32,blah,2);
- blah[0] = sum ? sumy/sum : 0;
- blah[1] = sum ? sumx/sum : 0;
- out->send(2,blah);
- rb_funcall(rself,SI(send_out),2,INT2NUM(1),INT2NUM(blah[0]));
- rb_funcall(rself,SI(send_out),2,INT2NUM(2),INT2NUM(blah[1]));
-} GRID_END
-
-\def void initialize () {
- rb_call_super(argc,argv);
-}
-
-\classinfo { IEVAL(rself,"install '#centroid',1,3"); }
-\end class GridCentroid
-
-//****************************************************************
-\class GridPerspective < GridObject
-struct GridPerspective : GridObject {
- \attr int32 z;
- \grin 0
- \decl void initialize (int32 z=256);
-};
-
-GRID_INLET(GridPerspective,0) {
- int n = in->dim->n;
- STACK_ARRAY(int32,v,n);
- COPY(v,in->dim->v,n);
- v[n-1]--;
- in->set_factor(in->dim->get(in->dim->n-1));
- out=new GridOutlet(this,0,new Dim(n,v),in->nt);
-} GRID_FLOW {
- int m = in->factor();
- for (; n; n-=m,data+=m) {
- op_mul->map(m-1,data,(T)z);
- op_div->map(m-1,data,data[m-1]);
- out->send(m-1,data);
- }
-} GRID_END
-
-\def void initialize (int32 z) {rb_call_super(argc,argv); this->z=z; }
-\classinfo { IEVAL(rself,"install '#perspective',1,1"); }
-\end class GridPerspective
-
-static Numop *OP(Ruby x) { return FIX2PTR(Numop,rb_hash_aref(op_dict,x)); }
-
-void startup_flow_objects () {
- op_add = OP(SYM(+));
- op_sub = OP(SYM(-));
- op_mul = OP(SYM(*));
- op_shl = OP(SYM(<<));
- op_mod = OP(SYM(%));
- op_and = OP(SYM(&));
- op_div = OP(SYM(/));
- op_put = OP(SYM(put));
- \startall
-}
diff --git a/externals/gridflow/base/flow_objects.rb b/externals/gridflow/base/flow_objects.rb
deleted file mode 100644
index 8782ae21..00000000
--- a/externals/gridflow/base/flow_objects.rb
+++ /dev/null
@@ -1,1457 +0,0 @@
-=begin
- $Id: flow_objects.rb,v 1.2 2006-03-15 04:37:28 matju Exp $
-
- GridFlow
- Copyright (c) 2001,2002,2003,2004,2005 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.
-=end
-
-module GridFlow
-
-#-------- fClasses for: control + misc
-
-# a dummy class that gives access to any stuff global to GridFlow.
-FObject.subclass("gridflow",1,1) {
- def _0_profiler_reset
- GridFlow.fobjects.each {|o,*| o.total_time = 0 }
- GridFlow.profiler_reset2 if GridFlow.respond_to? :profiler_reset2
- end
- def _0_profiler_dump
- ol = []
- total=0
- post "-"*32
- post "microseconds percent pointer constructor"
- GridFlow.fobjects.each {|o,*| ol.push o }
-
- # HACK: BitPacking is not a real fobject
- # !@#$ is this still necessary?
- ol.delete_if {|o| not o.respond_to? :total_time }
-
- ol.sort! {|a,b| a.total_time <=> b.total_time }
- ol.each {|o| total += o.total_time }
- total=1 if total<1
- total_us = 0
- ol.each {|o|
- ppm = o.total_time * 1000000 / total
- us = (o.total_time*1E6/GridFlow.cpu_hertz).to_i
- total_us += us
- post "%12d %2d.%04d %08x %s", us,
- ppm/10000, ppm%10000, o.object_id, o.args
- }
- post "-"*32
- post "sum of accounted microseconds: #{total_us}"
- if GridFlow.respond_to? :memcpy_calls then
- post "memcpy calls: #{GridFlow.memcpy_calls} "+
- "; bytes: #{GridFlow.memcpy_bytes}"+
- "; time: #{GridFlow.memcpy_time}"
- end
- if GridFlow.respond_to? :malloc_calls then
- post "malloc calls: #{GridFlow.malloc_calls} "+
- "; bytes: #{GridFlow.malloc_bytes}"+
- "; time: #{GridFlow.malloc_time}"
- end
- post "-"*32
- end
- def _0_formats
- post "-"*32
- GridFlow.fclasses.each {|k,v|
- next if not /#io:/ =~ k
- modes = case v.flags
- when 2; "#out"
- when 4; "#in"
- when 6; "#in/#out"
- end
- post "%s %s: %s", modes, k, v.description
- if v.respond_to? :info then
- post "-> %s", v.info
- end
- }
- post "-"*32
- end
- # security issue if patches shouldn't be allowed to do anything they want
- def _0_eval(*l)
- s = l.map{|x|x.to_i.chr}.join""
- post "ruby: %s", s
- post "returns: %s", eval(s).inspect
- end
- add_creator "@global"
- GridFlow.bind "gridflow", "gridflow" rescue Exception
-}
-FObject.subclass("fps",1,1) {
- def initialize(*options)
- super
- @history = [] # list of delays between incoming messages
- @last = 0.0 # when was last time
- @duration = 0.0 # how much delay since last summary
- @period = 1 # minimum delay between summaries
- @detailed = false
- @mode = :real
- options.each {|o|
- case o
- when :detailed; @detailed=true
- when :real,:user,:system,:cpu; @mode=o
- end
- }
- def @history.moment(n=1)
- sum = 0
- each {|x| sum += x**n }
- sum/length
- end
- end
- def method_missing(*a) end # ignore non-bangs
- def _0_period x; @period=x end
- def publish
- @history.sort!
- n=@history.length
- fps = @history.length/@duration
- if not @detailed then send_out 0, fps; return end
- send_out 0, fps,
- 1000*@history.min,
- 500*(@history[n/2]+@history[(n-1)/2]),
- 1000*@history.max,
- 1000/fps,
- 1000*(@history.moment(2) - @history.moment(1)**2)**0.5
- end
- def _0_bang
- t = case @mode
- when :real; Time.new.to_f
- when :user; Process.times.utime
- when :system; Process.times.stime
- when :cpu; GridFlow.rdtsc/GridFlow.cpu_hertz
- end
- @history.push t-@last
- @duration += t-@last
- @last = t
- return if @duration<@period
- fps = @history.length/@duration
- publish if fps>0.001
- @history.clear
- @duration = 0
- end
-}
-
-# to see what the messages look like when they get on the Ruby side.
-FObject.subclass("rubyprint",1,0) {
- def initialize(*a)
- super
- @time = !!(a.length and a[0]==:time)
- end
-
- def method_missing(s,*a)
- s=s.to_s
- pre = if @time then sprintf "%10.6f ", Time.new.to_f else "" end
- case s
- when /^_0_/; post "%s","#{pre}#{s[3..-1]}: #{a.inspect}"
- else super
- end
- end
-}
-FObject.subclass("printargs",0,0) {
- def initialize(*a) super; post a.inspect end
-}
-GridObject.subclass("#print",1,0) {
- install_rgrid 0, true
- attr_accessor :name
- def initialize(name=nil)
- super # don't forget super!!!
- if name then @name = name.to_s+": " else @name="" end
- @base=10; @format="d"; @trunc=70; @maxrows=50
- end
- def end_hook; end # other hijackability
- def format
- case @nt
- when :float32; '%6.6f'
- when :float64; '%14.14f'
- else "%#{@columns}#{@format}" end
- end
- def _0_base(x)
- @format = (case x
- when 2; "b"
- when 8; "o"
- when 10; "d"
- when 16; "x"
- else raise "base #{x} not supported" end)
- @base = x
- end
- def _0_trunc(x)
- x=x.to_f
- (0..240)===x or raise "out of range (not in 0..240 range)"
- @trunc = x
- end
- def _0_maxrows(x) @maxrows = x.to_i end
- def make_columns udata
- min = udata.min
- max = udata.max
- @columns = "" # huh?
- @columns = [
- sprintf(format,min).length,
- sprintf(format,max).length].max
- end
- def unpack data
- ps = GridFlow.packstring_for_nt @nt
- data.unpack ps
- end
- def _0_rgrid_begin
- @dim = inlet_dim 0
- @nt = inlet_nt 0
- @data = ""
- end
- def _0_rgrid_flow(data) @data << data end
- def _0_rgrid_end
- head = "#{name}Dim[#{@dim.join','}]"
- head << "(#{@nt})" if @nt!=:int32
- head << ": "
- if @dim.length > 3 then
- post head+" (not printed)"
- elsif @dim.length < 2 then
- udata = unpack @data
- make_columns udata
- post trunc(head + dump(udata))
- elsif @dim.length == 2 then
- post head
- udata = unpack @data
- make_columns udata
- sz = udata.length/@dim[0]
- rown = 1
- for row in 0...@dim[0] do
- post trunc(dump(udata[sz*row,sz]))
- rown += 1
- (post "..."; break) if rown>@maxrows
- end
- elsif @dim.length == 3 then
- post head
- make_columns unpack(@data)
- sz = @data.length/@dim[0]
- sz2 = sz/@dim[1]
- rown = 1
- for row in 0...@dim[0]
- column=0; str=""
- for col in 0...@dim[1]
- str << "(" << dump(unpack(@data[sz*row+sz2*col,sz2])) << ")"
- break if str.length>@trunc
- end
- post trunc(str)
- rown += 1
- (post "..."; break) if rown>@maxrows
- end
- end
- @data,@dim,@nt = nil
- end_hook
- end
- def dump(udata,sep=" ")
- f = format
- udata.map{|x| sprintf f,x }.join sep
- end
- def trunc s
- if s.length>@trunc then s[0...@trunc]+" [...]" else s end
- end
-}
-GridPack =
-GridObject.subclass("#pack",1,1) {
- install_rgrid 0
- class<<self;attr_reader :ninlets;end
- def initialize(n=2,cast=:int32)
- n||=self.class.ninlets
- n>=16 and raise "too many inlets"
- super
- @data=[0]*n
- @cast=cast
- @ps =GridFlow.packstring_for_nt cast
- end
- def initialize2
- return if self.class.ninlets>1
- add_inlets @data.length-1
- end
- def _0_cast(cast)
- @ps = GridFlow.packstring_for_nt cast
- @cast = cast
- end
- def self.define_inlet i
- module_eval "
- def _#{i}_int x; @data[#{i}]=x; _0_bang; end
- def _#{i}_float x; @data[#{i}]=x; _0_bang; end
- "
- end
- (0...15).each {|x| define_inlet x }
- def _0_bang
- send_out_grid_begin 0, [@data.length], @cast
- send_out_grid_flow 0, @data.pack(@ps), @cast
- end
- self
-}
-
-# the install_rgrids in the following are hacks so that
-# outlets can work. (install_rgrid is supposed to be for receiving)
-# maybe GF-0.8 doesn't need that.
-GridPack.subclass("@two", 2,1) { install_rgrid 0; def initialize() super 2 end }
-GridPack.subclass("@three",3,1) { install_rgrid 0; def initialize() super 2 end }
-GridPack.subclass("@four", 4,1) { install_rgrid 0; def initialize() super 2 end }
-GridPack.subclass("@eight",8,1) { install_rgrid 0; def initialize() super 2 end }
-GridObject.subclass("#unpack",1,0) {
- install_rgrid 0, true
- def initialize(n=2)
- @n=n
- n>=10 and raise "too many outlets"
- super
- end
- def initialize2; add_outlets @n end
- def _0_rgrid_begin
- inlet_dim(0)==[@n] or raise "expecting Dim[#{@n}], got Dim#{@dim}"
- inlet_set_factor 0,@n
- end
- def _0_rgrid_flow data
- @ps = GridFlow.packstring_for_nt inlet_nt(0)
- duh = data.unpack(@ps)
- i=duh.size-1
- until i<0 do send_out i,duh[i]; i-=1 end
- end
- def _0_rgrid_end; end
-}
-
-GridObject.subclass("#export_symbol",1,1) {
- install_rgrid 0
- def _0_rgrid_begin; @data="" end
- def _0_rgrid_flow data; @data << data; end
- def _0_rgrid_end
- send_out 0, :symbol, @data.unpack("I*").pack("c*").intern
- end
-}
-GridObject.subclass("unix_time",1,3) {
- install_rgrid 0
- def _0_bang
- t = Time.new
- tt = t.to_s
- send_out_grid_begin 0, [tt.length], :uint8
- send_out_grid_flow 0, tt, :uint8
- send_out 1, t.to_i/86400, t.to_i%86400,
- ((t.to_f-t.to_f.floor)*1000000).to_i
- send_out 2, t.year, t.month, t.day, t.hour, t.min, t.day
- end
-}
-### test with "shell xlogo &" -> [exec]
-FObject.subclass("exec",1,0) {
- def _0_shell(*a) system(a.map!{|x| x.to_s }.join(" ")) end
-}
-FObject.subclass("renamefile",1,0) {
- def initialize; end
- def _0_list(a,b) File.rename(a.to_s,b.to_s) end
-}
-FObject.subclass("ls",1,1) {
- def _0_symbol(s) send_out 0, :list, *Dir.new(s.to_s).map {|x| x.intern } end
- def _0_glob (s) send_out 0, :list, *Dir[ s.to_s].map {|x| x.intern } end
-}
-
-#-------- fClasses for: math
-
-FPatcher.subclass("gfmessagebox",1,1) {
- def initialize(*a) @a=a end
- def _0_float(x) send_out 0, *@a.map {|y| if y=="$1".intern then x else y end } end
- def _0_symbol(x) send_out 0, *@a.map {|y| if y=="$1".intern then x else y end } end
-}
-
-FPatcher.subclass("@!",1,1) {
- @fobjects = ["# +","#type","gfmessagebox list $1 #"]
- @wires = [-1,0,1,0, 1,0,2,0, 2,0,0,1, -1,0,0,0, 0,0,-1,0]
- def initialize(sym)
- super
- @fobjects[0].send_in 0, case sym
- when :rand; "op rand"; when :sqrt; "op sqrt"
- when :abs; "op abs-"; when :sq; "op sq-"
- else raise "bork BORK bork" end
- end
-}
-FPatcher.subclass("@fold",2,1) {
- @fobjects = ["#fold +","gfmessagebox seed $1"]
- @wires = [-1,0,0,0, -1,1,1,0, 1,0,0,1, 0,0,-1,0]
- def initialize(op,seed=0) super; o=@fobjects[0]
- o.send_in 0, :op, op; o.send_in 0, :seed, seed end
-}
-FPatcher.subclass("@scan",2,1) {
- @fobjects = ["#scan +","gfmessagebox seed $1"]
- @wires = [-1,0,0,0, -1,1,1,0, 1,0,0,1, 0,0,-1,0]
- def initialize(op,seed=0) super; o=@fobjects[0]
- o.send_in 0, :op, op; o.send_in 0, :seed, seed end
-}
-FPatcher.subclass("@inner",3,1) {
- @fobjects = ["#inner","gfmessagebox seed $1"]
- @wires = [-1,0,0,0, -1,1,1,0, 1,0,0,0, 0,0,-1,0, -1,2,0,1]
- def initialize(op=:*,fold=:+,seed=0,r=0) super; o=@fobjects[0]
- o.send_in 0, :op, op; o.send_in 0, :fold, fold
- o.send_in 0, :seed, seed; o.send_in 1, r end
-}
-FPatcher.subclass("@convolve",2,1) {
- @fobjects = ["#convolve"]
- @wires = [-1,0,0,0, -1,2,0,1, 0,0,-1,0]
- def initialize(op=:*,fold=:+,seed=0,r=0) super; o=@fobjects[0]
- o.send_in 0, :op, op; o.send_in 0, :fold, fold
- o.send_in 0, :seed, seed; o.send_in 1, r end
-}
-
-#-------- fClasses for: video
-
-FPatcher.subclass("@scale_to",2,1) {
- @fobjects = [
- "@for {0 0} {42 42} {1 1}","@ *","@ /",
- "@store","#dim","@redim {2}","#finished",
- ]
- @wires = []
- for i in 1..3 do @wires.concat [i-1,0,i,0] end
- @wires.concat [3,0,-1,0, 4,0,5,0, 5,0,1,1, 6,0,0,0,
- -1,0,4,0, -1,0,3,1, -1,0,6,0, -1,1,0,1, -1,1,2,1]
- def initialize(size)
- (size.length==2 and Numeric===size[0] and Numeric===size[1]) or
- raise "expecting {height width}"
- super
- send_in 1, size
- end
-}
-
-#<vektor> told me to:
-# RGBtoYUV : @fobjects = ["#inner (3 3 # 66 -38 112 128 -74 -94 25 112 -18)",
-# "@ >> 8","@ + {16 128 128}"]
-# YUVtoRGB : @fobjects = ["@ - (16 128 128)",
-# "#inner (3 3 # 298 298 298 0 -100 516 409 -208 0)","@ >> 8"]
-
-FPatcher.subclass("#rotate",2,1) {
- @fobjects = ["#inner","# >> 8"]
- @wires = [-1,0,0,0, 0,0,1,0, 1,0,-1,0]
- def update_rotator
- n = @axis[2]
- rotator = (0...n).map {|i| (0...n).map {|j| if i==j then 256 else 0 end }}
- th = @angle * Math::PI / 18000
- scale = 1<<8
- (0...2).each {|i| (0...2).each {|j|
- a = @axis[i].to_i
- b = @axis[j].to_i
- #GridFlow.post "(#{a},#{b}) #{rotator[a].inspect}"
- rotator[a][b] = (scale*Math.cos(th+(j-i)*Math::PI/2)).to_i
- }}
- @fobjects[0].send_in 1,n,n,"#".intern,*rotator.flatten
- end
- def _0_axis(from,to,total)
- total>=0 or raise "total-axis number incorrect"
- from>=0 and from<total or raise "from-axis number incorrect"
- to >=0 and to <total or raise "to-axis number incorrect"
- @axis = [from.to_i,to.to_i,total.to_i]
- update_rotator
- end
- def initialize(rot=0,axis=[0,1,2])
- super
- @angle=0
- _0_axis(*axis)
- send_in 1, rot
- end
- def _1_int(angle) @angle = angle; update_rotator end
- alias _1_float _1_int
-}
-
-FObject.subclass("foreach",1,1) {
- def initialize() super end
- def _0_list(*a)
- a.each {|e|
- if Symbol===e then
- send_out 0,:symbol,e
- else
- send_out 0,e
- end
- }
- end
-}
-FObject.subclass("listflatten",1,1) {
- def initialize() super end
- def _0_list(*a) send_out 0,:list,*a.flatten end
-}
-FObject.subclass("rubysprintf",2,1) {
- def initialize(*format) _1_list(format) end
- def _0_list(*a) send_out 0, :symbol, (sprintf @format, *a).intern end
- alias _0_float _0_list
- alias _0_symbol _0_list
- def _1_list(*format) @format = format.join(" ") end
- alias _1_symbol _1_list
-}
-
-#-------- fClasses for: jMax compatibility
-
-class JMaxUDPSend < FObject
- def initialize(host,port)
- super
- @socket = UDPSocket.new
- @host,@port = host.to_s,port.to_i
- end
- def encode(x)
- case x
- when Integer; "\x03" + [x].pack("N")
- when Float; "\x04" + [x].pack("g")
- when Symbol, String; "\x01" + x.to_s + "\x02"
- end
- end
- def method_missing(sel,*args)
- sel=sel.to_s.sub(/^_\d_/, "")
- @socket.send encode(sel) +
- args.map{|arg| encode(arg) }.join("") + "\x0b",
- 0, @host, @port
- end
- def delete; @socket.close end
- install "jmax_udpsend", 1, 0
-end
-
-class JMaxUDPReceive < FObject
- def initialize(port)
- super
- @socket = UDPSocket.new
- @port = port.to_i
- @socket.bind nil, @port
- @clock = Clock.new self
- @clock.delay 0
- end
- def decode s
- n = s.length
- i=0
- m = []
- case s[i]
- when 3; i+=5; m << s[i-4,4].unpack("N")[0]
- when 4; i+=5; m << s[i-4,4].unpack("g")[0]
- when 1; i2=s.index("\x02",i); m << s[i+1..i2-1].intern; i=i2+1
- when 11; break
- else raise "unknown code in udp packet"
- end while i<n
- m
- end
- def call
- ready_to_read = IO.select [@socket],[],[],0
- return if not ready_to_read
- data,sender = @socket.recvfrom 1024
- return if not data
- send_out 1, sender.map {|x| x=x.intern if String===x; x }
- send_out 0, *(decode data)
- @clock.delay 50
- end
- def delete; @clock.unset; @socket.close end
- install "jmax_udpreceive", 0, 2
-end
-
-class JMax4UDPSend < FObject
- def initialize(host,port)
- super
- @socket = UDPSocket.new
- @host,@port = host.to_s,port.to_i
- @symbols = {}
- end
- def encode(x)
- case x
- when Integer; "\x01" + [x].pack("N")
- when Float; "\x02" + [x].pack("G")
- when Symbol, String
- x = x.to_s
- y = x.intern
- if not @symbols[y]
- @symbols[y]=true
- "\x04" + [y].pack("N") + x + "\0"
- else
- "\x03" + [y].pack("N")
- end
- end
- end
- def method_missing(sel,*args)
- sel=sel.to_s.sub(/^_\d_/, "")
- sel=(case sel; when "int","float"; ""; else encode(sel) end)
- args=args.map{|arg| encode(arg) }.join("")
- @socket.send(sel+args+"\x0f", 0, @host, @port)
- end
- def delete; @socket.close end
- install "jmax4_udpsend", 1, 0
-end
-
-class JMax4UDPReceive < FObject
- def initialize(port)
- super
- @socket = UDPSocket.new
- @port = port.to_i
- @socket.bind nil, @port
- @clock = Clock.new self
- @clock.delay 0
- @symbols = {}
- end
- def decode s
- n = s.length
- i=0
- m = []
- case s[i]
- when 1; i+=5; m << s[i-4,4].unpack("N")[0]
- when 2; i+=9; m << s[i-8,8].unpack("G")[0]
- when 3
- i+=5; sid = s[i-4,4].unpack("N")[0]
- m << @symbols[sid]
- when 4
- i+=5; sid = s[i-4,4].unpack("N")[0]
- i2=s.index("\x00",i)
- @symbols[sid] = s[i..i2-1].intern
- m << @symbols[sid]
- i=i2+1
- when 15; break
- else post "unknown code %d in udp packet %s", s[i], s.inspect; return m
- end while i<n
- m
- end
- def call
- ready_to_read = IO.select [@socket],[],[],0
- return if not ready_to_read
- data,sender = @socket.recvfrom 1024
- return if not data
- send_out 1, sender.map {|x| x=x.intern if String===x; x }
- send_out 0, *(decode data)
- @clock.delay 50
- end
- def delete; @clock.unset; @socket.close end
- install "jmax4_udpreceive", 0, 2
-end
-
-class PDNetSocket < FObject
- def initialize(host,port,protocol=:udp,*options)
- super
- _1_connect(host,port,protocol)
- @options = {}
- options.each {|k|
- k=k.intern if String===k
- @options[k]=true
- }
- end
- def _1_connect(host,port,protocol=:udp)
- host = host.to_s
- port = port.to_i
- @host,@port,@protocol = host.to_s,port.to_i,protocol
- case protocol
- when :udp
- @socket = UDPSocket.new
- if host=="-" then
- @socket.bind nil, port
- end
- when :tcp
- if host=="-" then
- @server = TCPServer.new("localhost",port)
- else
- @socket = TCPSocket.new(host,port)
- end
-
- end
- @clock = Clock.new self
- @clock.delay 0
- @data = ""
- end
- def encode(x)
- x=x.to_i if @options[:nofloat] and Float===x
- x.to_s
- end
- def method_missing(sel,*args)
- sel=sel.to_s
- sel.sub!(/^_\d_/, "") or return super
- sel=(case sel; when "int","float"; ""; else encode(sel) end)
- msg = [sel,*args.map{|arg| encode(arg) }].join(" ")
- if @options[:nosemicolon] then msg << "\n" else msg << ";\n" end
- post "encoding as: %s", msg.inspect if @options[:debug]
- case @protocol
- when :udp; @socket.send msg, 0, @host, @port
- when :tcp; @socket.send msg, 0
- end
- end
- def delete; @clock.unset; @socket.close end
- def decode s
- post "decoding from: %s", s.inspect if @options[:debug]
- s.chomp!("\n")
- s.chomp!("\r")
- s.chomp!(";")
- a=s.split(/[\s\0]+/)
- a.shift if a[0]==""
- a.map {|x|
- case x
- when /-?\d+$/; x.to_i
- when /-?\d/; x.to_f
- else x.intern
- end
- }
- end
- def call
- ready_to_accept = IO.select [@server],[],[],0 if @server
- if ready_to_accept
- @socket.close if @socket
- @socket = @server.accept
- end
- ready_to_read = IO.select [@socket],[],[],0 if @socket
- return if not ready_to_read
- case @protocol
- when :udp
- data,sender = @socket.recvfrom 1024
- send_out 1, sender.map {|x| x=x.intern if String===x; x }
- send_out 0, *(decode data)
- when :tcp
- @data << @socket.sysread(1024)
- sender = @socket.peeraddr
- loop do
- n = /\n/ =~ @data
- break if not n
- send_out 1, sender.map {|x| x=x.intern if String===x; x }
- send_out 0, *(decode @data.slice!(0..n))
- end
- end
- @clock.delay 50
- end
- install "pd_netsocket", 2, 2
-end
-
-PDNetSocket.subclass("pd_netsend",1,0) {}
-PDNetSocket.subclass("pd_netreceive",0,2) {
- def initialize(port) super("-",port) end
-}
-
-# bogus class for representing objects that have no recognized class.
-FObject.subclass("broken",0,0) {
- def args; a=@args.dup; a[7,0] = " "+classname; a end
-}
-
-FObject.subclass("fork",1,2) {
- def method_missing(sel,*args)
- sel.to_s =~ /^_(\d)_(.*)$/ or super
- send_out 1,$2.intern,*args
- send_out 0,$2.intern,*args
- end
-}
-FObject.subclass("shunt",2,0) {
- def initialize(n=2,i=0) super; @n=n; @i=i end
- def initialize2; add_outlets @n end
- def method_missing(sel,*args)
- sel.to_s =~ /^_(\d)_(.*)$/ or super
- send_out @i,$2.intern,*args
- end
- def _1_int i; @i=i.to_i % @n end
- alias :_1_float :_1_int
- # hack: this is an alias.
- class Demux < self; install "demux", 2, 0; end
-}
-
-#-------- fClasses for: jmax2pd
-
- FObject.subclass("button",1,1) {
- def method_missing(*) send_out 0 end
- }
- FObject.subclass("toggle",1,1) {
- def _0_bang; @state ^= true; trigger end
- def _0_int x; @state = x!=0; trigger end
- def trigger; send_out 0, (if @state then 1 else 0 end) end
- }
- FObject.subclass("jpatcher",0,0) {
- def initialize(*a) super; @subobjects={} end
- attr_accessor :subobjects
- }
- FObject.subclass("jcomment",0,0) {}
- FObject.subclass("loadbang",0,1) { def trigger; send_out 0 end }
- FObject.subclass("messbox",1,1) {
- def _0_bang; send_out 0, *@argv end
- def clear; @argv=[]; end
- def append(*argv) @argv<<argv; end
- }
-
-#-------- fClasses for: list manipulation (jMax-compatible)
-
- FObject.subclass("listmake",2,1) {
- def initialize(*a) @a=a end
- def _0_list(*a) @a=a; _0_bang end
- def _1_list(*a) @a=a end
- def _0_bang; send_out 0, :list, *@a end
- }
- FObject.subclass("listlength",1,1) {
- def initialize() super end
- def _0_list(*a) send_out 0, a.length end
- }
- FObject.subclass("listelement",2,1) {
- def initialize(i=0) super; @i=i.to_i end
- def _1_int(i) @i=i.to_i end; alias _1_float _1_int
- def _0_list(*a)
- e=a[@i]
- if Symbol===e then
- send_out 0, :symbol, e
- else
- send_out 0, e
- end
- end
- }
- FObject.subclass("listsublist",3,1) {
- def initialize(i=0,n=1) super; @i,@n=i.to_i,n.to_i end
- def _1_int(i) @i=i.to_i end; alias _1_float _1_int
- def _2_int(n) @n=n.to_i end; alias _2_float _2_int
- def _0_list(*a) send_out 0, :list, *a[@i,@n] end
- }
- FObject.subclass("listprepend",2,1) {
- def initialize(*b) super; @b=b end
- def _0_list(*a) a[0,0]=@b; send_out 0, :list, *a end
- def _1_list(*b) @b=b end
- }
- FObject.subclass("listappend",2,1) {
- def initialize(*b) super; @b=b end
- def _0_list(*a) a[a.length,0]=@b; send_out 0, :list, *a end
- def _1_list(*b) @b=b end
- }
- FObject.subclass("listreverse",1,1) {
- def initialize() super end
- def _0_list(*a) send_out 0,:list,*a.reverse end
- }
- FObject.subclass("messageprepend",2,1) {
- def initialize(*b) super; @b=b end
- def _0_(*a) a[0,0]=@b; send_out 0, *a end
- def _1_list(*b) @b=b end
- def method_missing(sym,*a)
- (m = /(_\d_)(.*)/.match sym.to_s) or return super
- _0_ m[2].intern, *a
- end
- }
- FObject.subclass("messageappend",2,1) {
- def initialize(*b) super; @b=b end
- def _0_(*a) a[a.length,0]=@b; send_out 0, *a end
- def _1_list(*b) @b=b end
- def method_missing(sym,*a)
- (m = /(_\d_)(.*)/.match sym.to_s) or return super
- _0_ m[2].intern, *a
- end
- }
-
-# this was the original demo for the Ruby/jMax/PureData bridges
-# FObjects are Ruby Objects that are exported to the PureData system.
-# _0_bang means bang message on inlet 0
-# FObject#send_out sends a message through an outlet
-FObject.subclass("for",3,1) {
- attr_accessor :start, :stop, :step
- def cast(key,val)
- val = Integer(val) if Float===val
- raise ArgumentError, "#{key} isn't a number" unless Integer===val
- end
- def initialize(start,stop,step)
- super
- cast("start",start)
- cast("stop",stop)
- cast("step",step)
- @start,@stop,@step = start,stop,step
- end
- def _0_bang
- x = start
- if step > 0
- (send_out 0, x; x += step) while x < stop
- elsif step < 0
- (send_out 0, x; x += step) while x > stop
- end
- end
- def _0_float(x) self.start=x; _0_bang end
- alias _1_float stop=
- alias _2_float stop=
-}
-FObject.subclass("oneshot",2,1) {
- def initialize(state=true) @state=state!=0 end
- def method_missing(sel,*a)
- m = /^_0_(.*)$/.match(sel.to_s) or return super
- send_out 0, m[1].intern, *a if @state
- @state=false
- end
- def _1_int(state) @state=state!=0 end
- alias _1_float _1_int
- def _1_bang; @state=true end
-}
-FObject.subclass("inv+",2,1) {
- def initialize(b=0) @b=b end; def _1_float(b) @b=b end
- def _0_float(a) send_out 0, :float, @b-a end
-}
-FObject.subclass("inv*",2,1) {
- def initialize(b=0) @b=b end; def _1_float(b) @b=b end
- def _0_float(a) send_out 0, :float, @b/a end
-}
-FObject.subclass("range",1,1) {
- def initialize(*a) @a=a end
- def initialize2
- add_inlets @a.length
- add_outlets @a.length
- end
- def _0_float(x) i=0; i+=1 until @a[i]==nil or x<@a[i]; send_out i,x end
- def method_missing(sel,*a)
- m = /^(_\d+_)(.*)/.match(sel.to_s) or return super
- m[2]=="float" or return super
- @a[m[1].to_i-1] = a[0]
- post "setting a[#{m[1].to_i-1}] = #{a[0]}"
- end
-}
-FObject.subclass("listfind",2,1) {
- def initialize(*a) _1_list(*a) end
- def _1_list(*a) @a = a end
- def _0_float(x)
- i=0
- while i<@a.length
- (send_out 0,i; return) if @a[i]==x
- i+=1
- end
- send_out 0,-1
- end
- doc:_1_list,"list to search into"
- doc:_0_float,"float to find in that list"
- doc_out:_0_float,"position of the incoming float in the stored list"
-}
-
-#-------- fClasses for: GUI
-
-module Gooey # to be included in any FObject class
- def initialize(*)
- super
- @selected=false
- @bg = "#ffffff" # white background
- @bgb = "#000000" # black border
- @bgs = "#0000ff" # blue border when selected
- @fg = "#000000" # black foreground
- @rsym = "#{self.class}#{self.object_id}".intern # unique id for use in Tcl
- @can = nil # the canvas number
- @canvas = nil # the canvas string
- @y,@x = 0,0 # position on canvas
- @sy,@sx = 16,16 # size on canvas
- @font = "Courier -12"
- @vis = nil
- end
- attr_reader :canvas
- attr_reader :selected
- def canvas=(can)
- @can = can if Integer===can
- @canvas = case can
- when String; can
- when Integer; ".x%x.c"%(4*can)
- else raise "huh?"
- end
- end
- def initialize2(*) GridFlow.bind self, @rsym.to_s end
- def pd_displace(can,x,y) self.canvas||=can; @x+=x; @y+=y; pd_show(can) end
- def pd_activate(can,*) self.canvas||=can end
- def quote(text) # for tcl (isn't completely right ?)
- text=text.gsub(/[\{\}]/) {|x| "\\"+x }
- "{#{text}}"
- end
- def pd_vis(can,vis)
- self.canvas||=can; @vis=vis!=0; update end
- def update; pd_show @can if @vis end
- def pd_getrect(can)
- self.canvas||=can
- @x,@y = get_position(can)
- # the extra one-pixel on each side was for #peephole only
- # not sure what to do with this
- [@x-1,@y-1,@x+@sx+1,@y+@sy+1]
- end
- def pd_click(can,x,y,shift,alt,dbl,doit) return 0 end
- def outline; if selected then @bgs else "#000000" end end
- def pd_select(can,sel)
- self.canvas||=can
- @selected=sel!=0
- GridFlow.gui %{ #{canvas} itemconfigure #{@rsym} -outline #{outline} \n }
- end
- def pd_delete(can) end
- def pd_show(can)
- self.canvas||=can
- @x,@y = get_position can if can
- end
- def highlight(color,ratio) # doesn't use self
- c = /^#(..)(..)(..)/.match(color)[1..3].map {|x| x.hex }
- c.map! {|x| [255,(x*ratio).to_i].min }
- "#%02x%02x%02x" % c
- end
-end
-
-class Display < FObject; include Gooey
- attr_accessor :text
- def initialize()
- super
- @sel = nil; @args = [] # contents of last received message
- @text = "..."
- @sy,@sx = 16,80 # default size of the widget
- @bg,@bgs,@fg = "#6774A0","#00ff80","#ffff80"
- end
- def _0_set_size(sy,sx) @sy,@sx=sy,sx end
- def atom_to_s a
- case a
- when Float; sprintf("%.5f",a).gsub(/\.?0+$/, "")
- else a.to_s
- end
- end
- def method_missing(sel,*args)
- m = /^(_\d+_)(.*)/.match(sel.to_s) or return super
- @sel,@args = m[2].intern,args
- @text = case @sel
- when nil; "..."
- when :float; atom_to_s @args[0]
- else @sel.to_s + ": " + @args.map{|a| atom_to_s a }.join(' ')
- end
- update
- end
- def pd_show(can)
- super
- return if not canvas or not @vis # can't show for now...
- GridFlow.gui %{
- set canvas #{canvas}
- $canvas delete #{@rsym}TEXT
- set y #{@y+2}
- foreach line [split #{quote @text} \\n] {
- $canvas create text #{@x+2} $y -fill #{@fg} -font #{quote @font}\
- -text $line -anchor nw -tag #{@rsym}TEXT
- set y [expr $y+14]
- }
- foreach {x1 y1 x2 y2} [$canvas bbox #{@rsym}TEXT] {}
- set sx [expr $x2-$x1+1]
- set sy [expr $y2-$y1+3]
- $canvas delete #{@rsym}
- $canvas create rectangle #{@x} #{@y} \
- [expr #{@x}+$sx] [expr #{@y}+$sy] -fill #{@bg} \
- -tags #{@rsym} -outline #{outline}
- $canvas lower #{@rsym} #{@rsym}TEXT
- pd \"#{@rsym} set_size $sy $sx;\n\";
- }
- end
- def pd_delete(can)
- if @vis
- GridFlow.gui %{ #{canvas} delete #{@rsym} #{@rsym}TEXT \n}
- end
- super
- end
- def delete; super end
- def _0_grid(*foo) # big hack!
- # hijacking a [#print]
- gp = FObject["#print"]
- @text = ""
- overlord = self
- gp.instance_eval { @overlord = overlord }
- def gp.post(fmt,*args) @overlord.text << sprintf(fmt,*args) << "\n" end
- def gp.end_hook
- @overlord.instance_eval{@text.chomp!}
- @overlord.update
- end
- #gp.send_in 0, :trunc, 70
- gp.send_in 0, :maxrows, 20
- gp.send_in 0, :grid, *foo
- end
-
- install "display", 1, 1
- gui_enable if GridFlow.bridge_name =~ /puredata/
-end
-
-class GridEdit < GridObject; include Gooey
- def initialize(grid)
- super
- @store = GridStore.new
- @store.connect 0,self,2
- @fin = GridFinished.new
- @fin.connect 0,self,3
- @bg,@bgs,@fg = "#609068","#0080ff","#ff80ff"
- @bghi = highlight(@bg,1.25) # "#80C891" # highlighted @bg
- #@bghihi = highlight(@bghi,1.5) # very highlighted @bg
- @cellsy,@cellsx = 16,48
- @i,@j = nil,nil # highlighted cell dex
- send_in 0, grid
- end
- def _0_cell_size(sy,sx) @cellsy,@cellsx=sy,sx; update end
- def _0_float(*a) @store.send_in 1,:float,*a; @store.send_in 0; update end
- def _0_list (*a) @store.send_in 1, :list,*a; @store.send_in 0; update end
- def _0_grid (*a) @store.send_in 1, :grid,*a; @fin.send_in 0, :grid,*a end
- def _3_bang; @store.send_in 0; update end
- def edit_start(i,j)
- edit_end if @i
- @i,@j=i,j
- GridFlow.gui %{
- set canvas #{canvas}
- $canvas itemconfigure #{@rsym}CELL_#{@i}_#{@j} -fill #{@bghi}
- }
- end
- def edit_end
- GridFlow.gui %{
- set canvas #{canvas}
- $canvas itemconfigure #{@rsym}CELL_#{@i}_#{@j} -fill #{@bg}
- }
- unfocus @can
- end
- def _2_rgrid_begin
- @data = []
- @dim = inlet_dim 2
- @nt = inlet_nt 2
- post "_2_rgrid_begin: dim=#{@dim.inspect} nt=#{@nt.inspect}"
- send_out_grid_begin 0, @dim, @nt
- end
- def _2_rgrid_flow data
- ps = GridFlow.packstring_for_nt @nt
- @data[@data.length,0] = data.unpack(ps)
- post "_2_rgrid_flow: data=#{@data.inspect}"
- send_out_grid_flow 0, data
- end
- def _2_rgrid_end
- post "_2_rgrid_end"
- end
- def pd_click(can,x,y,shift,alt,dbl,doit)
- post "pd_click: %s", [can,x,y,shift,alt,dbl,doit].inspect
- return 0 if not doit!=0
- i = (y-@y-1)/@cellsy
- j = (x-@x-1)/@cellsx
- post "%d,%d", i,j
- ny = @dim[0] || 1
- nx = @dim[1] || 1
- if (0...ny)===i and (0...nx)===j then
- focus @can,x,y
- edit_start i,j
- end
- return 0
- end
- def pd_key(key)
- post "pd_key: %s", [key].inspect
- if key==0 then unfocus @can; return end
- end
- def pd_motion(dx,dy)
- post "pd_motion: %s", [dx,dy].inspect
- ny = @dim[0] || 1
- nx = @dim[1] || 1
- k = @i*nx+@j
- post "@data[#{k}]=#{@data[k]} before"
- @data[k]-=dy
- @store.send_in 1, :put_at, [@i,@j]
- @store.send_in 1, @data[k]
- @store.send_in 0
- post "@data[#{k}]=#{@data[k]} after"
- update
- end
- def pd_show(can)
- super
- return if not can
- ny = @dim[0] || 1
- nx = @dim[1] || 1
- @sy = 2+@cellsy*ny
- @sx = 2+@cellsx*nx
- g = %{
- set canvas #{canvas}
- $canvas delete #{@rsym} #{@rsym}CELL
- $canvas create rectangle #{@x} #{@y} #{@x+@sx} #{@y+@sy} \
- -fill #{@bg} -tags #{@rsym} -outline #{outline}
- }
- ny.times {|i|
- nx.times {|j|
- y1 = @y+1+i*@cellsy; y2 = y1+@cellsy
- x1 = @x+1+j*@cellsx; x2 = x1+@cellsx
- v = @data[i*nx+j]
- g << %{
- $canvas create rectangle #{x1} #{y1} #{x2} #{y2} -fill #{@bg} \
- -tags {#{@rsym}CELL #{@rsym}CELL_#{i}_#{j}} -outline #{outline}
- $canvas create text #{x2-4} #{y1+2} -text "#{v}" -anchor ne -fill #ffffff \
- -tags {#{@rsym}CELL_#{i}_#{j}_T}
- }
- }
- }
- GridFlow.gui g
- end
- install "#edit", 2, 1
- install_rgrid 2, true
- gui_enable if GridFlow.bridge_name =~ /puredata/
-end
-
-class Peephole < FPatcher; include Gooey
- @fobjects = ["#dim","#export_list","#downscale_by 1 smoothly","#out","#scale_by 1",
- proc{Demux.new(2)}]
- @wires = [-1,0,0,0, 0,0,1,0, -1,0,5,0, 2,0,3,0, 4,0,3,0, 5,0,2,0, 5,1,4,0, 3,0,-1,0]
- def initialize(sy=32,sx=32,*args)
- super
- @fobjects[1].connect 0,self,2
- post "Peephole#initialize: #{sx} #{sy} #{args.inspect}"
- @scale = 1
- @down = false
- @sy,@sx = sy,sx # size of the widget
- @fy,@fx = 0,0 # size of last frame after downscale
- @bg,@bgs = "#A07467","#00ff80"
- end
- def pd_show(can)
- super
- return if not can
- if not @open
- GridFlow.gui %{
- pd \"#{@rsym} open [eval list [winfo id #{@canvas}]] 1;\n\";
- }
- @open=true
- end
- # round-trip to ensure this is done after the open
- GridFlow.gui %{
- pd \"#{@rsym} set_geometry #{@y} #{@x} #{@sy} #{@sx};\n\";
- }
- GridFlow.gui %{
- set canvas #{canvas}
- $canvas delete #{@rsym}
- $canvas create rectangle #{@x} #{@y} #{@x+@sx} #{@y+@sy} \
- -fill #{@bg} -tags #{@rsym} -outline #{outline}
- }
- set_geometry_for_real_now
- end
- def set_geometry_for_real_now
- @fy,@fx=@sy,@sx if @fy<1 or @fx<1
- @down = (@fx>@sx or @fy>@sx)
- if @down then
- @scale = [(@fy+@sy-1)/@sy,(@fx+@sx-1)/@sx].max
- @scale=1 if @scale<1 # what???
- @fobjects[2].send_in 1, @scale
- sy2 = @fy/@scale
- sx2 = @fx/@scale
- else
- @scale = [@sy/@fy,@sx/@fx].min
- @fobjects[4].send_in 1, @scale
- sy2 = @fy*@scale
- sx2 = @fx*@scale
- end
- begin
- @fobjects[5].send_in 1, (if @down then 0 else 1 end)
- x2=@y+(@sy-sy2)/2
- y2=@x+(@sx-sx2)/2
- @fobjects[3].send_in 0, :set_geometry,
- x2, y2, sy2, sx2
- rescue StandardError => e
- post "peeperr: %s", e.inspect
- end
- post "set_geometry_for_real_now (%d,%d) (%d,%d) (%d,%d) (%d,%d) (%d,%d)",
- @x+1,@y+1,@sx,@sy,@fx,@fy,sx2,sy2,x2,y2
- end
- def _0_open(wid,use_subwindow)
- post "%s", [wid,use_subwindow].inspect
- @use_subwindow = use_subwindow==0 ? false : true
- if @use_subwindow then
- @fobjects[3].send_in 0, :open,:x11,:here,:embed_by_id,wid
- end
- end
- def _0_set_geometry(y,x,sy,sx)
- @sy,@sx = sy,sx
- @y,@x = y,x
- set_geometry_for_real_now
- end
- def _0_fall_thru(flag) # never worked ?
- post "fall_thru: #{flag}"
- @fobjects[3].send_in 0, :fall_thru, flag
- end
- # note: the numbering here is a FPatcher gimmick... -1,0 goes to _1_.
- def _1_position(y,x,b)
- s=@scale
- if @down then y*=s;x*=s else y*=s;x*=s end
- send_out 0,:position,y,x,b
- end
- def _2_list(sy,sx,chans)
- @fy,@fx = sy,sx
- set_geometry_for_real_now
- end
- def _0_paint()
- post "paint()"
- @fobjects[3].send_in 0, "draw"
- end
- def delete
- post "deleting peephole"
- GridFlow.gui %{ #{canvas} delete #{@rsym} \n}
- @fobjects[3].send_in 0, :close
- super
- end
- def method_missing(s,*a)
- #post "%s: %s", s.to_s, a.inspect
- super rescue NameError
- end
-
- install "#peephole", 1, 1
- gui_enable if GridFlow.bridge_name =~ /puredata/
- #GridFlow.addtomenu "#peephole" # was this IMPD-specific ?
-end
-
-#-------- fClasses for: Hardware
-
-# requires Ruby 1.8.0 because of bug in Ruby 1.6.x
-FObject.subclass("joystick_port",0,1) {
- def initialize(port)
- raise "sorry, requires Ruby 1.8" if RUBY_VERSION<"1.8"
- @f = File.open(port.to_s,"r+")
- @status = nil
- @clock = Clock.new self
- @clock.delay 0
- @f.nonblock=true
- end
- def delete; @clock.unset; @f.close end
- def call
- loop{
- begin
- event = @f.read(8)
- rescue Errno::EAGAIN
- @clock.delay 0
- return
- end
- return if not event
- return if event.length<8
- send_out 0, *event.unpack("IsCC")
- }
- end
-}
-
-# plotter control (HPGL)
-FObject.subclass("plotter_control",1,1) {
- def puts(x)
- x<<"\n"
- x.each_byte {|b| send_out 0, b }
- send_out 0
- end
- def _0_pu; puts "PU;" end
- def _0_pd; puts "PD;" end
- def _0_pa x,y; puts "PA#{x},#{y};" end
- def _0_sp c; puts "SP#{c};"; end
- def _0_ip(*v) puts "IP#{v.join','};" end
- def _0_other(command,*v) puts "#{command.to_s.upcase}#{v.join','};" end
- def _0_print(*text) puts "LB#{text.join(' ')}\003;" end
- def _0_print_from_ascii(*codes)
- _0_print codes.map{|code| code.chr }.join("")
- end
-}
-
-# ASCII, useful for controlling pics
-FObject.subclass("ascii",1,1) {
- def puts(x)
- x.each_byte {|b| send_out 0, b }
- end
- def _0_float x; puts "#{x.to_i}" end
-}
-
-# System, similar to shell
-FObject.subclass("system",1,1) {
- def _0_system(*a)
- system(a.join(" "))
- end
-}
-
-(begin require "linux/ParallelPort"; true; rescue LoadError; false end) and
-FObject.subclass("parallel_port",1,3) {
- def initialize(port,manually=0)
- @f = File.open(port.to_s,"r+")
- @f.extend Linux::ParallelPort
- @status = nil
- @flags = nil
- @manually = manually!=0
- @clock = (if @manually then nil else Clock.new self end)
- @clock.delay 0 if @clock
- end
- def delete; @clock.unset unless @manually; @f.close end
- def _0_int(x) @f.write x.to_i.chr; @f.flush end
- alias _0_float _0_int
- def call
- flags = @f.port_flags
- send_out 2, flags if @flags != flags
- @flags = flags
- status = @f.port_status
- send_out 1, status if @status != status
- @status = status
- @clock.delay 20 if @clock
- end
- def _0_bang
- @status = @flags = nil
- call
- end
- # outlet 0 reserved (future use)
-}
-
-(begin require "linux/SoundMixer"; true; rescue LoadError; false end) and
-#FObject.subclass("SoundMixer",1,1) {
-class GFSoundMixer < FObject; install "SoundMixer",1,1
- # BUG? i may have the channels (left,right) backwards
- def initialize(filename)
- super
- @file = File.open filename.to_s, 0
- @file.extend Linux::SoundMixer
- $sm = self
- end
- @@vars = Linux::SoundMixer.instance_methods.grep(/=/)
- @@vars_h = {}
- @@vars.each {|attr|
- attr.chop!
- eval %{ def _0_#{attr}(x) @file.#{attr} = x[0]*256+x[1] end }
- @@vars_h[attr]=true
- }
- def _0_get(sel=nil)
- if sel then
- sels=sel.to_s
- sel=sels.intern
- raise if not @@vars_h.include? sel.to_s
- begin
- x = @file.send sel
- send_out 0, sel, "(".intern, (x>>8)&255, x&255, ")".intern
- rescue
- send_out 0, sel, "(".intern, -1, -1, ")".intern
- end
- else
- @@vars.each {|var| _0_get var }
- end
- end
-end#}
-
-# experimental
-FObject.subclass("rubyarray",2,1) {
- def initialize() @a=[]; @i=0; end
- def _0_float i; @i=i; send_out 0, *@a[@i]; end
- def _1_list(*l) @a[@i]=l; end
- def _0_save(filename,format=nil)
- f=File.open(filename.to_s,"w")
- if format then
- @a.each {|x| f.puts(format.to_s%x) }
- else
- @a.each {|x| f.puts(x.join(",")) }
- end
- f.close
- end
- def _0_load(filename)
- f=File.open(filename.to_s,"r")
- @a.clear
- f.each {|x| @a.push x.split(",").map {|y| Float(y) rescue y.intern }}
- f.close
- end
-}
-
-FObject.subclass("regsub",3,1) {
- def initialize(from,to) _1_symbol(from); _2_symbol(to) end
- def _0_symbol(s) send_out 0, :symbol, s.to_s.gsub(@from, @to).intern end
- def _1_symbol(from) @from = Regexp.new(from.to_s.gsub(/`/,"\\")) end
- def _2_symbol(to) @to = to.to_s.gsub(/`/,"\\") end
- doc:_0_symbol,"a string to transform"
- doc:_1_symbol,"a regexp pattern to be found inside of the string"
- doc:_2_symbol,"a replacement for the found pattern"
- doc_out:_0_symbol,"the transformed string"
-}
-
-FObject.subclass("memstat",1,1) {
- def _0_bang
- f = File.open("/proc/#{$$}/stat")
- send_out 0, Float(f.gets.split(" ")[22]) / 1024.0
- f.close
- end
- doc:_0_bang,"lookup process stats for the currently running pd+ruby "+
- "and figure out how much RAM it uses."
- doc_out:_0_float,"virtual size of RAM in kilobytes (includes swapped out and shared memory)"
-}
-
-FObject.subclass("sendgui",1,0) {
- def _0_list(*x)
- GridFlow.gui x.join(" ").gsub(/`/,";")+"\n"
- end
- install "sys_vgui", 1, 0
- doc:_0_list,"a Tcl/Tk command to send to the pd client."
-}
-
-end # module GridFlow
-
-begin
- require "gridflow/rblti"
- GridFlow.post "Ruby-LTI support loaded."
-rescue Exception => e
- #GridFlow.post "%s", e.inspect
- #GridFlow.post "(rblti not found)"
-end
diff --git a/externals/gridflow/base/flow_objects_for_image.c b/externals/gridflow/base/flow_objects_for_image.c
deleted file mode 100644
index f6d6398d..00000000
--- a/externals/gridflow/base/flow_objects_for_image.c
+++ /dev/null
@@ -1,619 +0,0 @@
-/*
- $Id: flow_objects_for_image.c,v 1.2 2006-03-15 04:37:08 matju Exp $
-
- GridFlow
- Copyright (c) 2001,2002,2003,2004,2005 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 <math.h>
-#include "grid.h.fcs"
-
-static void expect_picture (P<Dim> d) {
- if (d->n!=3) RAISE("(height,width,chans) dimensions please");}
-static void expect_rgb_picture (P<Dim> d) {
- expect_picture(d);
- if (d->get(2)!=3) RAISE("(red,green,blue) channels please");}
-static void expect_rgba_picture (P<Dim> d) {
- expect_picture(d);
- if (d->get(2)!=4) RAISE("(red,green,blue,alpha) channels please");}
-static void expect_max_one_dim (P<Dim> d) {
- if (d->n>1) { RAISE("expecting Dim[] or Dim[n], got %s",d->to_s()); }}
-
-//****************************************************************
-//{ Dim[A,B,*Cs]<T>,Dim[D,E]<T> -> Dim[A,B,*Cs]<T> }
-
-static void expect_convolution_matrix (P<Dim> d) {
- if (d->n != 2) RAISE("only exactly two dimensions allowed for now (got %d)",
- d->n);
-}
-
-// entry in a compiled convolution kernel
-struct PlanEntry { int y,x; bool neutral; };
-
-\class GridConvolve < GridObject
-struct GridConvolve : GridObject {
- \attr Numop *op_para;
- \attr Numop *op_fold;
- \attr PtrGrid seed;
- \attr PtrGrid b;
- PtrGrid a;
- int plann;
- PlanEntry *plan; //Pt?
- int margx,margy; // margins
- GridConvolve () : plan(0) { b.constrain(expect_convolution_matrix); plan=0; }
- \decl void initialize (Grid *r=0);
- \decl void _0_op (Numop *op);
- \decl void _0_fold (Numop *op);
- \decl void _0_seed (Grid *seed);
- \grin 0
- \grin 1
- template <class T> void copy_row (Pt<T> buf, int sx, int y, int x);
- template <class T> void make_plan (T bogus);
- ~GridConvolve () {if (plan) delete[] plan;}
-};
-
-template <class T> void GridConvolve::copy_row (Pt<T> buf, int sx, int y, int x) {
- int day = a->dim->get(0), dax = a->dim->get(1), dac = a->dim->prod(2);
- y=mod(y,day); x=mod(x,dax);
- Pt<T> ap = (Pt<T>)*a + y*dax*dac;
- while (sx) {
- int sx1 = min(sx,dax-x);
- COPY(buf,ap+x*dac,sx1*dac);
- x=0;
- buf += sx1*dac;
- sx -= sx1;
- }
-}
-
-static Numop *OP(Ruby x) {return FIX2PTR(Numop,rb_hash_aref(op_dict,x));}
-
-template <class T> void GridConvolve::make_plan (T bogus) {
- P<Dim> da = a->dim, db = b->dim;
- int dby = db->get(0);
- int dbx = db->get(1);
- if (plan) delete[] plan;
- plan = new PlanEntry[dbx*dby];
- int i=0;
- for (int y=0; y<dby; y++) {
- for (int x=0; x<dbx; x++) {
- T rh = ((Pt<T>)*b)[y*dbx+x];
- bool neutral = op_para->on(rh)->is_neutral(rh,at_right);
- bool absorbent = op_para->on(rh)->is_absorbent(rh,at_right);
- STACK_ARRAY(T,foo,1);
- if (absorbent) {
- foo[0] = 0;
- op_para->map(1,foo,rh);
- absorbent = op_fold->on(rh)->is_neutral(foo[0],at_right);
- }
- if (absorbent) continue;
- plan[i].y = y;
- plan[i].x = x;
- plan[i].neutral = neutral;
- i++;
- }
- }
- plann = i;
-}
-
-GRID_INLET(GridConvolve,0) {
- SAME_TYPE(in,b);
- SAME_TYPE(in,seed);
- P<Dim> da = in->dim, db = b->dim;
- if (!db) RAISE("right inlet has no grid");
- if (!seed) RAISE("seed missing");
- if (db->n != 2) RAISE("right grid must have two dimensions");
- if (da->n < 2) RAISE("left grid has less than two dimensions");
- if (seed->dim->n != 0) RAISE("seed must be scalar");
- if (da->get(0) < db->get(0)) RAISE("grid too small (y): %d < %d", da->get(0), db->get(0));
- if (da->get(1) < db->get(1)) RAISE("grid too small (x): %d < %d", da->get(1), db->get(1));
- margy = (db->get(0)-1)/2;
- margx = (db->get(1)-1)/2;
- a=new Grid(in->dim,in->nt);
- out=new GridOutlet(this,0,da,in->nt);
-} GRID_FLOW {
- COPY((Pt<T>)*a+in->dex, data, n);
-} GRID_FINISH {
- Numop *op_put = OP(SYM(put));
- make_plan((T)0);
- int dbx = b->dim->get(1);
- int day = a->dim->get(0);
- int n = a->dim->prod(1);
- int sx = a->dim->get(1)+dbx-1;
- int n2 = sx*a->dim->prod(2);
- STACK_ARRAY(T,buf,n);
- STACK_ARRAY(T,buf2,n2);
- T orh=0;
- for (int iy=0; iy<day; iy++) {
- op_put->map(n,buf,*(T *)*seed);
- for (int i=0; i<plann; i++) {
- int jy = plan[i].y;
- int jx = plan[i].x;
- T rh = ((Pt<T>)*b)[jy*dbx+jx];
- if (i==0 || plan[i].y!=plan[i-1].y || orh!=rh) {
- copy_row(buf2,sx,iy+jy-margy,-margx);
- if (!plan[i].neutral) op_para->map(n2,buf2,rh);
- }
- op_fold->zip(n,buf,buf2+jx*a->dim->prod(2));
- orh=rh;
- }
- out->send(n,buf);
- }
- a=0;
-} GRID_END
-
-GRID_INPUT(GridConvolve,1,b) {} GRID_END
-
-\def void _0_op (Numop *op ) { this->op_para=op; }
-\def void _0_fold (Numop *op ) { this->op_fold=op; }
-\def void _0_seed (Grid *seed) { this->seed=seed; }
-
-\def void initialize (Grid *r) {
- rb_call_super(argc,argv);
- this->op_para = op_mul;
- this->op_fold = op_add;
- this->seed = new Grid(new Dim(),int32_e,true);
- this->b= r ? r : new Grid(new Dim(1,1),int32_e,true);
-}
-
-\classinfo { IEVAL(rself,"install '#convolve',2,1"); }
-\end class GridConvolve
-
-/* ---------------------------------------------------------------- */
-/* "#scale_by" does quick scaling of pictures by integer factors */
-/*{ Dim[A,B,3]<T> -> Dim[C,D,3]<T> }*/
-\class GridScaleBy < GridObject
-struct GridScaleBy : GridObject {
- \attr PtrGrid scale; // integer scale factor
- int scaley;
- int scalex;
- \decl void initialize (Grid *factor=0);
- \grin 0
- \grin 1
- void prepare_scale_factor () {
- scaley = ((Pt<int32>)*scale)[0];
- scalex = ((Pt<int32>)*scale)[scale->dim->prod()==1 ? 0 : 1];
- if (scaley<1) scaley=2;
- if (scalex<1) scalex=2;
- }
-};
-
-GRID_INLET(GridScaleBy,0) {
- P<Dim> a = in->dim;
- expect_picture(a);
- out=new GridOutlet(this,0,new Dim(a->get(0)*scaley,a->get(1)*scalex,a->get(2)),in->nt);
- in->set_factor(a->get(1)*a->get(2));
-} GRID_FLOW {
- int rowsize = in->dim->prod(1);
- STACK_ARRAY(T,buf,rowsize*scalex);
- int chans = in->dim->get(2);
- #define Z(z) buf[p+z]=data[i+z]
- for (; n>0; data+=rowsize, n-=rowsize) {
- int p=0;
- #define LOOP(z) \
- for (int i=0; i<rowsize; i+=z) \
- for (int k=0; k<scalex; k++, p+=z)
- switch (chans) {
- case 3: LOOP(3) {Z(0);Z(1);Z(2);} break;
- case 4: LOOP(4) {Z(0);Z(1);Z(2);Z(3);} break;
- default: LOOP(chans) {for (int c=0; c<chans; c++) Z(c);}
- }
- #undef LOOP
- for (int j=0; j<scaley; j++) out->send(rowsize*scalex,buf);
- }
- #undef Z
-} GRID_END
-
-static void expect_scale_factor (P<Dim> dim) {
- if (dim->prod()!=1 && dim->prod()!=2)
- RAISE("expecting only one or two numbers");
-}
-
-GRID_INPUT(GridScaleBy,1,scale) { prepare_scale_factor(); } GRID_END
-
-\def void initialize (Grid *factor) {
- scale.constrain(expect_scale_factor);
- rb_call_super(argc,argv);
- scale=new Grid(INT2NUM(2));
- if (factor) scale=factor;
- prepare_scale_factor();
-}
-
-\classinfo { IEVAL(rself,"install '#scale_by',2,1"); }
-\end class GridScaleBy
-
-// ----------------------------------------------------------------
-//{ Dim[A,B,3]<T> -> Dim[C,D,3]<T> }
-\class GridDownscaleBy < GridObject
-struct GridDownscaleBy : GridObject {
- \attr PtrGrid scale;
- \attr bool smoothly;
- int scaley;
- int scalex;
- PtrGrid temp;
- \decl void initialize (Grid *factor=0, Symbol option=Qnil);
- \grin 0
- \grin 1
- void prepare_scale_factor () {
- scaley = ((Pt<int32>)*scale)[0];
- scalex = ((Pt<int32>)*scale)[scale->dim->prod()==1 ? 0 : 1];
- if (scaley<1) scaley=2;
- if (scalex<1) scalex=2;
- }
-};
-
-GRID_INLET(GridDownscaleBy,0) {
-
- P<Dim> a = in->dim;
- if (a->n!=3) RAISE("(height,width,chans) please");
- out=new GridOutlet(this,0,new Dim(a->get(0)/scaley,a->get(1)/scalex,a->get(2)),in->nt);
- in->set_factor(a->get(1)*a->get(2));
- // i don't remember why two rows instead of just one.
- temp=new Grid(new Dim(2,in->dim->get(1)/scalex,in->dim->get(2)),in->nt);
-} GRID_FLOW {
- int rowsize = in->dim->prod(1);
- int rowsize2 = temp->dim->prod(1);
- Pt<T> buf = (Pt<T>)*temp; //!@#$ maybe should be something else than T ?
- int xinc = in->dim->get(2)*scalex;
- int y = in->dex / rowsize;
- int chans=in->dim->get(2);
- #define Z(z) buf[p+z]+=data[i+z]
- if (smoothly) {
- while (n>0) {
- if (y%scaley==0) CLEAR(buf,rowsize2);
- #define LOOP(z) \
- for (int i=0,p=0; p<rowsize2; p+=z) \
- for (int j=0; j<scalex; j++,i+=z)
- switch (chans) {
- case 1: LOOP(1) {Z(0);} break;
- case 2: LOOP(2) {Z(0);Z(1);} break;
- case 3: LOOP(3) {Z(0);Z(1);Z(2);} break;
- case 4: LOOP(4) {Z(0);Z(1);Z(2);Z(3);} break;
- default:LOOP(chans) {for (int k=0; k<chans; k++) Z(k);} break;
- }
- #undef LOOP
- y++;
- if (y%scaley==0 && out->dim) {
- op_div->map(rowsize2,buf,(T)(scalex*scaley));
- out->send(rowsize2,buf);
- CLEAR(buf,rowsize2);
- }
- data+=rowsize;
- n-=rowsize;
- }
- #undef Z
- } else {
- #define Z(z) buf[p+z]=data[i+z]
- for (; n>0 && out->dim; data+=rowsize, n-=rowsize,y++) {
- if (y%scaley!=0) continue;
- #define LOOP(z) for (int i=0,p=0; p<rowsize2; i+=xinc, p+=z)
- switch(in->dim->get(2)) {
- case 1: LOOP(1) {Z(0);} break;
- case 2: LOOP(2) {Z(0);Z(1);} break;
- case 3: LOOP(3) {Z(0);Z(1);Z(2);} break;
- case 4: LOOP(4) {Z(0);Z(1);Z(2);Z(3);} break;
- default:LOOP(chans) {for (int k=0; k<chans; k++) Z(k);}break;
- }
- #undef LOOP
- out->send(rowsize2,buf);
- }
- }
- #undef Z
-} GRID_END
-
-GRID_INPUT(GridDownscaleBy,1,scale) { prepare_scale_factor(); } GRID_END
-
-\def void initialize (Grid *factor, Symbol option) {
- scale.constrain(expect_scale_factor);
- rb_call_super(argc,argv);
- scale=new Grid(INT2NUM(2));
- if (factor) scale=factor;
- prepare_scale_factor();
- smoothly = option==SYM(smoothly);
-}
-
-\classinfo { IEVAL(rself,"install '#downscale_by',2,1"); }
-\end class GridDownscaleBy
-
-//****************************************************************
-\class GridLayer < GridObject
-struct GridLayer : GridObject {
- PtrGrid r;
- GridLayer() { r.constrain(expect_rgb_picture); }
- \grin 0 int
- \grin 1 int
-};
-
-GRID_INLET(GridLayer,0) {
- NOTEMPTY(r);
- SAME_TYPE(in,r);
- P<Dim> a = in->dim;
- expect_rgba_picture(a);
- if (a->get(1)!=r->dim->get(1)) RAISE("same width please");
- if (a->get(0)!=r->dim->get(0)) RAISE("same height please");
- in->set_factor(a->prod(2));
- out=new GridOutlet(this,0,r->dim);
-} GRID_FLOW {
- Pt<T> rr = ((Pt<T>)*r) + in->dex*3/4;
- STACK_ARRAY(T,foo,n*3/4);
-#define COMPUTE_ALPHA(c,a) \
- foo[j+c] = (data[i+c]*data[i+a] + rr[j+c]*(256-data[i+a])) >> 8
- for (int i=0,j=0; i<n; i+=4,j+=3) {
- COMPUTE_ALPHA(0,3);
- COMPUTE_ALPHA(1,3);
- COMPUTE_ALPHA(2,3);
- }
-#undef COMPUTE_ALPHA
- out->send(n*3/4,foo);
-} GRID_END
-
-GRID_INPUT(GridLayer,1,r) {} GRID_END
-
-\classinfo { IEVAL(rself,"install '#layer',2,1"); }
-\end class GridLayer
-
-// ****************************************************************
-// pad1,pad2 only are there for 32-byte alignment
-struct Line { int32 y1,x1,y2,x2,x,m,pad1,pad2; };
-
-static void expect_polygon (P<Dim> d) {
- if (d->n!=2 || d->get(1)!=2) RAISE("expecting Dim[n,2] polygon");
-}
-
-\class DrawPolygon < GridObject
-struct DrawPolygon : GridObject {
- \attr Numop *op;
- \attr PtrGrid color;
- \attr PtrGrid polygon;
- PtrGrid color2;
- PtrGrid lines;
- int lines_start;
- int lines_stop;
- DrawPolygon() {
- color.constrain(expect_max_one_dim);
- polygon.constrain(expect_polygon);
- }
- \decl void initialize (Numop *op, Grid *color=0, Grid *polygon=0);
- \grin 0
- \grin 1
- \grin 2 int32
- void init_lines();
-
-};
-
-void DrawPolygon::init_lines () {
- int nl = polygon->dim->get(0);
- lines=new Grid(new Dim(nl,8), int32_e);
- Pt<Line> ld = Pt<Line>((Line *)(int32 *)*lines,nl);
- Pt<int32> pd = *polygon;
- for (int i=0,j=0; i<nl; i++) {
- ld[i].y1 = pd[j+0];
- ld[i].x1 = pd[j+1];
- j=(j+2)%(2*nl);
- ld[i].y2 = pd[j+0];
- ld[i].x2 = pd[j+1];
- if (ld[i].y1>ld[i].y2) memswap(Pt<int32>(ld+i)+0,Pt<int32>(ld+i)+2,2);
- }
-}
-
-static int order_by_starting_scanline (const void *a, const void *b) {
- return ((Line *)a)->y1 - ((Line *)b)->y1;
-}
-
-static int order_by_column (const void *a, const void *b) {
- return ((Line *)a)->x - ((Line *)b)->x;
-}
-
-GRID_INLET(DrawPolygon,0) {
- NOTEMPTY(color);
- NOTEMPTY(polygon);
- NOTEMPTY(lines);
- SAME_TYPE(in,color);
- if (in->dim->n!=3) RAISE("expecting 3 dimensions");
- if (in->dim->get(2)!=color->dim->get(0))
- RAISE("image does not have same number of channels as stored color");
- out=new GridOutlet(this,0,in->dim,in->nt);
- lines_start = lines_stop = 0;
- in->set_factor(in->dim->get(1)*in->dim->get(2));
- int nl = polygon->dim->get(0);
- qsort((int32 *)*lines,nl,sizeof(Line),order_by_starting_scanline);
- int cn = color->dim->prod();
- color2=new Grid(new Dim(cn*16), color->nt);
- for (int i=0; i<16; i++) COPY((Pt<T>)*color2+cn*i,(Pt<T>)*color,cn);
-} GRID_FLOW {
- int nl = polygon->dim->get(0);
- Pt<Line> ld = Pt<Line>((Line *)(int32 *)*lines,nl);
- int f = in->factor();
- int y = in->dex/f;
- int cn = color->dim->prod();
- Pt<T> cd = (Pt<T>)*color2;
-
- while (n) {
- while (lines_stop != nl && ld[lines_stop].y1<=y) lines_stop++;
- for (int i=lines_start; i<lines_stop; i++) {
- if (ld[i].y2<=y) {
- memswap(ld+i,ld+lines_start,1);
- lines_start++;
- }
- }
- if (lines_start == lines_stop) {
- out->send(f,data);
- } else {
- int32 xl = in->dim->get(1);
- Pt<T> data2 = ARRAY_NEW(T,f);
- COPY(data2,data,f);
- for (int i=lines_start; i<lines_stop; i++) {
- Line &l = ld[i];
- l.x = l.x1 + (y-l.y1)*(l.x2-l.x1+1)/(l.y2-l.y1+1);
- }
- qsort(ld+lines_start,lines_stop-lines_start,
- sizeof(Line),order_by_column);
- for (int i=lines_start; i<lines_stop-1; i+=2) {
- int xs = max(ld[i].x,(int32)0), xe = min(ld[i+1].x,xl);
- if (xs>=xe) continue; /* !@#$ WHAT? */
- while (xe-xs>=16) { op->zip(16*cn,data2+cn*xs,cd); xs+=16; }
- op->zip((xe-xs)*cn,data2+cn*xs,cd);
- }
- out->give(f,data2);
- }
- n-=f;
- data+=f;
- y++;
- }
-} GRID_END
-
-
-GRID_INPUT(DrawPolygon,1,color) {} GRID_END
-GRID_INPUT(DrawPolygon,2,polygon) {init_lines();} GRID_END
-
-\def void initialize (Numop *op, Grid *color, Grid *polygon) {
- rb_call_super(argc,argv);
- this->op = op;
- if (color) this->color=color;
- if (polygon) { this->polygon=polygon; init_lines(); }
-}
-
-\classinfo { IEVAL(rself,"install '#draw_polygon',3,1"); }
-\end class DrawPolygon
-
-//****************************************************************
-static void expect_position(P<Dim> d) {
- if (d->n!=1) RAISE("position should have 1 dimension, not %d", d->n);
- if (d->v[0]!=2) RAISE("position dim 0 should have 2 elements, not %d", d->v[0]);
-}
-
-\class DrawImage < GridObject
-struct DrawImage : GridObject {
- \attr Numop *op;
- \attr PtrGrid image;
- \attr PtrGrid position;
- \attr bool alpha;
- \attr bool tile;
-
- DrawImage() : alpha(false), tile(false) {
- position.constrain(expect_position);
- image.constrain(expect_picture);
- }
-
- \decl void initialize (Numop *op, Grid *image=0, Grid *position=0);
- \decl void _0_alpha (bool v=true);
- \decl void _0_tile (bool v=true);
- \grin 0
- \grin 1
- \grin 2 int32
- // draw row # ry of right image in row buffer buf, starting at xs
- // overflow on both sides has to be handled automatically by this method
- template <class T> void draw_segment(Pt<T> obuf, Pt<T> ibuf, int ry, int x0);
-};
-
-#define COMPUTE_ALPHA(c,a) obuf[j+(c)] = ibuf[j+(c)] + (rbuf[a])*(obuf[j+(c)]-ibuf[j+(c)])/256;
-#define COMPUTE_ALPHA4(b) \
- COMPUTE_ALPHA(b+0,b+3); \
- COMPUTE_ALPHA(b+1,b+3); \
- COMPUTE_ALPHA(b+2,b+3); \
- obuf[b+3] = rbuf[b+3] + (255-rbuf[b+3])*(ibuf[j+b+3])/256;
-
-template <class T> void DrawImage::draw_segment(Pt<T> obuf, Pt<T> ibuf, int ry, int x0) {
- if (ry<0 || ry>=image->dim->get(0)) return; // outside of image
- int sx = in[0]->dim->get(1), rsx = image->dim->get(1);
- int sc = in[0]->dim->get(2), rsc = image->dim->get(2);
- Pt<T> rbuf = (Pt<T>)*image + ry*rsx*rsc;
- if (x0>sx || x0<=-rsx) return; // outside of buffer
- int n=rsx;
- if (x0+n>sx) n=sx-x0;
- if (x0<0) { rbuf-=rsc*x0; n+=x0; x0=0; }
- if (alpha && rsc==4 && sc==3) { // RGB by RGBA //!@#$ optimise
- int j=sc*x0;
- for (; n; n--, rbuf+=4, j+=3) {
- op->zip(sc,obuf+j,rbuf); COMPUTE_ALPHA(0,3); COMPUTE_ALPHA(1,3); COMPUTE_ALPHA(2,3);
- }
- } else if (alpha && rsc==4 && sc==4) { // RGBA by RGBA
- op->zip(n*rsc,obuf+x0*rsc,rbuf);
- int j=sc*x0;
- for (; n>=4; n-=4, rbuf+=16, j+=16) {
- COMPUTE_ALPHA4(0);COMPUTE_ALPHA4(4);
- COMPUTE_ALPHA4(8);COMPUTE_ALPHA4(12);
- }
- for (; n; n--, rbuf+=4, j+=4) {
- COMPUTE_ALPHA4(0);
- }
- } else { // RGB by RGB, etc
- op->zip(n*rsc,obuf+sc*x0,rbuf);
- }
-}
-
-GRID_INLET(DrawImage,0) {
- NOTEMPTY(image);
- NOTEMPTY(position);
- SAME_TYPE(in,image);
- if (in->dim->n!=3) RAISE("expecting 3 dimensions");
- int lchan = in->dim->get(2);
- int rchan = image->dim->get(2);
- if (alpha && rchan!=4) {
- RAISE("alpha mode works only with 4 channels in right_hand");
- }
- if (lchan != rchan-(alpha?1:0) && lchan != rchan) {
- RAISE("right_hand has %d channels, alpha=%d, left_hand has %d, expecting %d or %d",
- rchan, alpha?1:0, lchan, rchan-(alpha?1:0), rchan);
- }
- out=new GridOutlet(this,0,in->dim,in->nt);
- in->set_factor(in->dim->get(1)*in->dim->get(2));
-} GRID_FLOW {
- int f = in->factor();
- int y = in->dex/f;
- if (position->nt != int32_e) RAISE("position has to be int32");
- int py = ((int32*)*position)[0], rsy = image->dim->v[0], sy=in->dim->get(0);
- int px = ((int32*)*position)[1], rsx = image->dim->v[1], sx=in->dim->get(1);
- for (; n; y++, n-=f, data+=f) {
- int ty = div2(y-py,rsy);
- if (tile || ty==0) {
- Pt<T> data2 = ARRAY_NEW(T,f);
- COPY(data2,data,f);
- if (tile) {
- for (int x=px-div2(px+rsx-1,rsx)*rsx; x<sx; x+=rsx) {
- draw_segment(data2,data,mod(y-py,rsy),x);
- }
- } else {
- draw_segment(data2,data,y-py,px);
- }
- out->give(f,data2);
- } else {
- out->send(f,data);
- }
- }
-} GRID_END
-
-GRID_INPUT(DrawImage,1,image) {} GRID_END
-GRID_INPUT(DrawImage,2,position) {} GRID_END
-\def void _0_alpha (bool v=true) { alpha = v; gfpost("ALPHA=%d",v); }
-\def void _0_tile (bool v=true) { tile = v; }
-
-\def void initialize (Numop *op, Grid *image, Grid *position) {
- rb_call_super(argc,argv);
- this->op = op;
- if (image) this->image=image;
- if (position) this->position=position;
- else this->position=new Grid(new Dim(2),int32_e,true);
-}
-
-\classinfo { IEVAL(rself,"install '#draw_image',3,1"); }
-\end class DrawImage
-
-void startup_flow_objects_for_image () {
- \startall
-}
diff --git a/externals/gridflow/base/flow_objects_for_matrix.c b/externals/gridflow/base/flow_objects_for_matrix.c
deleted file mode 100644
index b88accba..00000000
--- a/externals/gridflow/base/flow_objects_for_matrix.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- $Id: flow_objects_for_matrix.c,v 1.2 2006-03-15 04:37:08 matju Exp $
-
- GridFlow
- Copyright (c) 2001,2002,2003 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 <math.h>
-#include "grid.h.fcs"
-
-// produce an upper triangular matrix with ones on the diagonal
-// will also affect any additional columns using the same row-operations
-
-void expect_complete_matrix (P<Dim> d) {
- if (d->n!=2) RAISE("bletch");
- if (d->get(0)>d->get(1)) RAISE("argh");
-}
-
-\class GridMatrixSolve < GridObject
-struct GridMatrixSolve : GridObject {
- Numop *op_sub;
- Numop *op_mul;
- Numop *op_div;
- PtrGrid matrix;
- GridMatrixSolve() {
- matrix.constrain(expect_complete_matrix);
- }
- \decl void initialize ();
- \grin 0 float
-};
-
-GRID_INPUT(GridMatrixSolve,0,matrix) {
- int n = matrix->dim->get(0); // # rows
- int m = matrix->dim->get(1); // # columns
- Pt<T> mat = (Pt<T>)*matrix;
- for (int j=0; j<n; j++) {
- op_div->map(m,mat+j*m,mat[j*m+j]);
- for (int i=j+1; i<n; i++) {
- STACK_ARRAY(T,row,m);
- COPY(row,mat+j,m);
- op_mul->map(m,row,mat[i*m+j]);
- op_sub->zip(m,mat+i*m,row);
- }
- }
- GridOutlet out(this,0,matrix->dim);
- out.send(n*m,mat);
-} GRID_END
-
-\def void initialize () {
- rb_call_super(argc,argv);
- this->op_sub = op_sub;
- this->op_mul = op_mul;
- this->op_div = op_div;
-}
-
-\classinfo { IEVAL(rself,"install '#matrix_solve',1,1"); }
-\end class
-
-void startup_flow_objects_for_matrix () {
- \startall
-}
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 <stdlib.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include "grid.h.fcs"
-#include <ctype.h>
-
-/* 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; i<n; i++) {
- if (a[i] == delim) {
- STACK_ARRAY(int32,v,i);
- if (i!=0 && TYPE(a[i-1])==T_SYMBOL) nt=NumberTypeE_find(a[--i]);
- for (int j=0; j<i; j++) v[j] = convert(a[j],(int32*)0);
- init(new Dim(i,v),nt);
- CHECK_ALIGN2(this->data,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<type> p = (Pt<type>)*this; \
- if (n==0) CLEAR(p,nn); \
- else { \
- for (int i=0; i<n; i++) NUM(a[i],p[i]); \
- for (int i=n; i<nn; i+=n) COPY(p+i,p,min(n,nn-i)); }}
- TYPESWITCH(nt,FOO,)
-#undef FOO
-}
-
-void Grid::init_from_ruby(Ruby x) {
- if (TYPE(x)==T_ARRAY) {
- init_from_ruby_list(rb_ary_len(x),rb_ary_ptr(x));
- } else if (INTEGER_P(x) || FLOAT_P(x)) {
- init(new Dim(),int32_e);
- CHECK_ALIGN2(this->data,nt);
- ((Pt<int32>)*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<T>()); 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<argc; i++) v[i] = NUM2INT(argv[i]);
- P<Dim> 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 <class T> void GridInlet::flow(int mode, int n, Pt<T> 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<T> bufd = (Pt<T>)*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<T> 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<T> 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<T>)*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<T>());
- TYPESWITCH(nt,FOO,)
-#undef FOO
- } // PROF
- dim=0;
- buf=0;
- dex=0;
-}
-
-template <class T> 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<T>());
- if (n>0 && this->mode!=0) {
- Pt<T> data = (Pt<T>)*g;
- CHECK_ALIGN(data);
- int size = g->dim->prod();
- if (this->mode==6) {
- Pt<T> 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<T>());
- //!@#$ 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> 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; i<n; i++) a[4+i] = INT2NUM(dim->get(i));
- parent->send_out(COUNT(a),a);
- frozen=true;
- if (!dim->prod()) {end(); return;}
- int32 lcm_factor = 1;
- for (uint32 i=0; i<inlets.size(); i++) lcm_factor = lcm(lcm_factor,inlets[i]->factor());
- 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 <class T>
-void GridOutlet::send_direct(int n, Pt<T> 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; i<inlets.size(); i++) inlets[i]->flow(4,pn,data);
- data+=pn, n-=pn;
- }
-}
-
-void GridOutlet::flush() {TRACE;
- if (!bufi) return;
-#define FOO(T) send_direct(bufi,(Pt<T>)*buf);
- TYPESWITCH(buf->nt,FOO,)
-#undef FOO
- bufi = 0;
-}
-
-template <class T, class S>
-static void convert_number_type(int n, Pt<T> out, Pt<S> in) {
- for (int i=0; i<n; i++) out[i]=(T)in[i];
-}
-
-//!@#$ buffering in outlet still is 8x faster...?
-//!@#$ should use BitPacking for conversion...?
-// send modifies dex; send_direct doesn't
-template <class T>
-void GridOutlet::send(int n, Pt<T> 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<T>)*buf+bufi,data,n);
- bufi += n;
- }
- if (dex==dim->prod()) end();
- }
-}
-
-template <class T>
-void GridOutlet::give(int n, Pt<T> 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 <class T>
-void GridObject_r_flow(GridInlet *in, int n, Pt<T> data) {
- GridObject *self = in->parent;
- uint32 i;
- for (i=0; i<self->in.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<GridInlet> 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<GridInlet> 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; i<n; i++) rb_ary_push(a,INT2NUM(inl->dim->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<GridInlet> 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<n; i++) v[i] = convert(p[i],(int32*)0);
- out = new GridOutlet(this,outlet,new Dim(n,v),nt); // valgrind says leak?
-}
-
-template <class T>
-void send_out_grid_flow_2(P<GridOutlet> go, Ruby s, T bogus) {
- int n = rb_str_len(s) / sizeof(T);
- Pt<T> 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); i++) {
- Ruby ghp = rb_ary_ptr(handlers)[i];
- if (ghp==Qnil) continue;
- GridHandler *gh = FIX2PTR(GridHandler,ghp);
- char buf[256];
- for (int j=0; j<COUNT(names); j++) {
- sprintf(buf,"_%d_%s",i,names[j]);
- rb_ary_push(list,rb_str_new2(buf));
- }
- }
- return list;
-}
-
-// this does auto-conversion of list/float to grid
-// this also (will) do grid inputs for ruby stuff.
-\def Ruby method_missing (...) {
- {
- if (argc<1) RAISE("not enough arguments");
- if (!SYMBOL_P(argv[0])) RAISE("expected symbol");
- const char *name = rb_sym_name(argv[0]);
- char *endp;
- if (*name++!='_') goto hell;
- int i = strtol(name,&endp,10);
- if (name==endp) goto hell;
- if (*endp++!='_') goto hell;
- if (strcmp(endp,"grid")==0) {
- Ruby handlers = rb_ivar_get(rb_obj_class(rself),SI(@handlers));
- if (TYPE(handlers)!=T_ARRAY) {
- rb_p(handlers);
- RAISE("gridhandler-list missing (maybe forgot install_rgrid ?)"
- " while trying to receive on inlet %d",i);
- }
- if (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<GridInlet> 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<S>());
-EACH_NUMBER_TYPE(FOO)
-#undef FOO
-}
-
diff --git a/externals/gridflow/base/grid.h b/externals/gridflow/base/grid.h
deleted file mode 100644
index 9e971b99..00000000
--- a/externals/gridflow/base/grid.h
+++ /dev/null
@@ -1,1146 +0,0 @@
-/*
- $Id: grid.h,v 1.2 2006-03-15 04:37:08 matju Exp $
-
- GridFlow
- Copyright (c) 2001,2002,2003,2004,2005 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.
-*/
-
-#ifndef __GF_GRID_H
-#define __GF_GRID_H
-
-// current version number as string literal
-#define GF_VERSION "0.8.1"
-#define GF_COMPILE_TIME __DATE__ ", " __TIME__
-
-#include <new>
-#include <vector>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-#include <stdio.h>
-#include <math.h>
-
-#ifdef __APPLE__
-static inline void *memalign (size_t a, size_t n) {return malloc(n);}
-#else
-#include <malloc.h>
-#endif
-
-extern "C" {
-#include <ruby.h>
-#include <rubyio.h>
-#include <version.h>
-};
-
-#ifndef RUBY_H
-#error "Can't do anything without ruby.h"
-#endif
-
-#include "../config.h"
-
-#ifdef __WIN32__
-#define INT winINT
-#define random rand
-#undef send
-#undef close
-#define sigjmp_buf jmp_buf
-#define siglongjmp longjmp
-#endif
-
-#define BUG(s,args...) {fprintf(stderr,s "\nat: %s\n",args,__PRETTY_FUNCTION__); ::raise(11);}
-#define L gfpost("%s:%d in %s",__FILE__,__LINE__,__PRETTY_FUNCTION__);
-
-#ifdef IS_BRIDGE
-#define RAISE(args...) rb_raise(rb_eArgError,args)
-#else
-#define RAISE(args...) rb_raise0(__FILE__,__LINE__,__PRETTY_FUNCTION__,rb_eArgError,args)
-#endif
-
-// avoid ruby warning
-#ifndef rb_enable_super
-#define rb_enable_super(a,b) \
- if (RUBY_RELEASE_CODE < 20030716) rb_enable_super(a,b)
-#endif
-
-typedef VALUE Ruby;
-
-/* undocumented function from Ruby that is one thing we need to fix a very elusive bug
-that manifests itself when embedding ruby inside a plugin of another app. This exists
-for all versions of Ruby up to now, and I don't know when it gets fixed. */
-extern "C" void Init_stack(VALUE *addr);
-
-extern "C" {
-void rb_raise0(
-const char *file, int line, const char *func, VALUE exc, const char *fmt, ...)
-__attribute__ ((noreturn));
-};
-#define SI(_sym_) (rb_intern(#_sym_))
-#define SYM(_sym_) (ID2SYM(SI(_sym_)))
-#define DGS(_class_) \
- _class_ *self; \
- Data_Get_Struct(rself,_class_,self); \
- self->check_magic();
-
-// returns the size of a statically defined array
-// warning: does not work with STACK_ARRAY()
-#define COUNT(_array_) ((int)(sizeof(_array_) / sizeof((_array_)[0])))
-
-static inline long rb_str_len(Ruby s) {return RSTRING(s)->len;}
-static inline char *rb_str_ptr(Ruby s) {return RSTRING(s)->ptr;}
-static inline long rb_ary_len(Ruby s) {return RARRAY(s)->len;}
-static inline Ruby *rb_ary_ptr(Ruby s) {return RARRAY(s)->ptr;}
-static inline const char *rb_sym_name(Ruby sym) {return rb_id2name(SYM2ID(sym));}
-#define rb_str_pt(s,t) Pt<t>((t*)rb_str_ptr(s),rb_str_len(s))
-#define IEVAL(_self_,s) rb_funcall(_self_,SI(instance_eval),1,rb_str_new2(s))
-#define EVAL(s) rb_eval_string(s)
-#define rassert(_p_) if (!(_p_)) RAISE(#_p_);
-// because of older versions of Ruby (1.6.?)
-#define rb_obj_class(o) rb_funcall((o),SI(class),0)
-
-#define WATCH(n,ar) { \
- char foo[16*1024], *p=foo; p += sprintf(p,"%s: ",#ar); \
- for (int q=0; q<n; q++) p += sprintf(p,"%lld ",(long long)ar[q]); \
- gfpost("%s",foo);}
-
-// we're gonna override assert, so load it first, to avoid conflicts
-#include <assert.h>
-
-#undef assert
-#define assert(_expr_) \
- if (!(_expr_)) { \
- fprintf(stderr, "%s:%d: assertion failed: %s is false\n", \
- __FILE__, __LINE__, #_expr_); \
- ::abort(); }
-
-// disabling assertion checking?
-#ifndef HAVE_DEBUG
-#undef assert
-#define assert(_foo_)
-#endif
-
-#ifdef HAVE_TSC_PROFILING
-#define HAVE_PROFILING
-#endif
-
-#ifdef HAVE_PROFILING
-#define PROF(_self_) for (GFStackMarker gf_marker(_self_);gf_marker.once();)
-#else
-#define PROF(_self_)
-#endif // HAVE_PROFILING
-
-static inline Ruby PTR2FIX (const void *ptr) {
- long p = (long)ptr;
- if ((p&3)!=0) BUG("unaligned pointer: %p\n",ptr);
- return LONG2NUM(p>>2);
-}
-#define FIX2PTR(type,ruby) ((type *)(TO(long,ruby)<<2))
-
-//****************************************************************
-
-/* int32 was long before, now int, because of amd64 */
-typedef char int8; typedef unsigned char uint8;
-typedef short int16; typedef unsigned short uint16;
-typedef int int32; typedef unsigned int uint32;
-typedef long long int64;typedef unsigned long long uint64;
-typedef float float32;
-typedef double float64;
-
-// three-way comparison (T is assumed Comparable)
-template <class T> static inline T cmp(T a, T b) { return a<b ? -1 : a>b; }
-
-// a remainder function such that div2(a,b)*b+mod(a,b) = a and for which
-// mod(a,b) is in [0;b) or (b;0]. in contrast to C-language builtin a%b,
-// this one has uniform behaviour around zero.
-static inline int mod(int a, int b) {
-int c=a%b; c+=b&-(c&&(a<0)^(b<0)); return c;}
-
-// counterpart of mod(a,b), just like a/b and a%b are counterparts
-static inline int div2(int a, int b) {
-int c=a<0; return (a/b)-(c&&!!(a%b));}
-
-static inline int32 gf_abs( int32 a) { return a>0?a:-a; }
-static inline int64 gf_abs( int64 a) { return a>0?a:-a; }
-static inline float32 gf_abs(float32 a) { return fabs(a); }
-static inline float64 gf_abs(float64 a) { return fabs(a); }
-
-// integer powers in log(b) time. T is assumed Integer
-template <class T> static inline T ipow(T a, T b) {
- for(T r=1;;) {if (b&1) r*=a; b>>=1; if (!b) return r; a*=a;}
-}
-
-// kludge
-static inline float32 ipow(float32 a, float32 b) { return pow(a,b); }
-static inline float64 ipow(float64 a, float64 b) { return pow(a,b); }
-
-#undef min
-#undef max
-// minimum/maximum functions; T is assumed to be Comparable
-template <class T> static inline T min(T a, T b) { return a<b?a:b; }
-template <class T> static inline T max(T a, T b) { return a>b?a:b; }
-//template <class T> inline T min(T a, T b) { T c = (a-b)>>31; return (a&c)|(b&~c); }
-
-// greatest common divisor, by euclid's algorithm
-// this runs in log(a+b) number operations
-template <class T> static T gcd (T a, T b) {
- while (b) {T c=mod(a,b); a=b; b=c;}
- return a;
-}
-
-// greatest common divisor, the binary algorithm. haven't tried yet.
-template <class T> static T gcd2 (T a, T b) {
- int s=0;
- while ((a|b)&1==0) { a>>=1; b>>=1; s++; }
- while (a) {
- if (a&1==0) a>>=1;
- else if (b&1==0) b>>=1;
- else {T t=abs(a-b); if (a<b) b=t; else a=t;}
- }
- return b<<s;
-}
-
-// least common multiple; this runs in log(a+b) like gcd.
-template <class T> static inline T lcm (T a, T b) {return a*b/gcd(a,b);}
-
-// returns the position (0..31) of highest bit set in a word, or 0 if none.
-#define Z(N) if ((x>>N)&(((typeof(x))1<<N)-1)) { x>>=N; i+=N; }
-static int highest_bit(uint8 x) {int i=0; Z(4)Z(2)Z(1)return i;}
-static int highest_bit(uint16 x) {int i=0; Z(8)Z(4)Z(2)Z(1)return i;}
-static int highest_bit(uint32 x) {int i=0; Z(16)Z(8)Z(4)Z(2)Z(1)return i;}
-static int highest_bit(uint64 x) {int i=0;Z(32)Z(16)Z(8)Z(4)Z(2)Z(1)return i;}
-#undef Z
-// returns the position (0..31) of lowest bit set in a word, or 0 if none.
-template <class T> static int lowest_bit(T n) { return highest_bit((~n+1)&n); }
-
-static double drand() { return 1.0*rand()/(RAND_MAX+1.0); }
-
-// is little-endian
-static inline bool is_le() {int x=1; return ((char *)&x)[0];}
-
-#if defined(HAVE_PENTIUM)
-static inline uint64 rdtsc() {
- uint64 x; __asm__ volatile (".byte 0x0f, 0x31":"=A"(x)); return x;
-}
-#elif defined(HAVE_PPC)
-static inline uint64 rdtsc() {
-#include <mach/mach.h>
-#include <mach/mach_time.h>
-/* see AbsoluteToNanoseconds(), Microseconds()
-http://www.simdtech.org/apps/group_public/email/altivec/msg01956.html
-and mach_absolute_time() and mach_timebase_info(&info),
-then ns=(time*info.numer)/info.denom;
-and the timebase_info is constant
-(double)mach_absolute_time*gTimeBaseToNS*/
-return 0;
-}
-#else
-static inline uint64 rdtsc() {return 0;}
-#endif
-
-#ifdef HAVE_LITE
-#define EACH_INT_TYPE(MACRO) MACRO(uint8) MACRO(int16) MACRO(int32)
-#define EACH_FLOAT_TYPE(MACRO)
-#else
-#define EACH_INT_TYPE(MACRO) MACRO(uint8) MACRO(int16) MACRO(int32) MACRO(int64)
-#define EACH_FLOAT_TYPE(MACRO) MACRO(float32) MACRO(float64)
-#endif
-#define EACH_NUMBER_TYPE(MACRO) EACH_INT_TYPE(MACRO) EACH_FLOAT_TYPE(MACRO) MACRO(ruby)
-
-// note: loop unrolling macros assume N!=0
-// btw this may cause alignment problems when 8 does not divide N
-#define UNROLL_8(MACRO,N,PTR,ARGS...) \
- int n__=(-N)&7; PTR-=n__; N+=n__; \
- switch (n__) { start: \
- case 0:MACRO(0); case 1:MACRO(1); case 2:MACRO(2); case 3:MACRO(3); \
- case 4:MACRO(4); case 5:MACRO(5); case 6:MACRO(6); case 7:MACRO(7); \
- PTR+=8; N-=8; ARGS; if (N) goto start; }
-#define UNROLL_4(MACRO,N,PTR,ARGS...) \
- int n__=(-N)&3; PTR-=n__; N+=n__; \
- switch (n__) { start: \
- case 0:MACRO(0); case 1:MACRO(1); case 2:MACRO(2); case 3:MACRO(3); \
- PTR+=4; N-=4; ARGS; if (N) goto start; }
-
-//****************************************************************
-// my own little Ruby <-> C++ layer
-
-//struct Arg { Ruby a; };
-//struct ArgList { int n; Pt<Arg> v; };
-static inline bool INTEGER_P(Ruby x) {return FIXNUM_P(x)||TYPE(x)==T_BIGNUM;}
-static inline bool FLOAT_P(Ruby x) {return TYPE(x)==T_FLOAT;}
-#define INT(x) TO(int32,x)
-#define TO(t,x) convert(x,(t*)0)
-
-// not using NUM2INT because Ruby can convert Symbol to int
-// (by compatibility with Ruby 1.4)
-static inline int32 convert(Ruby x, int32 *foo) {
- if (INTEGER_P(x)) return NUM2INT(x);
- if (FLOAT_P(x)) return NUM2INT(rb_funcall(x,SI(round),0));
- RAISE("expected Integer or Float (got %s)",
- rb_str_ptr(rb_funcall(x,SI(inspect),0)));
-}
-static int16 convert(Ruby x, int16 *foo) {
- int v = INT(x);
- if (v<-0x8000 || v>=0x8000) RAISE("value %d is out of range",v);
- return v;}
-static uint16 convert(Ruby x, uint16 *foo) {
- int v = INT(x);
- if (v<0 || v>=0x10000) RAISE("value %d is out of range",v);
- return v;}
-static bool convert(Ruby x, bool *foo) {
- if (x==Qtrue) return true;
- if (x==Qfalse) return false;
- switch (TYPE(x)) {
- case T_FIXNUM: case T_BIGNUM: case T_FLOAT: return !!INT(x);
- default: RAISE("can't convert to bool");
- }
-}
-
-#ifdef HAVE_GCC64
-static uint64 convert(Ruby val, uint64 *foo) { return NUM2ULONG(val); }
-static int64 convert(Ruby val, int64 *foo) { return NUM2ULONG(val); }
-static Ruby gf_ull2num(uint64 val) { return ULONG2NUM(val); }
-static Ruby gf_ll2num(uint64 val) { return LONG2NUM(val); }
-#else
-static uint64 convert(Ruby val, uint64 *foo) {
- if (FIXNUM_P(val)) return (uint64)FIX2LONG(val);
- if (TYPE(val)!=T_BIGNUM) RAISE("type error");
- uint64 v = (uint64)NUM2UINT(rb_funcall(val,SI(>>),1,INT2FIX(32))) << 32;
- return v + NUM2UINT(rb_funcall(val,SI(&),1,UINT2NUM(0xffffffff)));}
-static int64 convert(Ruby val, int64 *foo) {
- if (FIXNUM_P(val)) return (int64)FIX2LONG(val);
- if (TYPE(val)!=T_BIGNUM) RAISE("type error");
- int64 v = (int64)NUM2INT(rb_funcall(val,SI(>>),1,INT2FIX(32))) << 32;
- return v + NUM2UINT(rb_funcall(val,SI(&),1,UINT2NUM(0xffffffff)));}
-static Ruby gf_ull2num(uint64 val) {
- Ruby x = rb_funcall(UINT2NUM((uint32)(val>>32)),SI(<<),1,INT2FIX(32));
- return rb_funcall(x,SI(+),1,UINT2NUM((uint32)val));}
-static Ruby gf_ll2num(int64 val) {
- Ruby x = rb_funcall( INT2NUM(( int32)(val>>32)),SI(<<),1,INT2FIX(32));
- return rb_funcall(x,SI(+),1,UINT2NUM((uint32)val));}
-#endif
-
-static long convert(Ruby x, long *foo) {
- return sizeof(long)==sizeof(int32) ?
- convert(x,(int32 *)0) :
- convert(x,(int64 *)0);
-}
-
-static float64 convert(Ruby x, float64 *foo) {
- if (INTEGER_P(x)) return INT(x);
- if (TYPE(x)!=T_FLOAT) RAISE("not a Float");
- return ((RFloat*)x)->value;}
-static float32 convert(Ruby x, float32 *foo) {
- return (float32) convert(x,(float64 *)0);}
-typedef Ruby Symbol, Array, String, Integer;
-static Ruby convert(Ruby x, Ruby *bogus) { return x; }
-typedef Ruby (*RMethod)(...); /* !@#$ fishy */
-
-#define BUILTIN_SYMBOLS(MACRO) \
- MACRO(_grid,"grid") MACRO(_bang,"bang") MACRO(_float,"float") \
- MACRO(_list,"list") MACRO(_sharp,"#") \
- MACRO(iv_outlets,"@outlets") \
- MACRO(iv_ninlets,"@ninlets") \
- MACRO(iv_noutlets,"@noutlets")
-extern struct BuiltinSymbols {
-#define FOO(_sym_,_str_) Ruby _sym_;
-BUILTIN_SYMBOLS(FOO)
-#undef FOO
-} bsym;
-
-typedef struct R {
- VALUE r;
- R() {r=Qnil;}
- R(int x) {r=INT2NUM(x);}
- R(unsigned x) {r=UINT2NUM(x);}
- R(long x) {r=LONG2NUM(x);}
- R(unsigned long x) {r=ULONG2NUM(x);}
- R(double x) {r=rb_float_new(x);}
- R( int64 x) {r= gf_ll2num(x);}
- R(uint64 x) {r=gf_ull2num(x);}
- operator bool() {return !!INT2NUM(r);}
- operator uint8 () {return INT2NUM(r);}
- operator int16 () {return INT2NUM(r);}
- operator int32 () {return INT2NUM(r);}
- operator int64 () {return convert(r,(int64*)0);}
- operator float32 () {return convert(r,(float32*)0);}
- operator float64 () {return convert(r,(float64*)0);}
-#define FOO(As,Op) \
- R &operator As (int x) {r=rb_funcall(r, SI(Op),1,INT2NUM(x)); return *this;}
- FOO(+=,+) FOO(-=,-) FOO(*=,*) FOO(/=,/) FOO(%=,%)
- FOO(&=,&) FOO(|=,|) FOO(^=,^) FOO(<<=,<<) FOO(>>=,>>)
-#undef FOO
-// bool operator == (int x) {return rb_funcall(r,SI(==),1,INT2NUM(x));}
-#define FOO(Op) \
- R operator Op (R x) {return rb_funcall(r,SI(Op),1,x.r);} \
- R operator Op (int x) {return rb_funcall(r,SI(Op),1,INT2NUM(x));}
- FOO(+) FOO(-) FOO(*) FOO(/) FOO(%)
- FOO(&) FOO(|) FOO(^) FOO(<<) FOO(>>)
- FOO(<) FOO(>) FOO(<=) FOO(>=) FOO(==) FOO(!=)
-#undef FOO
- static R value(VALUE r) {R x; x.r=r; return x;}
-} ruby;
-
-static R operator -(int a, R b) {return rb_funcall(a,SI(Op),1,INT2NUM(b.r));}
-
-static inline R ipow(R a, R b) {return R::value(rb_funcall(a.r,SI(**),1,b.r));}
-static inline R gf_abs(R a) { return R::value(rb_funcall(a.r,SI(abs),0)); }
-static inline R cmp(R a, R b) { return R::value(rb_funcall(a.r,SI(<=>),1,b.r));}
-
-//****************************************************************
-// hook into pointer manipulation. will help find memory corruption bugs.
-
-template <class T> class Pt {
-typedef ptrdiff_t /* and not int nor long */ Z;
-public:
- T *p;
-#ifdef HAVE_DEBUG
- T *start;
- Z n;
- Pt() : p(0), start(0), n(0) {}
- Pt(T *q, Z _n) : p(q), start(q), n(_n) {}
- Pt(T *q, Z _n, T *_start) : p(q), start(_start), n(_n) {}
-#else
- Pt() : p(0) {}
- Pt(T *q, Z _n, T *_start=0) : p(q) {}
-#endif
- T &operator *() { return *p; }
- Pt operator+=(Z i) { p+=i; return *this; }
- Pt operator-=(Z i) { p-=i; return *this; }
- Pt operator++( ) { p++; return *this; }
- Pt operator--( ) { p--; return *this; }
- Pt operator++(int) { Pt f(*this); ++*this; return f; }
- Pt operator--(int) { Pt f(*this); --*this; return f; }
- T &operator[](Z i) {
-#ifdef HAVE_DEBUG_HARDER
- if (!(p+i>=start && p+i<start+n))
- BUG("BUFFER OVERFLOW: 0x%08lx[%ld]=0x%08lx is not in 0x%08lx..0x%08lx",
- (long)p, (long)i, (long)(p+i),(long)start,(long)(start+n));
-#endif
- return p[i];
- }
-
- void will_use(int k) {
-#ifdef HAVE_DEBUG_HARDER
- if (k==0) return;
- T *q = p+k;
- if (!(p>=start && p<start+n && q>=start && q<=start+n))
- BUG("BUFFER OVERFLOW: 0x%08lx...0x%08lx is not all inside 0x%08lx...0x%08lx",
- (long)p,(long)q,start,(long)(start+n));
-#endif
- }
-
- Z operator-(Pt x) { return p-x.p; }
- operator bool () { return (bool )p; }
- operator void *() { return (void *)p; }
- operator int8 *() { return (int8 *)p; }
-
-/* how do i make typecast operators that are not also default conversions??? */
-/* this should be found so i can clean up the following: */
-#define FOO(S) operator S *() { return (S *)p; }
-EACH_NUMBER_TYPE(FOO)
-#undef FOO
-#ifdef HAVE_DEBUG
-#define FOO(S) operator Pt<S>() { return Pt<S>((S *)p,n*sizeof(T)/1,(S *)start); }
-EACH_NUMBER_TYPE(FOO)
-#undef FOO
-#else
-#define FOO(S) operator Pt<S>() { return Pt<S>((S *)p,0); }
-EACH_NUMBER_TYPE(FOO)
-#undef FOO
-#endif
-/* end 0.8 (TESTING) */
-
-#ifdef HAVE_DEBUG
- template <class U> Pt operator+(U x) { return Pt(p+x,n,start); }
- template <class U> Pt operator-(U x) { return Pt(p-x,n,start); }
-#else
- template <class U> Pt operator+(U x) { return Pt(p+x,0); }
- template <class U> Pt operator-(U x) { return Pt(p-x,0); }
-#endif
-};
-
-//template <class T> class P : Pt<T> {};
-//a reference counting pointer class
-template <class T> class P {
-public:
-#define INCR if (p) p->refcount++;
-#define DECR if (p) {p->refcount--; if (!p->refcount) delete p;}
- T *p;
- P() : p(0) {}
- P(T *_p) { p = _p; INCR; }
- P(const P<T> &_p) { p = _p.p; INCR; }
- P<T> &operator =(T * _p) { DECR; p=_p; INCR; return *this; }
- P<T> &operator =(P<T> _p) { DECR; p=_p.p; INCR; return *this; }
- bool operator ==(P<T> _p) { return p == _p.p; }
- bool operator !=(P<T> _p) { return p != _p.p; }
- ~P() { DECR; }
- bool operator !(){ return !p; }
- operator bool() { return !!p; }
- T &operator *() { return *p; }
- T *operator ->() { return p; }
-//#undef INCR
-//#undef DECR
-};
-
-#ifndef IS_BRIDGE
-extern "C" void *gfmalloc(size_t n);
-extern "C" void gffree(void *p);
-// note that C++ (GCC 3.4) now refuses the :: prefix so i removed it in the 4 following lines:
-inline void *operator new (size_t n) { return gfmalloc(n); }
-inline void *operator new[] (size_t n) { return gfmalloc(n); }
-inline void operator delete (void *p) { gffree(p); }
-inline void operator delete[] (void *p) { gffree(p); }
-#endif
-
-#define STACK_ARRAY(T,V,N) T V##_foo[N]; Pt<T> V(V##_foo,N);
-#define ARRAY_NEW(T,N) (Pt<T>((T *)new T[N],N))
-
-void gfmemcopy(uint8 *out, const uint8 *in, int n);
-template <class T> inline void COPY(Pt<T> dest, Pt<T> src, int n) {
- src.will_use(n); dest.will_use(n);
- gfmemcopy((uint8*)dest,(const uint8*)src,n*sizeof(T));
-}
-template <class T> inline void CLEAR(Pt<T> dest, int n) {
- dest.will_use(n);
- memset(dest,0,n*sizeof(T));
-}
-template <class T> static void memswap (Pt<T> a, Pt<T> b, int n) {
- STACK_ARRAY(T,c,n); COPY(c,a,n); COPY(a,b,n); COPY(b,c,n);
-}
-
-//****************************************************************
-// CObject is the base class for C++ classes that get exported to Ruby.
-// BTW: It's quite convenient to have virtual-methods in the base class
-// because otherwise the vtable* isn't at the beginning of the object
-// and that's pretty confusing to a lot of people, especially when simple
-// casting causes a pointer to change its value.
-struct CObject {
-#define OBJECT_MAGIC 1618033989
- int32 magic;
- int32 refcount;
- Ruby rself; // point to Ruby peer
- CObject() : magic(OBJECT_MAGIC), refcount(0), rself(0) {}
- void check_magic () {
- if (magic != OBJECT_MAGIC) {
- fprintf(stderr,"Object memory corruption! (ask the debugger)\n");
- for (int i=-2; i<=2; i++)
- fprintf(stderr,"this[%d]=0x%08x\n",i,((int*)this)[i]);
- raise(11);
- }
- }
- virtual ~CObject() { magic = 0xDEADBEEF; }
- virtual void mark() {} // not used for now
-};
-void CObject_free (void *);
-
-// you shouldn't use MethodDecl directly (used by source_filter.rb)
-struct MethodDecl { const char *selector; RMethod method; };
-void define_many_methods(Ruby rself, int n, MethodDecl *methods);
-extern Ruby mGridFlow, cFObject, cGridObject, cFormat;
-
-//****************************************************************
-// a Dim is a list of dimensions that describe the shape of a grid
-\class Dim < CObject
-struct Dim : CObject {
- static const int MAX_DIM=16; // maximum number of dimensions in a grid
- int n;
- Pt<int32> v; // safe pointer
- int32 v2[MAX_DIM]; // real stuff
- void check(); // test invariants
- Dim(int n, Pt<int32> v) { this->v = Pt<int32>(v2,MAX_DIM); this->n = n; COPY(this->v,v,n); check();}
- Dim(int n, int32 *v) { this->v = Pt<int32>(v2,MAX_DIM); this->n = n; COPY(this->v,Pt<int32>(v,n),n); check();}
- Dim() {v=Pt<int32>(v2,MAX_DIM); n=0; check();}
- Dim(int a) {v=Pt<int32>(v2,MAX_DIM); n=1;v[0]=a; check();}
- Dim(int a,int b) {v=Pt<int32>(v2,MAX_DIM); n=2;v[0]=a;v[1]=b; check();}
- Dim(int a,int b,int c){v=Pt<int32>(v2,MAX_DIM); n=3;v[0]=a;v[1]=b;v[2]=c;check();}
- int count() {return n;}
- int get(int i) { return v[i]; }
- int32 prod(int start=0, int end=-1) {
- if (end<0) end+=n;
- int32 tot=1;
- for (int i=start; i<=end; i++) tot *= v[i];
- return tot;
- }
- char *to_s();
- bool equal(P<Dim> o) {
- if (n!=o->n) return false;
- for (int i=0; i<n; i++) if (v[i]!=o->v[i]) return false;
- return true;
- }
-};
-\end class Dim
-
-//****************************************************************
-//BitPacking objects encapsulate optimised loops of conversion
-struct BitPacking;
-// those are the types of the optimised loops of conversion
-// inputs are const
-struct Packer {
-#define FOO(S) void (*as_##S)(BitPacking *self, int n, Pt<S> in, Pt<uint8> out);
-EACH_INT_TYPE(FOO)
-#undef FOO
-};
-struct Unpacker {
-#define FOO(S) void (*as_##S)(BitPacking *self, int n, Pt<uint8> in, Pt<S> out);
-EACH_INT_TYPE(FOO)
-#undef FOO
-};
-
-\class BitPacking < CObject
-struct BitPacking : CObject {
- Packer *packer;
- Unpacker *unpacker;
- unsigned int endian; // 0=big, 1=little, 2=same, 3=different
- int bytes;
- int size;
- uint32 mask[4];
- BitPacking(){::abort();} // don't call, but don't remove. sorry.
- BitPacking(int endian, int bytes, int size, uint32 *mask,
- Packer *packer=0, Unpacker *unpacker=0);
- bool is_le();
- bool eq(BitPacking *o);
- \decl void initialize(Ruby foo1, Ruby foo2, Ruby foo3);
- \decl String pack2(String ins, String outs=Qnil);
- \decl String unpack2(String ins, String outs=Qnil);
- \decl String to_s();
-// main entrances to Packers/Unpackers
- template <class T> void pack( int n, Pt<T> in, Pt<uint8> out);
- template <class T> void unpack(int n, Pt<uint8> in, Pt<T> out);
-};
-\end class
-
-int high_bit(uint32 n);
-int low_bit(uint32 n);
-void swap32 (int n, Pt<uint32> data);
-void swap16 (int n, Pt<uint16> data);
-
-#define NT_UNSIGNED (1<<0)
-#define NT_FLOAT (1<<1)
-#define NT_UNIMPL (1<<2)
-#define NUMBER_TYPE_LIMITS(T,a,b,c) \
- inline T nt_smallest(T *bogus) {return a;} \
- inline T nt_greatest(T *bogus) {return b;} \
- inline T nt_all_ones(T *bogus) {return c;}
-
-NUMBER_TYPE_LIMITS( uint8,0,255,255)
-NUMBER_TYPE_LIMITS( int16,-0x8000,0x7fff,-1)
-NUMBER_TYPE_LIMITS( int32,-0x80000000,0x7fffffff,-1)
-NUMBER_TYPE_LIMITS( int64,-0x8000000000000000LL,0x7fffffffffffffffLL,-1)
-NUMBER_TYPE_LIMITS(float32,-HUGE_VAL,+HUGE_VAL,(RAISE("all_ones"),0))
-NUMBER_TYPE_LIMITS(float64,-HUGE_VAL,+HUGE_VAL,(RAISE("all_ones"),0))
-NUMBER_TYPE_LIMITS( ruby,ruby(-HUGE_VAL),ruby(+HUGE_VAL),(RAISE("all_ones"),0))
-
-#ifdef HAVE_LITE
-#define NT_NOTLITE NT_UNIMPL
-#define NONLITE(x...)
-#else
-#define NT_NOTLITE 0
-#define NONLITE(x...) x
-#endif
-#define NUMBER_TYPES(MACRO) \
- MACRO( uint8, 8,NT_UNSIGNED, "u8,b") MACRO( int8, 8,NT_UNIMPL, "i8") \
- MACRO( uint16,16,NT_UNSIGNED|NT_UNIMPL, "u16") MACRO(int16,16,0, "i16,s") \
- MACRO( uint32,32,NT_UNSIGNED|NT_UNIMPL, "u32") MACRO(int32,32,0, "i32,i") \
- MACRO( uint64,64,NT_UNSIGNED|NT_UNIMPL, "u64") MACRO(int64,64,NT_NOTLITE, "i64,l") \
- MACRO(float32,32,NT_NOTLITE|NT_FLOAT, "f32,f") \
- MACRO(float64,64,NT_NOTLITE|NT_FLOAT, "f64,d") \
- MACRO( ruby,sizeof(long),NT_NOTLITE,"r")
-
-enum NumberTypeE {
-#define FOO(_sym_,args...) _sym_##_e,
-NUMBER_TYPES(FOO)
-#undef FOO
- number_type_table_end
-};
-
-#define FOO(_type_) \
-inline NumberTypeE NumberTypeE_type_of(_type_ &x) { \
- return _type_##_e; }
-EACH_NUMBER_TYPE(FOO)
-#undef FOO
-
-\class NumberType < CObject
-struct NumberType : CObject {
- Ruby /*Symbol*/ sym;
- const char *name;
- int size;
- int flags;
- const char *aliases;
- NumberTypeE index;
- NumberType(const char *name_, int size_, int flags_, const char *aliases_) :
- name(name_), size(size_), flags(flags_), aliases(aliases_) {}
- \decl Symbol sym_m();
- \decl int size_m();
- \decl int flags_m();
- \decl int index_m();
-};
-\end class
-
-NumberTypeE NumberTypeE_find (Ruby sym);
-
-#define TYPESWITCH(T,C,E) switch (T) { \
- case uint8_e: C(uint8) break; case int16_e: C(int16) break; \
- case int32_e: C(int32) break; NONLITE(case int64_e: C(int64) break; \
- case float32_e: C(float32) break; case float64_e: C(float64) break; \
- case ruby_e: C(ruby) break;) \
- default: E; RAISE("type '%s' not available here",number_type_table[T].sym);}
-#define TYPESWITCH_JUSTINT(T,C,E) switch (T) { \
- case uint8_e: C(uint8) break; case int16_e: C(int16) break; \
- case int32_e: C(int32) break; NONLITE(case int64_e: C(int64) break;) \
- default: E; RAISE("type '%s' not available here",number_type_table[T].sym);}
-
-// Numop objects encapsulate optimised loops of simple operations
-
-enum LeftRight { at_left, at_right };
-
-template <class T>
-struct NumopOn : CObject {
- // Function Vectorisations
- typedef void (*Map )( int n, T *as, T b ); Map op_map;
- typedef void (*Zip )( int n, T *as, T *bs); Zip op_zip;
- typedef void (*Fold)(int an, int n, T *as, T *bs); Fold op_fold;
- typedef void (*Scan)(int an, int n, T *as, T *bs); Scan op_scan;
- // Algebraic Properties (those involving simply numeric types)
- typedef bool (*AlgebraicCheck)(T x, LeftRight side);
- // neutral: right: forall y {f(x,y)=x}; left: forall x {f(x,y)=y};
- // absorbent: right: exists a forall y {f(x,y)=a}; ...
- T (*neutral)(LeftRight); // default neutral: e.g. 0 for addition, 1 for multiplication
- AlgebraicCheck is_neutral, is_absorbent;
- NumopOn(Map m, Zip z, Fold f, Scan s, T (*neu)(LeftRight), AlgebraicCheck n, AlgebraicCheck a) :
- op_map(m), op_zip(z), op_fold(f), op_scan(s), neutral(neu), is_neutral(n), is_absorbent(a) {}
- NumopOn() {}
- NumopOn(const NumopOn &z) {
- op_map = z.op_map; op_zip = z.op_zip;
- op_fold = z.op_fold; op_scan = z.op_scan;
- is_neutral = z.is_neutral; neutral = z.neutral;
- is_absorbent = z.is_absorbent; }
-};
-
-// semigroup property: associativity: f(a,f(b,c))=f(f(a,b),c)
-#define OP_ASSOC (1<<0)
-// abelian property: commutativity: f(a,b)=f(b,a)
-#define OP_COMM (1<<1)
-
-\class Numop < CObject
-struct Numop : CObject {
- Ruby /*Symbol*/ sym;
- const char *name;
- int flags;
-//private:
-#define FOO(T) \
- NumopOn<T> on_##T; \
- NumopOn<T> *on(T &foo) { \
- if (!on_##T.op_map) \
- RAISE("operator %s does not support type "#T,rb_sym_name(sym)); \
- return &on_##T;}
-EACH_NUMBER_TYPE(FOO)
-#undef FOO
-//public:
- template <class T> inline void map(int n, Pt<T> as, T b) {
- as.will_use(n);
- on(*as)->op_map(n,(T *)as,b);}
- template <class T> inline void zip(int n, Pt<T> as, Pt<T> bs) {
- as.will_use(n);
- bs.will_use(n);
- on(*as)->op_zip(n,(T *)as,(T *)bs);}
- template <class T> inline void fold(int an, int n, Pt<T> as, Pt<T> bs) {
- as.will_use(an);
- bs.will_use(an*n);
- typename NumopOn<T>::Fold f = on(*as)->op_fold;
- if (!f) RAISE("operator %s does not support fold",rb_sym_name(sym));
- f(an,n,(T *)as,(T *)bs);}
- template <class T> inline void scan(int an, int n, Pt<T> as, Pt<T> bs) {
- as.will_use(an);
- bs.will_use(an*n);
- typename NumopOn<T>::Scan f = on(*as)->op_scan;
- if (!f) RAISE("operator %s does not support scan",rb_sym_name(sym));
- f(an,n,(T *)as,(T *)bs);}
-
- \decl void map_m (NumberTypeE nt, int n, String as, String b);
- \decl void zip_m (NumberTypeE nt, int n, String as, String bs);
- \decl void fold_m (NumberTypeE nt, int an, int n, String as, String bs);
- \decl void scan_m (NumberTypeE nt, int an, int n, String as, String bs);
-
- Numop(Ruby /*Symbol*/ sym_, const char *name_,
-#define FOO(T) NumopOn<T> op_##T,
-EACH_NUMBER_TYPE(FOO)
-#undef FOO
- int flags_) : sym(sym_), name(name_), flags(flags_) {
-#define FOO(T) on_##T = op_##T;
-EACH_NUMBER_TYPE(FOO)
-#undef FOO
- }
-};
-\end class
-
-extern NumberType number_type_table[];
-extern Ruby number_type_dict; // GridFlow.@number_type_dict={}
-extern Ruby op_dict; // GridFlow.@op_dict={}
-
-static inline NumberTypeE convert(Ruby x, NumberTypeE *bogus) {
- return NumberTypeE_find(x);
-}
-
-#ifndef IS_BRIDGE
-static Numop *convert(Ruby x, Numop **bogus) {
- Ruby s = rb_hash_aref(rb_ivar_get(mGridFlow,SI(@op_dict)),x);
- if (s==Qnil) RAISE("expected two-input-operator");
- return FIX2PTR(Numop,s);
-}
-#endif
-
-// ****************************************************************
-\class Grid < CObject
-struct Grid : CObject {
- P<Dim> dim;
- NumberTypeE nt;
- void *data;
- Grid(P<Dim> dim, NumberTypeE nt, bool clear=false) : dim(0), nt(int32_e), data(0) {
- if (!dim) RAISE("hell");
- init(dim,nt);
- if (clear) {int size = bytes(); CLEAR(Pt<char>((char *)data,size),size);}
- }
- Grid(Ruby x) : dim(0), nt(int32_e), data(0) { init_from_ruby(x); }
- Grid(int n, Ruby *a, NumberTypeE nt=int32_e) : dim(0), nt(int32_e), data(0) {
- init_from_ruby_list(n,a,nt);
- }
- int32 bytes() { return dim->prod()*number_type_table[nt].size/8; }
- P<Dim> to_dim () { return new Dim(dim->prod(),(Pt<int32>)*this); }
-#define FOO(type) \
- operator type *() { return (type *)data; } \
- operator Pt<type>() { return Pt<type>((type *)data,dim->prod()); }
-EACH_NUMBER_TYPE(FOO)
-#undef FOO
- Grid *dup () {
- Grid *foo=new Grid(dim,nt);
- memcpy(foo->data,data,bytes());
- return foo;
- }
- ~Grid() {if (data) free(data);}
-private:
- void init(P<Dim> dim, NumberTypeE nt) {
- this->dim = dim;
- this->nt = nt;
- data = 0;
- if (dim) data = memalign(16,bytes()+16);
- //fprintf(stderr,"rdata=%p data=%p align=%d\n",rdata,data,align);
- }
- void init_from_ruby(Ruby x);
- void init_from_ruby_list(int n, Ruby *a, NumberTypeE nt=int32_e);
-};
-\end class Grid
-
-static inline Grid *convert (Ruby r, Grid **bogus) {
- return r ? new Grid(r) : 0;
-}
-
-// DimConstraint interface:
-// return if d is acceptable
-// else RAISE with proper descriptive message
-typedef void (*DimConstraint)(P<Dim> d);
-
-struct PtrGrid : public P<Grid> {
- DimConstraint dc;
- void constrain(DimConstraint dc_) { dc=dc_; }
- P<Grid> next;
- PtrGrid() : P<Grid>(), dc(0), next(0) {}
- PtrGrid(const PtrGrid &_p) : P<Grid>(), dc(0), next(0) {dc=_p.dc; p=_p.p; INCR;}
- PtrGrid &operator =( Grid *_p) {if(dc&&p)dc(_p->dim); DECR; p=_p; INCR; return *this;}
- PtrGrid &operator =(P<Grid> _p) {if(dc&&p)dc(_p->dim); DECR; p=_p.p; INCR; return *this;}
- PtrGrid &operator =(PtrGrid _p) {if(dc&&p)dc(_p->dim); DECR; p=_p.p; INCR; return *this;}
-};
-
-#ifndef IS_BRIDGE
-static inline P<Dim> convert(Ruby x, P<Dim> *foo) {
- Grid *d = convert(x,(Grid **)0);
- if (!d) RAISE("urgh");
- if (d->dim->n!=1) RAISE("dimension list must have only one dimension itself");
- return new Dim(d->dim->v[0],(int32 *)(d->data));
-}
-
-static inline PtrGrid convert(Ruby x, PtrGrid *foo) {
- PtrGrid pg;
- pg = convert(x,(Grid **)0);
- return pg;
-}
-#endif
-
-//****************************************************************
-// GridInlet represents a grid-aware inlet
-
-// four-part macro for defining the behaviour of a gridinlet in a class
-// C:Class I:Inlet
-#define GRID_INLET(C,I) \
- template <class T> void C::grinw_##I (GridInlet *in, int n, Pt<T> data) { \
- ((C*)(in->parent))->grin_##I(in,n,data); } \
- template <class T> void C::grin_##I (GridInlet *in, int n, Pt<T> data) { \
- if (n==-1)
-#define GRID_ALLOC else if (n==-3)
-#define GRID_FLOW else if (n>=0)
-#define GRID_FINISH else if (n==-2)
-#define GRID_END }
-
-/* macro for defining a gridinlet's behaviour as just storage (no backstore) */
-// V is a PtrGrid instance-var
-#define GRID_INPUT(C,I,V) \
-GRID_INLET(C,I) { V=new Grid(in->dim,NumberTypeE_type_of(*data)); } \
-GRID_FLOW { COPY((Pt<T>)*(V)+in->dex, data, n); } GRID_FINISH
-
-// macro for defining a gridinlet's behaviour as just storage (with backstore)
-// V is a PtrGrid instance-var
-#define GRID_INPUT2(C,I,V) \
- GRID_INLET(C,I) { \
- if (is_busy_except(in)) { \
- V.next = new Grid(in->dim,NumberTypeE_type_of(*data)); \
- } else V= new Grid(in->dim,NumberTypeE_type_of(*data)); \
- } GRID_FLOW { \
- COPY(((Pt<T>)*(V.next?V.next.p:&*V.p))+in->dex, data, n); \
- } GRID_FINISH
-
-typedef struct GridInlet GridInlet;
-typedef struct GridHandler {
-#define FOO(T) \
- void (*flow_##T)(GridInlet *in, int n, Pt<T> data); \
- void flow(GridInlet *in, int n, Pt<T> data) const { \
- assert(flow_##T); flow_##T(in,n,data); }
-EACH_NUMBER_TYPE(FOO)
-#undef FOO
-} GridHandler;
-
-typedef struct GridObject GridObject;
-\class GridInlet < CObject
-struct GridInlet : CObject {
- GridObject *parent;
- const GridHandler *gh;
- GridObject *sender;
- P<Dim> dim;
- NumberTypeE nt;
- int dex;
- PtrGrid buf;// factor-chunk buffer
- int bufi; // buffer index: how much of buf is filled
- int mode; // 0=ignore; 4=ro; 6=rw
-
- int allocfactor,allocmin,allocmax,allocn;
- Pt<uint8> alloc;
-
-// methods
- GridInlet(GridObject *parent_, const GridHandler *gh_) :
- parent(parent_), gh(gh_), sender(0),
- dim(0), nt(int32_e), dex(0), bufi(0), mode(4) {}
- ~GridInlet() {}
- void set_factor(int factor);
- void set_mode(int mode_) { mode=mode_; }
- int32 factor() {return buf?buf->dim->prod():1;}
- Ruby begin(int argc, Ruby *argv);
-
- // n=-1 is begin, and n=-2 is _finish_. the name "end" is now used
- // as an end-marker for inlet definitions... sorry for the confusion
- // GF-0.8: n=-3 is alloc.
- template <class T> void flow(int mode, int n, Pt<T> data);
- void end(); // this one ought to be called finish().
- void from_ruby_list(int argc, Ruby *argv, NumberTypeE nt=int32_e) {
- Grid t(argc,argv,nt); from_grid(&t);
- }
- void from_ruby(int argc, Ruby *argv) {
- Grid t(argv[0]); from_grid(&t);
- }
- void from_grid(Grid *g);
- bool supports_type(NumberTypeE nt);
-private:
- template <class T> void from_grid2(Grid *g, T foo);
-};
-\end class GridInlet
-
-//****************************************************************
-// for use by source_filter.rb ONLY (for \grin and \classinfo)
-
-// C is for class, I for inlet number
-// GRIN1 : int32 only
-// GRIN4 : all types
-// GRIN2 : integers only; no floats (no R either actually)
-// GRINF : floats only; no integers
-#ifndef HAVE_LITE
-#define GRIN(TB,TS,TI,TL,TF,TD,TR) {TB,TS,TI,TL,TF,TD,TR}
-#else
-#define GRIN(TB,TS,TI,TL,TF,TD,TR) {TB,TS,TI}
-#endif // HAVE_LITE
-
-#define GRIN1(C,I) GRIN(0,0,C::grinw_##I,0,0,0,0)
-#define GRIN4(C,I) GRIN(C::grinw_##I,C::grinw_##I,C::grinw_##I,C::grinw_##I,C::grinw_##I,C::grinw_##I,C::grinw_##I)
-#define GRIN2(C,I) GRIN(C::grinw_##I,C::grinw_##I,C::grinw_##I,C::grinw_##I,0,0,0)
-#define GRINF(C,I) GRIN(0,0,0,0,C::grinw_##I,C::grinw_##I,0)
-
-struct FClass { // 0.7.8: removed all GridObject-specific stuff.
- void *(*allocator)(); // returns a new C++ object
- void (*startup)(Ruby rself); // initializer for the Ruby class
- const char *name; // C++/Ruby name (not PD name)
- int methodsn; MethodDecl *methods; // C++ -> Ruby methods
-};
-
-//****************************************************************
-// GridOutlet represents a grid-aware outlet
-\class GridOutlet < CObject
-struct GridOutlet : CObject {
-// number of (minimum,maximum) BYTES to send at once
-// starting with version 0.8, this is amount of BYTES, not amount of NUMBERS.
- static const int MIN_PACKET_SIZE = 1<<8;
- static const int MAX_PACKET_SIZE = 1<<12;
-// those are set only once
- GridObject *parent; // not a P<> because of circular refs
- P<Dim> dim; // dimensions of the grid being sent
- NumberTypeE nt;
- PtrGrid buf; // temporary buffer
- bool frozen; // is the "begin" phase finished?
- std::vector<GridInlet *> inlets; // which inlets are we connected to
-// those are updated during transmission
- int dex; // how many numbers were already sent in this connection
- int bufi; // number of bytes used in the buffer
-// methods
- GridOutlet(GridObject *parent_, int woutlet, P<Dim> dim_, NumberTypeE nt_=int32_e) :
- parent(parent_), dim(dim_), nt(nt_), frozen(false), dex(0), bufi(0) {
- int ntsz = number_type_table[nt].size;
- buf=new Grid(new Dim(MAX_PACKET_SIZE/*/ntsz*/), nt);
- begin(woutlet,dim,nt);
- }
- ~GridOutlet() {}
- void callback(GridInlet *in);
-
- // send/send_direct: data belongs to caller, may be stack-allocated,
- // receiver doesn't modify the data; in send(), there is buffering;
- // in send_direct(), there is not. When switching from buffered to
- // unbuffered mode, flush() must be called
- template <class T> void send(int n, Pt<T> data);
- void flush(); // goes with send();
-
- // give: data must be dynamically allocated as a whole: the data
- // will be deleted eventually, and should not be used by the caller
- // beyond the call to give().
- template <class T> void give(int n, Pt<T> data);
-
- // third way to send (upcoming, in GF-0.8.??) is called "ask".
- template <class T> void ask(int &n, Pt<T> &data, int factor, int min, int max);
-
-private:
- void begin(int woutlet, P<Dim> dim, NumberTypeE nt=int32_e);
- template <class T> void send_direct(int n, Pt<T> data);
- void end() {
- flush();
- for (uint32 i=0; i<inlets.size(); i++) inlets[i]->end();
- dim=0;
- }
-};
-\end class GridOutlet
-
-//****************************************************************
-
-typedef struct BFObject BFObject; // Pd t_object or something
-
-// represents objects that have inlets/outlets
-\class FObject < CObject
-struct FObject : CObject {
- BFObject *bself; // point to PD peer
- uint64 total_time;
- FObject() : bself(0), total_time(0) {}
- const char *args() {
- Ruby s=rb_funcall(rself,SI(args),0);
- if (s==Qnil) return 0;
- return rb_str_ptr(s);
- }
- \decl Ruby total_time_get();
- \decl Ruby total_time_set(Ruby x);
- \decl void send_in (...);
- \decl void send_out (...);
- \decl void delete_m ();
-};
-\end class FObject
-
-\class GridObject < FObject
-struct GridObject : FObject {
- std::vector<P<GridInlet> > in;
- P<GridOutlet> out;
- // Make sure you distinguish #close/#delete, and C++'s delete. The first
- // two are quite equivalent and should never make an object "crashable".
- // C++'s delete is called by Ruby's garbage collector or by PureData's delete.
- GridObject() {}
- ~GridObject() {check_magic();}
- bool is_busy_except(P<GridInlet> gin) {
- for (uint32 i=0; i<in.size(); i++)
- if (in[i] && in[i]!=gin && in[i]->dim) return true;
- return false;
- }
- \decl Ruby method_missing(...);
- \decl Array inlet_dim(int inln);
- \decl Symbol inlet_nt(int inln);
- \decl void inlet_set_factor(int inln, int factor);
- \decl void send_out_grid_begin(int outlet, Array dim, NumberTypeE nt=int32_e);
- \decl void send_out_grid_flow (int outlet, String buf, NumberTypeE nt=int32_e);
-};
-\end class GridObject
-
-uint64 gf_timeofday();
-extern "C" void Init_gridflow ();
-void gfpost(const char *fmt, ...);
-extern Numop *op_add,*op_sub,*op_mul,*op_div,*op_mod,*op_shl,*op_and,*op_put;
-
-#define INFO(OBJ) rb_str_ptr(rb_funcall(OBJ->rself,SI(info),0))
-//#define INFO(OBJ) "(bleh)"
-#define NOTEMPTY(_a_) if (!(_a_)) RAISE("in [%s], '%s' is empty",INFO(this), #_a_);
-#define SAME_TYPE(_a_,_b_) \
- if ((_a_)->nt != (_b_)->nt) RAISE("%s: same type please (%s has %s; %s has %s)", \
- INFO(this), \
- #_a_, number_type_table[(_a_)->nt].name, \
- #_b_, number_type_table[(_b_)->nt].name);
-static void SAME_DIM(int n, P<Dim> a, int ai, P<Dim> b, int bi) {
- if (ai+n > a->n) RAISE("left hand: not enough dimensions");
- if (bi+n > b->n) RAISE("right hand: not enough dimensions");
- for (int i=0; i<n; i++) {
- if (a->v[ai+i] != b->v[bi+i]) {
- RAISE("mismatch: left dim #%d is %d, right dim #%d is %d",
- ai+i, a->v[ai+i],
- bi+i, b->v[bi+i]);}}}
-
-// a stack for the profiler, etc.
-#define GF_STACK_MAX 256
-//#define NO_INLINE(decl) decl __attribute__((noinline))
-#define NO_INLINE(decl) decl
-struct GFStack {
- struct GFStackFrame {
- FObject *o;
- void *bp; // a pointer into system stack
- uint64 time;
- }; // sizeof() == 16 (in 32-bit mode)
- GFStackFrame s[GF_STACK_MAX];
- int n;
- GFStack() { n = 0; }
- NO_INLINE(void push (FObject *o));
- NO_INLINE(void pop ());
-};
-extern GFStack gf_stack;
-struct GFStackMarker {
- int n;
- bool flag;
- GFStackMarker(FObject *o) { n = gf_stack.n; gf_stack.push(o); flag=true; }
- ~GFStackMarker() { while (gf_stack.n != n) gf_stack.pop(); }
- bool once () {
- if (flag) { flag=false; return true; } else return false;
- }
-};
-
-typedef GridObject Format;
-
-#endif // __GF_GRID_H
diff --git a/externals/gridflow/base/main.c b/externals/gridflow/base/main.c
deleted file mode 100644
index d65c81d0..00000000
--- a/externals/gridflow/base/main.c
+++ /dev/null
@@ -1,648 +0,0 @@
-/*
- $Id: main.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 <stdlib.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <time.h>
-#include <stdarg.h>
-#include <string.h>
-#include <signal.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdarg.h>
-
-#include "grid.h.fcs"
-#include "../config.h"
-#include <assert.h>
-#include <limits.h>
-
-BuiltinSymbols bsym;
-GFStack gf_stack;
-Ruby mGridFlow;
-Ruby cFObject;
-
-extern "C"{
-void rb_raise0(
-const char *file, int line, const char *func, VALUE exc, const char *fmt, ...) {
- va_list args;
- char buf[BUFSIZ];
- va_start(args,fmt);
- vsnprintf(buf, BUFSIZ, fmt, args);
- buf[BUFSIZ-1]=0;
- va_end(args);
- VALUE e = rb_exc_new2(exc, buf);
- char buf2[BUFSIZ];
- snprintf(buf2, BUFSIZ, "%s:%d:in `%s'", file, line, func);
- buf2[BUFSIZ-1]=0;
- VALUE ary = rb_funcall(e,SI(caller),0);
- if (gf_stack.n) {
- rb_funcall(ary,SI(unshift),2,rb_str_new2(buf2),
- rb_str_new2(INFO(gf_stack.s[gf_stack.n-1].o)));
- } else {
- rb_funcall(ary,SI(unshift),1,rb_str_new2(buf2));
- }
- rb_funcall(e,SI(set_backtrace),1,ary);
- rb_exc_raise(e);
-}};
-
-Ruby rb_ary_fetch(Ruby rself, int i) {
- Ruby argv[] = { INT2NUM(i) };
- return rb_ary_aref(COUNT(argv),argv,rself);
-}
-
-//----------------------------------------------------------------
-// CObject
-
-static void CObject_mark (void *z) {}
-void CObject_free (void *foo) {
- CObject *self = (CObject *)foo;
- self->check_magic();
- if (!self->rself) {
- fprintf(stderr,"attempt to free object that has no rself\n");
- abort();
- }
- self->rself = 0; /* paranoia */
- delete self;
-}
-
-//----------------------------------------------------------------
-// Dim
-
-void Dim::check() {
- if (n>MAX_DIM) RAISE("too many dimensions");
- for (int i=0; i<n; i++) if (v[i]<0) RAISE("Dim: negative dimension");
-}
-
-// !@#$ big leak machine?
-// returns a string like "Dim[240,320,3]"
-char *Dim::to_s() {
- // if you blow 256 chars it's your own fault
- char buf[256];
- char *s = buf;
- s += sprintf(s,"Dim[");
- for(int i=0; i<n; i++) s += sprintf(s,"%s%d", ","+!i, v[i]);
- s += sprintf(s,"]");
- return strdup(buf);
-}
-
-//----------------------------------------------------------------
-\class FObject < CObject
-
-static void FObject_prepare_message(int &argc, Ruby *&argv, Ruby &sym, FObject *foo=0) {
- if (argc<1) {
- sym = bsym._bang;
- } else if (argc>1 && !SYMBOL_P(*argv)) {
- sym = bsym._list;
- } else if (INTEGER_P(*argv)||FLOAT_P(*argv)) {
- sym = bsym._float;
- } else if (SYMBOL_P(*argv)) {
- sym = *argv;
- argc--, argv++;
- } else if (argc==1 && TYPE(*argv)==T_ARRAY) {
- sym = bsym._list;
- argc = rb_ary_len(*argv);
- argv = rb_ary_ptr(*argv);
- } else {
- RAISE("%s received bad message: argc=%d; argv[0]=%s",foo?INFO(foo):"", argc,
- argc ? rb_str_ptr(rb_inspect(argv[0])) : "");
- }
-}
-
-struct Helper {
- int argc;
- Ruby *argv;
- FObject *self;
- Ruby rself;
- int n; // stack level
-};
-
-static Ruby GridFlow_handle_braces(Ruby rself, Ruby argv);
-
-// inlet #-1 is reserved for SystemInlet messages
-// inlet #-2 is for inlet #0 messages that happen at start time
-static void send_in_2 (Helper *h) { PROF(h->self) {
- int argc = h->argc;
- Ruby *argv = h->argv;
- if (h->argc<1) RAISE("not enough args");
- int inlet = INT(argv[0]);
- argc--, argv++;
- Ruby foo;
- if (argc==1 && TYPE(argv[0])==T_STRING /* && argv[0] =~ / / */) {
- foo = rb_funcall(mGridFlow,SI(parse),1,argv[0]);
- argc = rb_ary_len(foo);
- argv = rb_ary_ptr(foo);
- }
- if (argc>1) {
- foo = rb_ary_new4(argc,argv);
- GridFlow_handle_braces(0,foo);
- argc = rb_ary_len(foo);
- argv = rb_ary_ptr(foo);
- }
- if (inlet==-2) {
- Array init_messages = rb_ivar_get(h->rself,SI(@init_messages));
- rb_ary_push(init_messages, rb_ary_new4(argc,argv));
- inlet=0;
- }
- if (inlet<0 || inlet>9 /*|| inlet>real_inlet_max*/)
- if (inlet!=-3 && inlet!=-1) RAISE("invalid inlet number: %d", inlet);
- Ruby sym;
- FObject_prepare_message(argc,argv,sym,h->self);
-// if (rb_const_get(mGridFlow,SI(@verbose))==Qtrue) gfpost m.inspect
- char buf[256];
- if (inlet==-1) sprintf(buf,"_sys_%s",rb_sym_name(sym));
- else sprintf(buf,"_%d_%s",inlet,rb_sym_name(sym));
- rb_funcall2(h->rself,rb_intern(buf),argc,argv);
-} /* PROF */ }
-
-static void send_in_3 (Helper *h) {
- while (gf_stack.n > h->n) gf_stack.pop();
-}
-
-\def void send_in (...) {
- Helper h = {argc,argv,this,rself,gf_stack.n};
- rb_ensure(
- (RMethod)send_in_2,(Ruby)&h,
- (RMethod)send_in_3,(Ruby)&h);
-}
-
-\def void send_out (...) {
- int n=0;
- if (argc<1) RAISE("not enough args");
- int outlet = INT(*argv);
- if (outlet<0 || outlet>9 /*|| outlet>real_outlet_max*/)
- RAISE("invalid outlet number: %d",outlet);
- argc--, argv++;
- Ruby sym;
- FObject_prepare_message(argc,argv,sym,this);
- Ruby noutlets2 = rb_ivar_get(rb_obj_class(rself),SYM2ID(SYM(@noutlets)));
- if (TYPE(noutlets2)!=T_FIXNUM) {
- IEVAL(rself,"STDERR.puts inspect");
- RAISE("don't know how many outlets this has");
- }
- int noutlets = INT(noutlets2);
- //if (outlet<0 || outlet>=noutlets) RAISE("outlet %d does not exist",outlet);
- // was PROF(0) a hack because of exception-handling problems?
- PROF(0) {
- Ruby argv2[argc+2];
- for (int i=0; i<argc; i++) argv2[2+i] = argv[i];
- argv2[0] = INT2NUM(outlet);
- argv2[1] = sym;
- rb_funcall2(rself,SI(send_out2), argc+2, argv2);
-
- Ruby ary = rb_ivar_defined(rself,SYM2ID(bsym.iv_outlets)) ?
- rb_ivar_get(rself,SYM2ID(bsym.iv_outlets)) : Qnil;
- if (ary==Qnil) goto end;
- if (TYPE(ary)!=T_ARRAY) RAISE("send_out: expected array");
- ary = rb_ary_fetch(ary,outlet);
- if (ary==Qnil) goto end;
- if (TYPE(ary)!=T_ARRAY) RAISE("send_out: expected array");
- n = rb_ary_len(ary);
-
- for (int i=0; i<n; i++) {
- Ruby conn = rb_ary_fetch(ary,i);
- Ruby rec = rb_ary_fetch(conn,0);
- int inl = INT(rb_ary_fetch(conn,1));
- argv2[0] = INT2NUM(inl);
- rb_funcall2(rec,SI(send_in),argc+2,argv2);
- }
- } /* PROF */
-end:;
-}
-
-Ruby FObject_s_new(Ruby argc, Ruby *argv, Ruby qlass) {
- Ruby allocator = rb_ivar_defined(qlass,SI(@allocator)) ?
- rb_ivar_get(qlass,SI(@allocator)) : Qnil;
- FObject *self;
- if (allocator==Qnil) {
- // this is a pure-ruby FObject/GridObject
- // !@#$ GridObject is in FObject constructor (ugly)
- self = new GridObject;
- } else {
- // this is a C++ FObject/GridObject
- void*(*alloc)() = (void*(*)())FIX2PTR(void,allocator);
- self = (FObject *)alloc();
- }
- self->check_magic();
- Ruby keep = rb_ivar_get(mGridFlow, SI(@fobjects));
- self->bself = 0;
- Ruby rself = Data_Wrap_Struct(qlass, CObject_mark, CObject_free, self);
- self->rself = rself;
- rb_hash_aset(keep,rself,Qtrue); // prevent sweeping
- rb_funcall2(rself,SI(initialize),argc,argv);
- return rself;
-}
-
-Ruby FObject_s_install(Ruby rself, Ruby name, Ruby inlets2, Ruby outlets2) {
- int inlets, outlets;
- Ruby name2;
- if (SYMBOL_P(name)) {
- name2 = rb_funcall(name,SI(to_str),0);
- } else if (TYPE(name) == T_STRING) {
- name2 = rb_funcall(name,SI(dup),0);
- } else {
- RAISE("expect symbol or string");
- }
- inlets = INT(inlets2); if ( inlets<0 || inlets>9) RAISE("...");
- outlets = INT(outlets2); if (outlets<0 || outlets>9) RAISE("...");
- rb_ivar_set(rself,SI(@ninlets),INT2NUM(inlets));
- rb_ivar_set(rself,SI(@noutlets),INT2NUM(outlets));
- rb_ivar_set(rself,SI(@foreign_name),name2);
- rb_hash_aset(rb_ivar_get(mGridFlow,SI(@fclasses)), name2, rself);
- rb_funcall(rself, SI(install2), 1, name2);
- return Qnil;
-}
-
-\def Ruby total_time_get () {return gf_ull2num(total_time);}
-
-\def Ruby total_time_set (Ruby x) {
- if (argc<1) RAISE("muh");
- total_time = TO(uint64,x);
- return argv[0];
-}
-
-\def void delete_m () {
- Ruby keep = rb_ivar_get(mGridFlow, SI(@fobjects));
- rb_funcall(keep,SI(delete),1,rself);
-}
-
-\classinfo
-\end class FObject
-
-/* ---------------------------------------------------------------- */
-/* C++<->Ruby bridge for classes/functions in base/number.c */
-
-static Ruby String_swap32_f (Ruby rself) {
- int n = rb_str_len(rself)/4;
- swap32(n,Pt<uint32>((uint32 *)rb_str_ptr(rself),n));
- return rself;
-}
-
-static Ruby String_swap16_f (Ruby rself) {
- int n = rb_str_len(rself)/2;
- swap16(n,Pt<uint16>((uint16 *)rb_str_ptr(rself),n));
- return rself;
-}
-
-NumberTypeE NumberTypeE_find (Ruby sym) {
- if (TYPE(sym)!=T_SYMBOL) RAISE("expected symbol (not %s)",
- rb_str_ptr(rb_inspect(rb_obj_class(sym))));
- Ruby nt_dict = rb_ivar_get(mGridFlow,SI(@number_type_dict));
- Ruby v = rb_hash_aref(nt_dict,sym);
- if (v!=Qnil) return FIX2PTR(NumberType,v)->index;
- RAISE("unknown number type \"%s\"", rb_sym_name(sym));
-}
-
-/* **************************************************************** */
-\class BitPacking < CObject
-
-\def void initialize(Ruby foo1, Ruby foo2, Ruby foo3) {}
-
-// !@#$ doesn't support number types
-\def String pack2 (String ins, String outs=Qnil) {
- int n = rb_str_len(ins) / sizeof(int32) / size;
- Pt<int32> in = Pt<int32>((int32 *)rb_str_ptr(ins),rb_str_len(ins));
- int bytes2 = n*bytes;
- Ruby out = outs!=Qnil ? rb_str_resize(outs,bytes2) : rb_str_new("",bytes2);
- rb_str_modify(out);
- pack(n,Pt<int32>(in,n),Pt<uint8>((uint8 *)rb_str_ptr(out),bytes2));
- return out;
-}
-
-// !@#$ doesn't support number types
-\def String unpack2 (String ins, String outs=Qnil) {
- int n = rb_str_len(argv[0]) / bytes;
- Pt<uint8> in = Pt<uint8>((uint8 *)rb_str_ptr(ins),rb_str_len(ins));
- int bytes2 = n*size*sizeof(int32);
- Ruby out = outs!=Qnil ? rb_str_resize(outs,bytes2) : rb_str_new("",bytes2);
- rb_str_modify(out);
- unpack(n,Pt<uint8>((uint8 *)in,bytes2),Pt<int32>((int32 *)rb_str_ptr(out),n));
- return out;
-}
-
-static Ruby BitPacking_s_new(Ruby argc, Ruby *argv, Ruby qlass) {
- Ruby keep = rb_ivar_get(mGridFlow, rb_intern("@fobjects"));
- if (argc!=3) RAISE("bad args");
- if (TYPE(argv[2])!=T_ARRAY) RAISE("bad mask");
- int endian = INT(argv[0]);
- int bytes = INT(argv[1]);
- Ruby *masks = rb_ary_ptr(argv[2]);
- uint32 masks2[4];
- int size = rb_ary_len(argv[2]);
- if (size<1) RAISE("not enough masks");
- if (size>4) RAISE("too many masks (%d)",size);
- for (int i=0; i<size; i++) masks2[i] = NUM2UINT(masks[i]);
- BitPacking *self = new BitPacking(endian,bytes,size,masks2);
- Ruby rself = Data_Wrap_Struct(qlass, 0, CObject_free, self);
- self->rself = rself;
- rb_hash_aset(keep,rself,Qtrue); // prevent sweeping (leak) (!@#$ WHAT???)
- rb_funcall2(rself,SI(initialize),argc,argv);
- return rself;
-}
-
-\classinfo
-\end class BitPacking
-
-void gfpost(const char *fmt, ...) {
- va_list args;
- int length;
- va_start(args,fmt);
- const int n=256;
- char post_s[n];
- length = vsnprintf(post_s,n,fmt,args);
- if (length<0 || length>=n) sprintf(post_s+n-6,"[...]"); /* safety */
- va_end(args);
- rb_funcall(mGridFlow,SI(gfpost2),2,rb_str_new2(fmt),rb_str_new2(post_s));
-}
-
-void define_many_methods(Ruby rself, int n, MethodDecl *methods) {
- for (int i=0; i<n; i++) {
- MethodDecl *md = &methods[i];
- char *buf = strdup(md->selector);
- if (strlen(buf)>2 && strcmp(buf+strlen(buf)-2,"_m")==0)
- buf[strlen(buf)-2]=0;
- rb_define_method(rself,buf,(RMethod)md->method,-1);
- rb_enable_super(rself,buf);
- free(buf);
- }
-}
-
-static Ruby GridFlow_fclass_install(Ruby rself_, Ruby fc_, Ruby super) {
- FClass *fc = FIX2PTR(FClass,fc_);
- Ruby rself = super!=Qnil ?
- rb_define_class_under(mGridFlow, fc->name, super) :
- rb_funcall(mGridFlow,SI(const_get),1,rb_str_new2(fc->name));
- define_many_methods(rself,fc->methodsn,fc->methods);
- rb_ivar_set(rself,SI(@allocator),PTR2FIX((void*)(fc->allocator))); //#!@$??
- if (fc->startup) fc->startup(rself);
- return Qnil;
-}
-
-//----------------------------------------------------------------
-// GridFlow.class
-//\class GridFlow_s < patate
-
-typedef void (*Callback)(void*);
-static Ruby GridFlow_exec (Ruby rself, Ruby data, Ruby func) {
- void *data2 = FIX2PTR(void,data);
- Callback func2 = (Callback) FIX2PTR(void,func);
- func2(data2);
- return Qnil;
-}
-
-static Ruby GridFlow_get_id (Ruby rself, Ruby arg) {
- fprintf(stderr,"%ld\n",arg);
- return INT2NUM((int)arg);
-}
-
-Ruby GridFlow_rdtsc (Ruby rself) { return gf_ull2num(rdtsc()); }
-
-/* This code handles nested lists because PureData (0.38) doesn't do it */
-static Ruby GridFlow_handle_braces(Ruby rself, Ruby argv) {
- int stack[16];
- int stackn=0;
- Ruby *av = rb_ary_ptr(argv);
- int ac = rb_ary_len(argv);
- int j=0;
- for (int i=0; i<ac; ) {
- int close=0;
- if (SYMBOL_P(av[i])) {
- const char *s = rb_sym_name(av[i]);
- while (*s=='(' || *s=='{') {
- if (stackn==16) RAISE("too many nested lists (>16)");
- stack[stackn++]=j;
- s++;
- }
- const char *se = s+strlen(s);
- while (se>s && (se[-1]==')' || se[-1]=='}')) { se--; close++; }
- if (s!=se) {
- Ruby u = rb_str_new(s,se-s);
- av[j++] = rb_funcall(rself,SI(FloatOrSymbol),1,u);
- }
- } else {
- av[j++]=av[i];
- }
- i++;
- while (close--) {
- if (!stackn) RAISE("unbalanced '}' or ')'",av[i]);
- Ruby a2 = rb_ary_new();
- int j2 = stack[--stackn];
- for (int k=j2; k<j; k++) rb_ary_push(a2,av[k]);
- j=j2;
- av[j++] = a2;
- }
- }
- if (stackn) RAISE("unbalanced '{' or '(' (stackn=%d)",stackn);
- RARRAY(argv)->len = j;
- return rself;
-}
-
-/* ---------------------------------------------------------------- */
-
-static uint32 memcpy_calls = 0;
-static uint64 memcpy_bytes = 0;
-static uint64 memcpy_time = 0;
-static uint32 malloc_calls = 0; /* only new not delete */
-static uint64 malloc_bytes = 0; /* only new not delete */
-static uint64 malloc_time = 0; /* in cpu ticks */
-
-// don't touch.
-static void gfmemcopy32(int32 *as, int32 *bs, int n) {
- int32 ba = bs-as;
-#define FOO(I) as[I] = (as+ba)[I];
- UNROLL_8(FOO,n,as)
-#undef FOO
-
-}
-
-void gfmemcopy(uint8 *out, const uint8 *in, int n) {
- uint64 t = rdtsc();
- memcpy_calls++;
- memcpy_bytes+=n;
- for (; n>16; in+=16, out+=16, n-=16) {
- ((int32*)out)[0] = ((int32*)in)[0];
- ((int32*)out)[1] = ((int32*)in)[1];
- ((int32*)out)[2] = ((int32*)in)[2];
- ((int32*)out)[3] = ((int32*)in)[3];
- }
- for (; n>4; in+=4, out+=4, n-=4) { *(int32*)out = *(int32*)in; }
- for (; n; in++, out++, n--) { *out = *in; }
- t=rdtsc()-t;
- memcpy_time+=t;
-}
-
-extern "C" {
-void *gfmalloc(size_t n) {
- uint64 t = rdtsc();
-// void *p = malloc(n);
- void *p = memalign(16,n);
- long align = (long)p & 7;
- if (align) fprintf(stderr,"malloc alignment = %ld mod 8\n",align);
- t=rdtsc()-t;
- malloc_time+=t;
- malloc_calls++;
- malloc_bytes+=n;
- return p;
-}
-void gffree(void *p) {
- uint64 t = rdtsc();
- free(p);
- t=rdtsc()-t;
- malloc_time+=t;
-}};
-
-Ruby GridFlow_memcpy_calls (Ruby rself) { return LONG2NUM(memcpy_calls); }
-Ruby GridFlow_memcpy_bytes (Ruby rself) { return gf_ull2num(memcpy_bytes); }
-Ruby GridFlow_memcpy_time (Ruby rself) { return gf_ull2num(memcpy_time); }
-Ruby GridFlow_malloc_calls (Ruby rself) { return LONG2NUM(malloc_calls); }
-Ruby GridFlow_malloc_bytes (Ruby rself) { return gf_ull2num(malloc_bytes); }
-Ruby GridFlow_malloc_time (Ruby rself) { return gf_ull2num(malloc_time); }
-
-Ruby GridFlow_profiler_reset2 (Ruby rself) {
- memcpy_calls = memcpy_bytes = memcpy_time = 0;
- malloc_calls = malloc_bytes = malloc_time = 0;
- return Qnil;
-}
-
-/* ---------------------------------------------------------------- */
-
-void startup_number();
-void startup_grid();
-void startup_flow_objects();
-void startup_flow_objects_for_image();
-void startup_flow_objects_for_matrix();
-
-Ruby cFormat;
-
-#define SDEF(_class_,_name_,_argc_) \
- rb_define_singleton_method(c##_class_,#_name_,(RMethod)_class_##_s_##_name_,_argc_)
-#define SDEF2(_name1_,_name2_,_argc_) \
- rb_define_singleton_method(mGridFlow,_name1_,(RMethod)_name2_,_argc_)
-
-STARTUP_LIST(void)
-
-// Ruby's entrypoint.
-void Init_gridflow () {
-#define FOO(_sym_,_name_) bsym._sym_ = ID2SYM(rb_intern(_name_));
-BUILTIN_SYMBOLS(FOO)
-#undef FOO
- signal(11,SIG_DFL); // paranoia
- mGridFlow = EVAL("module GridFlow; CObject = ::Object; "
- "class<<self; attr_reader :bridge_name; end; "
- "def post_string(s) STDERR.puts s end; "
- "self end");
- SDEF2("exec",GridFlow_exec,2);
- SDEF2("get_id",GridFlow_get_id,1);
- SDEF2("rdtsc",GridFlow_rdtsc,0);
- SDEF2("profiler_reset2",GridFlow_profiler_reset2,0);
- SDEF2("memcpy_calls",GridFlow_memcpy_calls,0);
- SDEF2("memcpy_bytes",GridFlow_memcpy_bytes,0);
- SDEF2("memcpy_time", GridFlow_memcpy_time,0);
- SDEF2("malloc_calls",GridFlow_malloc_calls,0);
- SDEF2("malloc_bytes",GridFlow_malloc_bytes,0);
- SDEF2("malloc_time", GridFlow_malloc_time,0);
- SDEF2("handle_braces!",GridFlow_handle_braces,1);
- SDEF2("fclass_install",GridFlow_fclass_install,2);
-
-//#define FOO(A) fprintf(stderr,"sizeof("#A")=%d\n",sizeof(A));
-//FOO(Dim) FOO(BitPacking) FOO(GridHandler) FOO(GridInlet) FOO(GridOutlet) FOO(GridObject)
-//#undef FOO
-
- rb_ivar_set(mGridFlow, SI(@fobjects), rb_hash_new());
- rb_ivar_set(mGridFlow, SI(@fclasses), rb_hash_new());
- rb_ivar_set(mGridFlow, SI(@bsym), PTR2FIX(&bsym));
- rb_define_const(mGridFlow, "GF_VERSION", rb_str_new2(GF_VERSION));
- rb_define_const(mGridFlow, "GF_COMPILE_TIME", rb_str_new2(GF_COMPILE_TIME));
- rb_define_const(mGridFlow, "GCC_VERSION", rb_str_new2(GCC_VERSION));
- cFObject = rb_define_class_under(mGridFlow, "FObject", rb_cObject);
- EVAL(
-\ruby
- module GridFlow
- class FObject
- def send_out2(*) end
- def self.install2(*) end
- def self.add_creator(name)
- name=name.to_str.dup
- GridFlow.fclasses[name]=self
- GridFlow.add_creator_2 name end
- end
- end
-\end ruby
-);
- define_many_methods(cFObject,COUNT(FObject_methods),FObject_methods);
- SDEF(FObject, install, 3);
- SDEF(FObject, new, -1);
- ID gbi = SI(gf_bridge_init);
- if (rb_respond_to(rb_cData,gbi)) rb_funcall(rb_cData,gbi,0);
- Ruby cBitPacking =
- rb_define_class_under(mGridFlow, "BitPacking", rb_cObject);
- define_many_methods(cBitPacking,
- ciBitPacking.methodsn,
- ciBitPacking.methods);
- SDEF(BitPacking,new,-1);
- rb_define_method(rb_cString, "swap32!", (RMethod)String_swap32_f, 0);
- rb_define_method(rb_cString, "swap16!", (RMethod)String_swap16_f, 0);
-
- startup_number();
- startup_grid();
- startup_flow_objects();
- startup_flow_objects_for_image();
- startup_flow_objects_for_matrix();
- if (!EVAL("begin require 'gridflow/base/main.rb'; true\n"
- "rescue Exception => e; "
- "STDERR.puts \"can't load: #{$!}\n"
- "backtrace: #{$!.backtrace.join\"\n\"}\n"
- "$: = #{$:.inspect}\"\n; false end")) return;
- cFormat = EVAL("GridFlow::Format");
- STARTUP_LIST()
- EVAL("h=GridFlow.fclasses; h['#io:window'] = h['#io:quartz']||h['#io:x11']||h['#io:sdl']");
- EVAL("GridFlow.load_user_config");
- signal(11,SIG_DFL); // paranoia
-}
-
-void GFStack::push (FObject *o) {
- void *bp = &o; // really. just finding our position on the stack.
- if (n>=GF_STACK_MAX)
- RAISE("stack overflow (maximum %d FObject activations at once)", GF_STACK_MAX);
- uint64 t = rdtsc();
- if (n) s[n-1].time = t - s[n-1].time;
- s[n].o = o;
- s[n].bp = bp;
- s[n].time = t;
- n++;
-}
-
-void GFStack::pop () {
- uint64 t = rdtsc();
- if (!n) RAISE("stack underflow (WHAT?)");
- n--;
- if (s[n].o) s[n].o->total_time += t - s[n].time;
- if (n) s[n-1].time = t - s[n-1].time;
-}
-
-uint64 gf_timeofday () {
- timeval t;
- gettimeofday(&t,0);
- return t.tv_sec*1000000+t.tv_usec;
-}
diff --git a/externals/gridflow/base/main.rb b/externals/gridflow/base/main.rb
deleted file mode 100644
index 5b33bfad..00000000
--- a/externals/gridflow/base/main.rb
+++ /dev/null
@@ -1,384 +0,0 @@
-=begin
- $Id: main.rb,v 1.2 2006-03-15 04:37:28 matju Exp $
-
- GridFlow
- Copyright (c) 2001,2002,2003,2004,2005 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.
-=end
-
-# ENV["RUBY_VERBOSE_GC"]="yes"
-
-# this file gets loaded by main.c upon startup
-# module GridFlow is supposed to be created by main.c
-# this includes GridFlow.post_string(s)
-
-# because Ruby1.6 has no #object_id and Ruby1.8 warns on #id
-unless Object.instance_methods(true).include? "object_id"
- class Object; alias object_id id end
-end
-
-# in case of bug in Ruby ("Error: Success")
-module Errno; class E000 < StandardError; end; end
-
-#$post_log = File.open "/tmp/gridflow.log", "w"
-$post_log = nil
-
-class Array
- def split(elem)
- r=[]
- j=0
- for i in 0...length
- (r<<self[j,i-j]; j=i+1) if self[i]==elem
- end
- r<<self[j,length-j]
- end
-end
-
-module GridFlow #------------------
-
-def self.post(s,*a)
- post_string(sprintf("%s"+s,post_header,*a))
- ($post_log << sprintf(s,*a); $post_log.flush) if $post_log
-end
-
-class<<self
- attr_accessor :data_path
- attr_accessor :post_header
- attr_accessor :verbose
- attr_reader :fobjects
- attr_reader :fclasses
- attr_reader :cpu_hertz
- attr_reader :subprocesses
- attr_reader :bridge_name
- alias gfpost post
-end
-
-@subprocesses={}
-@verbose=false
-@data_path=[]
-if GridFlow.respond_to? :config then
- @data_path << GridFlow.config["PUREDATA_PATH"]+"/extra/gridflow/images"
-end
-
-def self.hunt_zombies
- #STDERR.puts "GridFlow.hunt_zombies"
- # the $$ value is bogus
- begin
- died = []
- subprocesses.each {|x,v|
- Process.waitpid2(x,Process::WNOHANG) and died<<x
- }
- rescue Errno::ECHILD
- end
- #STDERR.puts died.inspect
- died.each {|x| subprocesses.delete x }
-end
-
-def self.packstring_for_nt(nt)
- case nt
- when :u, :u8, :uint8; "C*"
- when :s, :i16, :int16; "s*"
- when :i, :i32, :int32; "l*"
- when :l, :i64, :int64; raise "int64? lol"
- when :f, :f32, :float32; "f*"
- when :d, :f64, :float64; "d*"
- else raise "no decoder for #{nt.inspect}"
- end
-end
-
-self.post_header = "[gf] "
-
-def self.gfpost2(fmt,s); post("%s",s) end
-
-if GridFlow.bridge_name then
- post "This is GridFlow #{GridFlow::GF_VERSION} within Ruby version #{RUBY_VERSION}"
- post "base/main.c was compiled on #{GridFlow::GF_COMPILE_TIME}"
- post "Please use at least 1.6.6 if you plan to use sockets" if RUBY_VERSION<"1.6.6"
-end
-
-if not GridFlow.bridge_name then
- require "gridflow/bridge/placebo"
-end
-
-Brace1 = "{".intern
-Brace2 = "}".intern
-Paren1 = "(".intern
-Paren2 = ")".intern
-
-def self.parse(m)
- m = m.gsub(/(\{|\})/," \\1 ").split(/\s+/)
- m.map! {|x| case x
- when Integer, Symbol; x
- when /^[+\-]?[0-9]+$/; x.to_i
- when String; x.intern
- end
- }
- m
-end
-
-def self.stringify_list(argv)
- argv.map {|x| stringify x }.join(" ")
-end
-
-def self.stringify(arg)
- case arg
- when Integer, Float, Symbol; arg.to_s
- when Array; "{#{stringify_list arg}}"
- end
-end
-
-::Object.module_eval do def FloatOrSymbol(x) Float(x) rescue x.intern end end
-
-# adding some functionality to that:
-class FObject
- @broken_ok = false
- @do_loadbangs = true
- class<<self
- # global
- attr_accessor :broken_ok
- # per-class
- attr_reader :ninlets
- attr_reader :noutlets
- attr_accessor :do_loadbangs
- attr_accessor :comment
- def foreign_name; @foreign_name if defined? @foreign_name end
- def doc(selector=nil,text=nil)
- return @doc if not selector
- if not defined? @doc; @doc={}; end
- return @doc[selector] if not text
- @doc[selector] = text
- end
- def doc_out(selector=nil,text=nil)
- return @doc_out if not selector
- if not defined? @doc_out; @doc_out={}; end
- return @doc_out[selector] if not text
- @doc_out[selector] = text
- end
- end
- def post(*a) GridFlow.post(*a) end
- def self.subclass(*args,&b)
- qlass = Class.new self
- qlass.install(*args)
- #qlass.module_eval{qlass.instance_eval(&b)}
- qlass.instance_eval{qlass.module_eval(&b)}
- #qlass.module_eval(&b)
- end
- alias :total_time :total_time_get
- alias :total_time= :total_time_set
- attr_writer :args # String
- attr_accessor :argv # Array
- attr_reader :outlets
- attr_accessor :parent_patcher
- attr_accessor :properties
- attr_accessor :classname
- def initialize2; end
- def args
- if defined? @args
- @args
- else
- "[#{self.class} ...]"
- end
- end
- alias info args
- def connect outlet, object, inlet
- @outlets ||= []
- @outlets[outlet] ||= []
- @outlets[outlet].push [object, inlet]
- end
- def self.name_lookup sym
- qlasses = GridFlow.fclasses
- qlass = qlasses[sym.to_s]
- if not qlass
- return qlasses['broken'] if @broken_ok
- raise "object class '#{sym}' not found"
- end
- qlass
- end
- def self.[](*m)
- o=nil
- if m.length==1 and m[0] =~ / /
- o="[#{m[0]}]"
- m=GridFlow.parse(m[0])
- else
- o=m.inspect
- end
- GridFlow.handle_braces!(m)
- ms = m.split ','.intern
- m = ms.shift
- qlass = m.shift
- qlassname = qlass.to_s
- qlass = name_lookup qlass.to_s unless Class===qlass
- r = qlass.new(*m)
- r.classname = qlassname
- GridFlow.post "%s",r.args if GridFlow.verbose
- for x in ms do r.send_in(-2, *x) end if FObject.do_loadbangs
- r
- end
- def inspect
- if args then "#<#{self.class} #{args}>" else super end
- end
- def initialize(*argv)
- s = GridFlow.stringify_list argv
- @argv = argv
- @args = "["
- @args << (self.class.foreign_name || self.to_s)
- @args << " " if s.length>0
- @args << s << "]"
- @parent_patcher = nil
- @properties = {}
- @init_messages = []
- end
-end
-
-class FPatcher < FObject
- class << self
- attr_reader :fobjects
- attr_reader :wires
- end
- def initialize(*)
- super
- fobjects = self.class.fobjects
- wires = self.class.wires
- @fobjects = fobjects.map {|x| if String===x then FObject[x] else x.call end }
- @inlets = []
- @ninlets = self.class.ninlets or raise "oops"
- i=0
- @fobjects << self
- while i<wires.length do
- a,b,c,d = wires[i,4]
- if a==-1 then
- a=self
- @inlets[b]||=[]
- @inlets[b] << [@fobjects[c],d]
- else
- if c==-1 then
- @fobjects[a].connect b,self,d+@ninlets
- else
- @fobjects[a].connect b,@fobjects[c],d
- end
- end
- i+=4
- end
- end
- def method_missing(sym,*args)
- sym=sym.to_s
- if sym =~ /^_(\d)_(.*)/ then
- inl = Integer $1
- sym = $2.intern
- if inl<@ninlets then
- raise "#{inspect} has not @inlets[#{inl}]" if not @inlets[inl]
- for x in @inlets[inl] do
- x[0].send_in x[1],sym,*args end
- else
- send_out(inl-@ninlets,sym,*args)
- end
- else super end
- end
-end
-
-def GridFlow.estimate_cpu_clock
- u0,t0=GridFlow.rdtsc,Time.new.to_f; sleep 0.01
- u1,t1=GridFlow.rdtsc,Time.new.to_f; (u1-u0)/(t1-t0)
-end
-
-begin
- @cpu_hertz = (0...3).map {
- GridFlow.estimate_cpu_clock
- }.sort[1] # median of three tries
-rescue
- GridFlow.post $!
-end
-
-def GridFlow.find_file s
- s=s.to_s
- if s==File.basename(s) then
- dir = GridFlow.data_path.find {|x| File.exist? "#{x}/#{s}" }
- if dir then "#{dir}/#{s}" else s end
- elsif GridFlow.respond_to? :find_file_2
- GridFlow.find_file_2 s
- else
- s
- end
-end
-
-def GridFlow.macerr(i)
- begin
- f=File.open("/System/Library/Frameworks/CoreServices.framework/"+
- "Versions/A/Frameworks/CarbonCore.framework/Versions/A/Headers/"+
- "MacErrors.h")
- while f.gets
- m = /^\s*(\w+)\s*=\s*(-\d+),\s*\/\*\s*(.*)\s*\*\/$/.match $_
- next if not m
- if m[2].to_i == i then return "#{m[2]}: \"#{m[3]}\"" end
- end
- return "no error message available for this error number"
- rescue FileError
- return "Can't find Apple's precious copyrighted list of error messages on this system."
- ensure
- f.close if f
- end
-end
-
-end # module GridFlow
-
-class IO
- def nonblock= flag
- bit = Fcntl::O_NONBLOCK
- state = fcntl(Fcntl::F_GETFL, 0)
- fcntl(Fcntl::F_SETFL, (state & ~bit) |
- (if flag; bit else 0 end))
- end
-end
-
-def protect
- yield
-rescue Exception => e
- STDERR.puts "#{e.class}: #{e}"
- STDERR.puts e.backtrace
-end
-
-def GridFlow.load_user_config
- require "gridflow/bridge/puredata.rb" if GridFlow.bridge_name == "puredata"
- user_config_file = ENV["HOME"] + "/.gridflow_startup"
- begin
- load user_config_file if File.exist? user_config_file
- rescue Exception => e
- GridFlow.post "#{e.class}: #{e}:\n" + e.backtrace.join("\n")
- GridFlow.post "while loading ~/.gridflow_startup"
- end
-end
-
-require "gridflow/base/flow_objects.rb"
-require "gridflow/format/main.rb"
-
-%w(
- # #for #finished #type #dim #transpose #perspective #store #outer
- #grade #redim #import #export #export_list #cast
- #scale_by #downscale_by #draw_polygon #draw_image #layer
- #print #pack #export_symbol #rotate
- #in #out
-).each {|k|
- GridFlow::FObject.name_lookup(k).add_creator k.gsub(/#/,"@")
-}
-
-END {
- GridFlow.fobjects.each {|k,v| k.delete if k.respond_to? :delete }
- GridFlow.fobjects.clear
- GC.start
-}
-
diff --git a/externals/gridflow/base/number.c b/externals/gridflow/base/number.c
deleted file mode 100644
index b362e2cb..00000000
--- a/externals/gridflow/base/number.c
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- $Id: number.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 "grid.h.fcs"
-#include <math.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <limits.h>
-
-#ifdef PASS1
-NumberType number_type_table[] = {
-#define FOO(_sym_,_size_,_flags_,args...) NumberType( #_sym_, _size_, _flags_, args ),
-NUMBER_TYPES(FOO)
-#undef FOO
-};
-const long number_type_table_n = COUNT(number_type_table);
-#endif
-
-// those are bogus class-templates in the sense that you don't create
-// objects from those, you just call static functions. The same kind
-// of pattern is present in STL to overcome some limitations of C++.
-
-template <class T> class Op {
-public:
- // I call abort() on those because I can't say they're purevirtual.
- static T f(T a, T b) {abort();}
- static bool is_neutral(T x, LeftRight side) {assert(!"Op::is_neutral called?"); return false;}
- static bool is_absorbent(T x, LeftRight side) {assert(!"Op::is_absorbent called?"); return false;}
-};
-
-template <class O> class OpLoops {
-public:
- template <class T> static void op_map (int n, T *as, T b) {
- if (!n) return;
-#define FOO(I) as[I]=O::f(as[I],b);
- UNROLL_8(FOO,n,as)
-#undef FOO
- }
- template <class T> static void op_zip (int n, T *as, T *bs) {
- if (!n) return;
- ptrdiff_t ba=bs-as; // really!
-#define FOO(I) as[I]=O::f(as[I],as[ba+I]);
- UNROLL_8(FOO,n,as)
-#undef FOO
- }
- // disabled
- template <class T> static void op_zip2 (int n, T *as, T *bs, T *cs) {
- if (!n) return;
- ptrdiff_t ba=bs-as, ca=cs-as;
-#define FOO(I) as[ca+I]=O::f(as[I],as[ba+I]);
- UNROLL_8(FOO,n,as)
-#undef FOO
- }
-#define W(i) as[i]=O::f(as[i],bs[i]);
-#define Z(i,j) as[i]=O::f(O::f(O::f(O::f(as[i],bs[i]),bs[i+j]),bs[i+j+j]),bs[i+j+j+j]);
- template <class T> static void op_fold (int an, int n, T *as, T *bs) {
- switch (an) {
- case 1: for (; (n&3)!=0; bs++, n--) W(0);
- for (; n; bs+=4, n-=4) { Z(0,1); } break;
- case 2: for (; (n&3)!=0; bs+=2, n--) { W(0); W(1); }
- for (; n; bs+=8, n-=4) { Z(0,2); Z(1,2); } break;
- case 3: for (; (n&3)!=0; bs+=3, n--) { W(0); W(1); W(2); }
- for (; n; bs+=12, n-=4) { Z(0,3); Z(1,3); Z(2,3); } break;
- case 4: for (; (n&3)!=0; bs+=4, n--) { W(0); W(1); W(2); W(3); }
- for (; n; bs+=16, n-=4) { Z(0,4); Z(1,4); Z(2,4); Z(3,4); } break;
- default:for (; n--; ) {
- int i=0;
- for (; i<(an&-4); i+=4, bs+=4) {
- as[i+0]=O::f(as[i+0],bs[0]);
- as[i+1]=O::f(as[i+1],bs[1]);
- as[i+2]=O::f(as[i+2],bs[2]);
- as[i+3]=O::f(as[i+3],bs[3]);
- }
- for (; i<an; i++, bs++) as[i] = O::f(as[i],*bs);
- }
- }
- }
- template <class T> static void op_scan (int an, int n, T *as, T *bs) {
- for (; n--; as=bs-an) {
- for (int i=0; i<an; i++, as++, bs++) *bs=O::f(*as,*bs);
- }
- }
-};
-
-template <class T>
-static void quick_mod_map (int n, T *as, T b) {
- if (!b) return;
-#define FOO(I) as[I]=mod(as[I],b);
- UNROLL_8(FOO,n,as)
-#undef FOO
-}
-
-template <class T> static void quick_ign_map (int n, T *as, T b) {}
-template <class T> static void quick_ign_zip (int n, T *as, T *bs) {}
-template <class T> static void quick_put_map (int n, T *as, T b) {
-#define FOO(I) as[I]=b;
- UNROLL_8(FOO,n,as)
-#undef FOO
-}
-
-#ifdef PASS1
-void quick_put_map (int n, int16 *as, int16 b) {
- if (n&1!=0 && (long)as&4!=0) { *as++=b; n--; }
- quick_put_map (n>>1, (int32 *)as, (int32)(b<<16)+b);
- if (n&1!=0) *as++=b;
-}
-void quick_put_map (int n, uint8 *as, uint8 b) {
- while (n&3!=0 && (long)as&4!=0) { *as++=b; n--; }
- int32 c=(b<<8)+b; c+=c<<16;
- quick_put_map (n>>2, (int32 *)as, c);
- while (n&3!=0) *as++=b;
-}
-#endif
-template <class T> static void quick_put_zip (int n, T *as, T *bs) {
- gfmemcopy((uint8 *)as, (uint8 *)bs, n*sizeof(T));
-}
-
-// classic two-input operator
-#define DEF_OP(op,expr,neu,isneu,isorb) \
- template <class T> class Y##op : Op<T> { public: \
- inline static T f(T a, T b) { return expr; } \
- inline static T neutral (LeftRight side) {return neu;} \
- inline static bool is_neutral (T x, LeftRight side) {return isneu;} \
- inline static bool is_absorbent(T x, LeftRight side) {return isorb;}};
-#define DEF_OPFT(op,expr,neu,isneu,isorb,T) \
- template <> class Y##op<T> : Op<T> { public: \
- inline static T f(T a, T b) { return expr; } \
- inline static T neutral (LeftRight side) {return neu;} \
- inline static bool is_neutral (T x, LeftRight side) {return isneu;} \
- inline static bool is_absorbent(T x, LeftRight side) {return isorb;}};
-// this macro is for operators that have different code for the float version
-#define DEF_OPF(op,expr,expr2,neu,isneu,isorb) \
- DEF_OP( op,expr, neu,isneu,isorb) \
- DEF_OPFT(op,expr2,neu,isneu,isorb,float32) \
- DEF_OPFT(op,expr2,neu,isneu,isorb,float64)
-
-#define DECL_OPON(base,op,T) NumopOn<T>( \
- &base<Y##op<T> >::op_map, &base<Y##op<T> >::op_zip, \
- &base<Y##op<T> >::op_fold, &base<Y##op<T> >::op_scan, \
- &Y##op<T>::neutral, &Y##op<T>::is_neutral, &Y##op<T>::is_absorbent)
-#define DECL_OPON_NOFOLD(base,op,T) NumopOn<T>( \
- &base<Y##op<T> >::op_map, &base<Y##op<T> >::op_zip, 0,0, \
- &Y##op<T>::neutral, &Y##op<T>::is_neutral, &Y##op<T>::is_absorbent)
-#define DECL_OP(op,sym,flags) Numop(0, sym, \
- DECL_OPON(OpLoops,op,uint8), DECL_OPON(OpLoops,op,int16), \
- DECL_OPON(OpLoops,op,int32) NONLITE(, DECL_OPON(OpLoops,op,int64), \
- DECL_OPON(OpLoops,op,float32), DECL_OPON(OpLoops,op,float64), \
- DECL_OPON(OpLoops,op,ruby)), flags)
-#define DECL_OP_NOFLOAT(op,sym,flags) Numop(0, sym, \
- DECL_OPON(OpLoops,op,uint8), DECL_OPON(OpLoops,op,int16), \
- DECL_OPON(OpLoops,op,int32) NONLITE(, DECL_OPON(OpLoops,op,int64), \
- NumopOn<float32>(0,0,0,0,0,0,0), NumopOn<float64>(0,0,0,0,0,0,0), \
- DECL_OPON(OpLoops,op,ruby)), flags)
-#define DECL_OP_NOFOLD(op,sym,flags) Numop(0, sym, \
- DECL_OPON_NOFOLD(OpLoops,op,uint8), DECL_OPON_NOFOLD(OpLoops,op,int16), \
- DECL_OPON_NOFOLD(OpLoops,op,int32) NONLITE(, DECL_OPON_NOFOLD(OpLoops,op,int64), \
- DECL_OPON_NOFOLD(OpLoops,op,float32), DECL_OPON_NOFOLD(OpLoops,op,float64), \
- DECL_OPON_NOFOLD(OpLoops,op,ruby)), flags)
-
-template <class T> static inline T gf_floor (T a) {
- return (T) floor((double)a); }
-template <class T> static inline T gf_trunc (T a) {
- return (T) floor(abs((double)a)) * (a<0?-1:1); }
-
-// trying to avoid GCC warning about uint8 too small for ==256
-template <class T> static bool equal256 (T x) {return x==256;}
-template <> static bool equal256 (uint8 x) {return false;}
-
-#ifdef PASS1
-DEF_OP(ignore, a, 0, side==at_right, side==at_left)
-DEF_OP(put, b, 0, side==at_left, side==at_right)
-DEF_OP(add, a+b, 0, x==0, false)
-DEF_OP(sub, a-b, 0, side==at_right && x==0, false)
-DEF_OP(bus, b-a, 0, side==at_left && x==0, false)
-DEF_OP(mul, a*b, 1, x==1, x==0)
-DEF_OP(mulshr8, (a*b)>>8, 256, equal256(x), x==0)
-DEF_OP(div, b==0 ? (T)0 : a/b , 1, side==at_right && x==1, false)
-DEF_OP(div2, b==0 ? 0 : div2(a,b), 1, side==at_right && x==1, false)
-DEF_OP(vid, a==0 ? (T)0 : b/a , 1, side==at_left && x==1, false)
-DEF_OP(vid2, a==0 ? 0 : div2(b,a), 1, side==at_left && x==1, false)
-DEF_OPF(mod, b==0 ? 0 : mod(a,b), b==0 ? 0 : a-b*gf_floor(a/b), 0, false, side==at_left && x==0 || side==at_right && x==1)
-DEF_OPF(dom, a==0 ? 0 : mod(b,a), a==0 ? 0 : b-a*gf_floor(b/a), 0, false, side==at_left && x==0 || side==at_right && x==1)
-//DEF_OPF(rem, b==0 ? 0 : a%b, b==0 ? 0 : a-b*gf_trunc(a/b))
-//DEF_OPF(mer, a==0 ? 0 : b%a, a==0 ? 0 : b-a*gf_trunc(b/a))
-DEF_OP(rem, b==0?(T)0:a%b, 0, false, side==at_left&&x==0 || side==at_right&&x==1)
-DEF_OP(mer, a==0?(T)0:b%a, 0, false, side==at_left&&x==0 || side==at_right&&x==1)
-#endif
-#ifdef PASS2
-DEF_OP(gcd, gcd(a,b), 0, x==0, x==1)
-DEF_OP(gcd2, gcd2(a,b), 0, x==0, x==1) // should test those and pick one of the two
-DEF_OP(lcm, a==0 || b==0 ? (T)0 : lcm(a,b), 1, x==1, x==0)
-DEF_OPF(or , a|b, (float32)((int32)a | (int32)b), 0, x==0, x==nt_all_ones(&x))
-DEF_OPF(xor, a^b, (float32)((int32)a ^ (int32)b), 0, x==0, false)
-DEF_OPF(and, a&b, (float32)((int32)a & (int32)b), -1 /*nt_all_ones((T*)0)*/, x==nt_all_ones(&x), x==0)
-DEF_OPF(shl, a<<b, a*pow(2.0,+b), 0, side==at_right && x==0, false)
-DEF_OPF(shr, a>>b, a*pow(2.0,-b), 0, side==at_right && x==0, false)
-DEF_OP(sc_and, a ? b : a, 1, side==at_left && x!=0, side==at_left && x==0)
-DEF_OP(sc_or, a ? a : b, 0, side==at_left && x==0, side==at_left && x!=0)
-DEF_OP(min, min(a,b), nt_greatest((T*)0), x==nt_greatest(&x), x==nt_smallest(&x))
-DEF_OP(max, max(a,b), nt_smallest((T*)0), x==nt_smallest(&x), x==nt_greatest(&x))
-DEF_OP(cmp, cmp(a,b), 0, false, false)
-DEF_OP(eq, a == b, 0, false, false)
-DEF_OP(ne, a != b, 0, false, false)
-DEF_OP(gt, a > b, 0, false, side==at_left&&x==nt_smallest(&x)||side==at_right&&x==nt_greatest(&x))
-DEF_OP(le, a <= b, 0, false, side==at_left&&x==nt_smallest(&x)||side==at_right&&x==nt_greatest(&x))
-DEF_OP(lt, a < b, 0, false, side==at_left&&x==nt_greatest(&x)||side==at_right&&x==nt_smallest(&x))
-DEF_OP(ge, a >= b, 0, false, side==at_left&&x==nt_greatest(&x)||side==at_right&&x==nt_smallest(&x))
-#endif
-#ifdef PASS3
-DEF_OP(sin, (T)((float64)b * sin((float64)a * (M_PI / 18000))), 0, false, false) // "LN=9000+36000n RA=0 LA=..."
-DEF_OP(cos, (T)((float64)b * cos((float64)a * (M_PI / 18000))), 0, false, false) // "LN=36000n RA=0 LA=..."
-DEF_OP(atan, (T)(atan2(a,b) * (18000 / M_PI)), 0, false, false) // "LA=0"
-DEF_OP(tanh, (T)((float64)b * tanh((float64)a * (M_PI / 18000))), 0, false, x==0)
-DEF_OP(gamma, b<=0 ? (T)0 : (T)(0+floor(pow((float64)a/256.0,256.0/(float64)b)*256.0)), 0, false, false) // "RN=256"
-DEF_OP(pow, ipow(a,b), 0, false, false) // "RN=1"
-DEF_OP(log, (T)(a==0 ? (T)0 : (T)((float64)b * log((float64)gf_abs(a)))), 0, false, false) // "RA=0"
-// 0.8
-DEF_OPF(clipadd, clipadd(a,b), a+b, 0, x==0, false)
-DEF_OPF(clipsub, clipsub(a,b), a-b, 0, side==at_right && x==0, false)
-DEF_OP(abssub, gf_abs(a-b), 0, false, false)
-DEF_OP(sqsub, (a-b)*(a-b), 0, false, false)
-DEF_OP(avg, (a+b)/2, 0, false, false)
-DEF_OP(hypot, (T)(0+floor(sqrt(a*a+b*b))), 0, false, false)
-DEF_OP(sqrt, (T)(0+floor(sqrt(a))), 0, false, false)
-DEF_OP(rand, a==0 ? (T)0 : (T)(random()%(int32)a), 0, false, false)
-//DEF_OP(erf,"erf*", 0)
-#endif
-
-extern Numop op_table1[], op_table2[], op_table3[];
-extern const long op_table1_n, op_table2_n, op_table3_n;
-
-#ifdef PASS1
-Numop op_table1[] = {
- DECL_OP(ignore, "ignore", OP_ASSOC),
- DECL_OP(put, "put", OP_ASSOC),
- DECL_OP(add, "+", OP_ASSOC|OP_COMM), // "LINV=sub"
- DECL_OP(sub, "-", 0),
- DECL_OP(bus, "inv+", 0),
- DECL_OP(mul, "*", OP_ASSOC|OP_COMM),
- DECL_OP_NOFLOAT(mulshr8, "*>>8", OP_ASSOC|OP_COMM),
- DECL_OP(div, "/", 0),
- DECL_OP_NOFLOAT(div2, "div", 0),
- DECL_OP(vid, "inv*", 0),
- DECL_OP_NOFLOAT(vid2, "swapdiv", 0),
- DECL_OP_NOFLOAT(mod, "%", 0),
- DECL_OP_NOFLOAT(dom, "swap%", 0),
- DECL_OP_NOFLOAT(rem, "rem", 0),
- DECL_OP_NOFLOAT(mer, "swaprem", 0),
-};
-const long op_table1_n = COUNT(op_table1);
-#endif
-#ifdef PASS2
-Numop op_table2[] = {
- DECL_OP_NOFLOAT(gcd, "gcd", OP_ASSOC|OP_COMM),
- DECL_OP_NOFLOAT(gcd2, "gcd2", OP_ASSOC|OP_COMM),
- DECL_OP_NOFLOAT(lcm, "lcm", OP_ASSOC|OP_COMM),
- DECL_OP(or , "|", OP_ASSOC|OP_COMM),
- DECL_OP(xor, "^", OP_ASSOC|OP_COMM),
- DECL_OP(and, "&", OP_ASSOC|OP_COMM),
- DECL_OP_NOFOLD(shl, "<<", 0),
- DECL_OP_NOFOLD(shr, ">>", 0),
- DECL_OP_NOFOLD(sc_and,"&&", 0),
- DECL_OP_NOFOLD(sc_or, "||", 0),
- DECL_OP(min, "min", OP_ASSOC|OP_COMM),
- DECL_OP(max, "max", OP_ASSOC|OP_COMM),
- DECL_OP_NOFOLD(eq, "==", OP_COMM),
- DECL_OP_NOFOLD(ne, "!=", OP_COMM),
- DECL_OP_NOFOLD(gt, ">", 0),
- DECL_OP_NOFOLD(le, "<=", 0),
- DECL_OP_NOFOLD(lt, "<", 0),
- DECL_OP_NOFOLD(ge, ">=", 0),
- DECL_OP_NOFOLD(cmp, "cmp", 0),
-};
-const long op_table2_n = COUNT(op_table2);
-#endif
-#ifdef PASS3
-uint8 clipadd(uint8 a, uint8 b) { int32 c=a+b; return c<0?0:c>255?255:c; }
-int16 clipadd(int16 a, int16 b) { int32 c=a+b; return c<-0x8000?-0x8000:c>0x7fff?0x7fff:c; }
-int32 clipadd(int32 a, int32 b) { int64 c=a+b; return c<-0x80000000?-0x80000000:c>0x7fffffff?0x7fffffff:c; }
-int64 clipadd(int64 a, int64 b) { int64 c=(a>>1)+(b>>1)+(a&b&1), p=nt_smallest((int64 *)0), q=nt_greatest((int64 *)0);
- return c<p/2?p:c>q/2?q:a+b; }
-uint8 clipsub(uint8 a, uint8 b) { int32 c=a-b; return c<0?0:c>255?255:c; }
-int16 clipsub(int16 a, int16 b) { int32 c=a-b; return c<-0x8000?-0x8000:c>0x7fff?0x7fff:c; }
-int32 clipsub(int32 a, int32 b) { int64 c=a-b; return c<-0x80000000?-0x80000000:c>0x7fffffff?0x7fffffff:c; }
-int64 clipsub(int64 a, int64 b) { int64 c=(a>>1)-(b>>1); //???
- int64 p=nt_smallest((int64 *)0), q=nt_greatest((int64 *)0);
- return c<p/2?p:c>q/2?q:a-b; }
-
-ruby clipadd(ruby a, ruby b) { return a+b; }
-ruby clipsub(ruby a, ruby b) { return a-b; }
-
-Numop op_table3[] = {
- DECL_OP_NOFOLD(sin, "sin*", 0),
- DECL_OP_NOFOLD(cos, "cos*", 0),
- DECL_OP_NOFOLD(atan, "atan", 0),
- DECL_OP_NOFOLD(tanh, "tanh*", 0),
- DECL_OP_NOFOLD(gamma, "gamma", 0),
- DECL_OP_NOFOLD(pow, "**", 0),
- DECL_OP_NOFOLD(log, "log*", 0),
-// 0.8
- DECL_OP(clipadd,"clip+", OP_ASSOC|OP_COMM),
- DECL_OP(clipsub,"clip-", 0),
- DECL_OP_NOFOLD(abssub,"abs-", OP_COMM),
- DECL_OP_NOFOLD(sqsub,"sq-", OP_COMM),
- DECL_OP_NOFOLD(avg,"avg", OP_COMM),
- DECL_OP_NOFOLD(hypot,"hypot", OP_COMM),
- DECL_OP_NOFOLD(sqrt,"sqrt", 0),
- DECL_OP_NOFOLD(rand,"rand", 0),
- //DECL_OP_NOFOLD(erf,"erf*", 0),
-};
-const long op_table3_n = COUNT(op_table3);
-#endif
-
-// D=dictionary, A=table, A##_n=table count.
-#define INIT_TABLE(D,A) { D=IEVAL(mGridFlow,"@"#D" ||= {}"); \
- for(int i=0; i<A##_n; i++) { \
- A[i].sym = ID2SYM(rb_intern(A[i].name)); \
- rb_hash_aset(D,A[i].sym,PTR2FIX((A+i)));}}
-
-#ifdef PASS1
-Ruby op_dict = Qnil;
-Ruby number_type_dict = Qnil;
-void startup_number () {
- INIT_TABLE(op_dict,op_table1)
- INIT_TABLE(op_dict,op_table2)
- INIT_TABLE(op_dict,op_table3)
- INIT_TABLE(number_type_dict,number_type_table)
-
- for (int i=0; i<COUNT(number_type_table); i++) {
- number_type_table[i].index = (NumberTypeE) i;
- char a[64];
- strcpy(a,number_type_table[i].aliases);
- char *b = strchr(a,',');
- if (b) {
- *b=0;
- rb_hash_aset(number_type_dict, ID2SYM(rb_intern(b+1)),
- PTR2FIX(&number_type_table[i]));
- }
- rb_hash_aset(number_type_dict, ID2SYM(rb_intern(a)),
- PTR2FIX(&number_type_table[i]));
- }
-// S:name; M:mode; F:replacement function;
-#define OVERRIDE_INT(S,M,F) { \
- Numop *foo = FIX2PTR(Numop,rb_hash_aref(op_dict,SYM(S))); \
- foo->on_uint8.op_##M=F; \
- foo->on_int16.op_##M=F; \
- foo->on_int32.op_##M=F; }
- OVERRIDE_INT(ignore,map,quick_ign_map);
- OVERRIDE_INT(ignore,zip,quick_ign_zip);
- //OVERRIDE_INT(put,map,quick_put_map);
- //OVERRIDE_INT(put,zip,quick_put_zip);
- //OVERRIDE_INT(%,map,quick_mod_map); // !@#$ does that make an improvement at all?
-}
-#endif
diff --git a/externals/gridflow/base/source_filter.rb b/externals/gridflow/base/source_filter.rb
deleted file mode 100644
index c55f4d95..00000000
--- a/externals/gridflow/base/source_filter.rb
+++ /dev/null
@@ -1,276 +0,0 @@
-#!/usr/bin/env ruby
-
-$keywords = %w(class decl def end grdecl)
-$stack = []
-$classes = []
-
-ClassDecl = Struct.new(:name,:supername,:methods,:grins,:attrs,:info)
-MethodDecl = Struct.new(:rettype,:selector,:arglist,:minargs,:maxargs,:where,:static)
-Arg = Struct.new(:type,:name,:default)
-
-class MethodDecl
- def ==(o)
- return false unless rettype==o.rettype && static==o.static &&
- maxargs==o.maxargs # && minargs==o.minargs
- arglist.each_index{|i| arglist[i] == o.arglist[i] or return false }
- return true
- end
-end
-
-class Arg
- def ==(o)
- type==o.type && name==o.name # && default==o.default
- end
-end
-
-In = File.open ARGV[0], "r"
-Out = File.open ARGV[1], "w"
-
-def handle_class(line)
- raise "already in class #{where}" if $stack[-1] and ClassDecl===$stack[-1]
- #STDERR.puts "class: #{line}"
- /^(\w+)(?:\s*<\s*(\w+))?$/.match line or raise "syntax error #{where}"
- q=ClassDecl.new($1,$2,{},{},{},false)
- $stack << q
- $classes << q
- Out.puts ""
-end
-
-def parse_methoddecl(line,term)
- /^(static\s)?\s*(\w+)\s+(\w+)\s*\(([^\)]*)\)\s*#{term}/.match line or
- raise "syntax error #{where} #{line}"
- static,rettype,selector,arglist = $1,$2,$3,$4
- arglist,minargs,maxargs = parse_arglist arglist
- MethodDecl.new(rettype,selector,arglist,minargs,maxargs,where,static)
-end
-
-def parse_arglist(arglist)
- arglist = arglist.split(/,/)
- maxargs = arglist.length
- args = arglist.map {|arg|
- if /^\s*\.\.\.\s*$/.match arg then maxargs=-1; next end
- /^\s*([\w\s\*<>]+)\s*\b(\w+)\s*(?:\=(.*))?/.match arg or
- raise "syntax error in \"#{arg}\" #{where}"
- type,name,default=$1,$2,$3
- Arg.new(type.sub(/\s+$/,""),name,default)
- }.compact
- minargs = args.length
- minargs-=1 while minargs>0 and args[minargs-1].default
- [args,minargs,maxargs]
-end
-
-def unparse_arglist(arglist,with_default=true)
- arglist.map {|arg|
- x="#{arg.type} #{arg.name} "
- x<<'='<<arg.default if with_default and arg.default
- x
- }.join(", ")
-end
-
-def where
- "[#{ARGV[0]}:#{$linenumber}]"
-end
-
-def handle_attr(line)
- type = line.gsub(%r"//.*$","").gsub(%r"/\*.*\*/","").gsub(%r";?\s*$","")
- name = type.slice!(/\w+$/)
- raise "missing \\class #{where}" if
- not $stack[-1] or not ClassDecl===$stack[-1]
- $stack[-1].attrs[name]=Arg.new(type,name,nil)
- Out.print line.gsub(/\/\/.*$/,"") # hack!
- handle_decl "void _0_#{name}_m (#{type} #{name});"
-# Out.puts "# #{$linenumber}"
-end
-
-def handle_decl(line)
- raise "missing \\class #{where}" if
- not $stack[-1] or not ClassDecl===$stack[-1]
- classname = $stack[-1].name
- m = parse_methoddecl(line,";\s*$")
- $stack[-1].methods[m.selector] = m
-
- Out.print "static " if m.static
- Out.print "#{m.rettype} #{m.selector}(int argc, Ruby *argv"
- Out.print "," if m.arglist.length>0
- Out.print "#{unparse_arglist m.arglist});"
- Out.puts "static Ruby #{m.selector}_wrap"+
- "(int argc, Ruby *argv, Ruby rself);//FCS"
-# Out.puts "# #{$linenumber}"
-end
-
-def handle_def(line)
- m = parse_methoddecl(line,"\\{?.*$")
- term = line[/\{.*/]
- qlass = $stack[-1]
- raise "missing \\class #{where}" if not qlass or not ClassDecl===qlass
- classname = qlass.name
- if qlass.methods[m.selector]
- n = m; m = qlass.methods[m.selector]
- if m!=n then
- STDERR.puts "warning: def does not match decl:"
- STDERR.puts "#{m.where}: \\decl #{m.inspect}"
- STDERR.puts "#{n.where}: \\def #{n.inspect}"
- end
- else
- qlass.methods[m.selector] = m
- end
-
- Out.print "Ruby #{classname}::#{m.selector}_wrap"+
- "(int argc, Ruby *argv, Ruby rself) {"+
- "static const char *methodspec = "+
- "\"#{qlass.name}::#{m.selector}(#{unparse_arglist m.arglist,false})\";"+
- "DGS(#{classname});"
-
- Out.print "if (argc<#{m.minargs}"
- Out.print "||argc>#{m.maxargs}" if m.maxargs!=-1
- Out.print ") RAISE(\"got %d args instead of %d..%d in %s\""+
- ",argc,#{m.minargs},#{m.maxargs},methodspec);"
-
- error = proc {|x,y|
- "RAISE(\"got %s instead of #{x} in %s\","+
- "rb_str_ptr(rb_inspect(rb_obj_class(#{y}))),methodspec)"
- }
-
- m.arglist.each_with_index{|arg,i|
- case arg.type
- when "Symbol"
- Out.print "if (argc>#{i} && TYPE(argv[#{i}])!=T_SYMBOL) "+
- error[arg.type,"argv[#{i}]"]+";"
- when "Array"
- Out.print "if (argc>#{i} && TYPE(argv[#{i}])!=T_ARRAY) "+
- error[arg.type,"argv[#{i}]"]+";"
- when "String"
- Out.print "if (argc>#{i} && TYPE(argv[#{i}])==T_SYMBOL) "+
- "argv[#{i}]=rb_funcall(argv[#{i}],SI(to_s),0);"
- Out.print "if (argc>#{i} && TYPE(argv[#{i}])!=T_STRING) "+
- error[arg.type,"argv[#{i}]"]+";"
- end
- }
-
-# Out.print "return " if m.rettype!="void"
- Out.print "VALUE foo = " if m.rettype!="void" ###
-
- Out.print " self->#{m.selector}(argc,argv"
- m.arglist.each_with_index{|arg,i|
- if arg.default then
- Out.print ",argc<#{i+1}?#{arg.default}:convert(argv[#{i}],(#{arg.type}*)0)"
- else
- Out.print ",convert(argv[#{i}],(#{arg.type}*)0)"
- end
- }
- Out.print ");"
- Out.print "self->check_magic();"
- Out.print "return Qnil;" if m.rettype=="void"
- Out.print "return foo;" if m.rettype!="void" ###
- Out.print "} #{m.rettype} #{classname}::#{m.selector}(int argc, Ruby *argv"
- Out.print "," if m.arglist.length>0
- Out.puts "#{unparse_arglist m.arglist, false})#{term}//FCS"
-end
-
-def handle_classinfo(line)
- frame = $stack[-1]
- cl = frame.name
- line="{}" if /^\s*$/ =~ line
- Out.puts "static void #{cl}_startup (Ruby rself);"
- Out.puts "static void *#{cl}_allocator () {return new #{cl};}"
- Out.puts "static MethodDecl #{cl}_methods[] = {"
- Out.puts frame.methods.map {|foo,method|
- c,s = frame.name,method.selector
- "{ \"#{s}\",(RMethod)#{c}::#{s}_wrap }"
- }.join(",")
- Out.puts "}; static FClass ci#{cl} = { #{cl}_allocator, #{cl}_startup,"
- Out.puts "#{cl.inspect}, COUNT(#{cl}_methods), #{cl}_methods };"
- Out.puts "void #{frame.name}_startup (Ruby rself) "+line
-end
-
-def handle_grin(line)
- fields = line.split(/\s+/)
- i = fields[0].to_i
- c = $stack[-1].name
- Out.print "template <class T> void grin_#{i}(GridInlet *in, int n, Pt<T> data);"
- Out.print "template <class T> static void grinw_#{i} (GridInlet *in, int n, Pt<T> data);"
- Out.print "static GridHandler grid_#{i}_hand;"
- handle_decl "Ruby _#{i}_grid(...);"
- $stack[-1].grins[i] = fields.dup
-end
-
-def handle_end(line)
- frame = $stack.pop
- fields = line.split(/\s+/)
- n = fields.length
- if ClassDecl===frame then
- #handle_classinfo if not frame.info
- cl = frame.name
- if fields[0]!="class" or
- (n>1 and fields[1]!=cl)
- then raise "end not matching #{where}" end
- $stack.push frame
- frame.attrs.each {|name,attr|
- type,name,default = attr.to_a
- #STDERR.puts "type=#{type} name=#{name} default=#{default}"
- handle_def "void _0_#{name}_m (#{type} #{name}) { this->#{name}=#{name}; }"
- }
- frame.grins.each {|i,v|
- k = case v[1]
- when nil; '4'
- when 'int32'; '1'
- when 'int'; '2'
- when 'float'; 'F'
- else raise 'BORK BORK BORK' end
- Out.print "static GridHandler #{cl}_grid_#{i}_hand = GRIN#{k}(#{cl},#{i});"
- handle_def "Ruby _#{i}_grid(...) {"+
- "if (in.size()<=#{i}) in.resize(#{i}+1);"+
- "if (!in[#{i}]) in[#{i}]=new GridInlet((GridObject *)this,&#{cl}_grid_#{i}_hand);"+
- "return in[#{i}]->begin(argc,argv);}"
-
- }
- $stack.pop
- Out.puts "# #{$linenumber}"
- end
- if :ruby==frame then
- if fields[0]!="ruby" then raise "expected \\end ruby" end
- end
- Out.puts ""
-end
-
-def handle_startall(line)
- $classes.each {|q|
- Out.print "rb_funcall(EVAL(\"GridFlow\"),SI(fclass_install),2,PTR2FIX(&ci#{q.name}),"
- if q.supername then
- Out.print "EVAL(\"GridFlow::#{q.supername}\"));"
- else
- Out.print "Qnil);"
- end
- }
- Out.puts ""
-end
-
-def handle_ruby(line)
- Out.puts ""
- $stack.push :ruby
-end
-
-$rubymode=false
-$linenumber=1
-loop{
- x = In.gets
- break if not x
- if /^\s*\\(\w+)\s*(.*)$/.match x then
- begin
- send("handle_#{$1}",$2)
- rescue StandardError => e
- STDERR.puts e.inspect
- STDERR.puts "at line #{$linenumber}"
- STDERR.puts e.backtrace
- File.unlink ARGV[1]
- exit 1
- end
- else
- if $stack[-1]==:ruby then
- x.gsub!(/([\\\"])/) { "\\"+$1 }
- x="\"#{x.chomp}\\n\"\n"
- end
- Out.puts x
- end
- $linenumber+=1
-}
diff --git a/externals/gridflow/base/test.rb b/externals/gridflow/base/test.rb
deleted file mode 100644
index 86c17af3..00000000
--- a/externals/gridflow/base/test.rb
+++ /dev/null
@@ -1,1074 +0,0 @@
-# $Id: test.rb,v 1.2 2006-03-15 04:37:28 matju Exp $
-
-$:.delete_if {|x| x=='.' }
-require "gridflow"
-
-include GridFlow
-GridFlow.verbose=true
-
-$imdir = "./images"
-$animdir = "./images/movies"
-srand Time.new.to_i
-$port = 4200+rand(100)
-
-def pressakey; puts "press return to continue."; readline; end
-
-FO = FObject # shortcut
-
-class Expect < FO
- def praise(*a)
- #raise(*a)
- puts a
- end
- def expect(*v)
- @count=0
- @v=v
- @expecting=true
- yield
- @expecting=false
- praise "wrong number of messages (#{@count}), expecting #{@v.inspect}" if @count!=@v.length
- end
- def _0_list(*l)
- return if not @expecting
- praise "wrong number of messages (#{@count})" if @count==@v.length
- praise "got #{l.inspect} expecting #{@v.inspect}" if @v[@count]!=l
- @count+=1
- end
- def method_missing(s,*a)
- praise "stray message: #{s}: #{a.inspect}"
- end
- install "expect", 1, 0
-end
-
-def cast value, type
- case type
- when :b, :u8,:uint8; value & 0xff
- when :s,:i16,:int16; (value & 0x7fff) - (value & 0x8000)
- when :i,:i32,:int32; value
- when :l,:i64,:int64; value
- when :f,:f32,:float32; value.to_f
- when :d,:f64,:float64; value.to_f
- when :r,:ruby; value
- else raise "hell"
- end
-end
-
-def test_bitpacking
- #!@#$ WRITE ME
-end
-
-def test_numops
- #!@#$ WRITE ME
-end
-
-#def tnt() for nt in [:b,:s,:i,:l,:f,:d,:r] do yield end end
-def _(o,s,i,d) o.connect(s,i,d) end
-def chain(*a)
- (a.length-1).times {|i| a[i].connect 0,a[i+1],a }
- a[-1]
-end
-
-def test_math
-for nt in [:b,:s,:i,:l,:f,:d,:r] do
- hm = "#".intern
- #GridFlow.verbose = false
-
- (e=FO["#export_list"])
- (x=Expect.new)
- _ e,0,x,0
-
- x.expect([1,2,3,11,12,13,21,22,23]) {
- e.send_in 0, 3,3,nt,hm,1,2,3,11,12,13,21,22,23 }
-
- (a=FO["fork"])
- (b=FO["@ +"])
- _ a,0,b,0
- _ a,1,b,1
- _ b,0,e,0
- x.expect([4]) { a.send_in 0, 2 }
-
- x.expect([2,3,5,7]) { e.send_in 0,:list,nt,2,3,5,7 }
- a = FO["#fold + , seed {#{nt} # 0}"]
- _ a,0,e,0
- x.expect([cast(420000,nt)]) { a.send_in 0,"10000 #{nt} # 42" }
-
- a = FO["# + {#{nt} 0 10}"]
- _ a,0,e,0
- x.expect([1,12,4,18,16,42,64]) {
- a.send_in 0,:list,nt, 1,2,4,8,16,32,64 }
-
- a = FO["# + {#{nt} 2 3 5}"]
- b = FO["#fold + , seed {#{nt} # 0}"]
- _ a,0,b,0
- _ b,0,e,0
- x.expect([cast(45332,nt)]) { a.send_in 0, 1000,nt,hm,42 }
-
- a = FO["@ + {#{nt} # 42}"]
- _ a,0,e,0
- x.expect((43..169).to_a) {
- a.send_in 0,:list,nt, *(1..127).to_a }
-
- x.expect([3,5,9,15]) {
- a.send_in 1,:list,4,nt,hm, 2,3,5,7
- a.send_in 0,:list,4,nt,hm, 1,2,4,8 }
- x.expect([11,12,14,18]) {
- a.send_in 1, "list #{nt} # 10"
- a.send_in 0,:list,nt, 1,2,4,8 }
-
-if nt!=:b and nt!=:f and nt!=:d
- a=FO["# / {#{nt} # 3}" ]; _ a,0,e,0; x.expect([-2,-1,-1,-1,0,0,0,0,0,1,1,1,2]) { a.send_in(0,:list,nt, *(-6..6).to_a) }
- a=FO["# div {#{nt} # 3}"]; _ a,0,e,0; x.expect([-2,-2,-2,-1,-1,-1,0,0,0,1,1,1,2]) { a.send_in(0, :list, nt, *(-6..6).to_a) }
-end
-
- (a = FO["# ignore {#{nt} # 42}"]).connect 0,e,0
- x.expect((42..52).to_a) { a.send_in(0, :list, nt, *(42..52).to_a) }
-
- (a = FO["# put {#{nt} # 42}"]).connect 0,e,0
- x.expect([42]*13) { a.send_in(0, :list, nt, *(-6..6).to_a) }
-
-if nt!=:b
- (a = FO["# abs-"]).connect 0,e,0
- x.expect([2,3,5,7]) {
- a.send_in 0,:list,nt, -2,3,-5,7 }
-end
-
- (a = FO["#fold *, seed {#{nt} # 1}"]).connect 0,e,0
- x.expect([210]) { a.send_in 0,:list,nt, 2,3,5,7 }
- x.expect([128]) { a.send_in 0,:list,nt, 1,1,2,1,2,2,2,1,1,2,1,2,2 }
-
- (a = FO["#fold +, seed {#{nt} 0 0}"]).connect 0,e,0
- x.expect([18,23]) { a.send_in 0, 3,2,nt,hm,2,3,5,7,11,13 }
-
- (a = FO["#scan +, seed {#{nt} 0 0}"]).connect 0,e,0
- x.expect([2,3,7,10,18,23]) { a.send_in 0, 3,2,nt,hm,2,3,5,7,11,13 }
-
- (a = FO["#scan *, seed {#{nt} # 1}"]).connect 0,e,0
- x.expect([2,6,30,210]) { a.send_in 0,:list,nt, 2,3,5,7 }
- x.expect([1,1,2,2,4,8,16,16,16,32,32,64,128]) {
- a.send_in 0,:list,nt, 1,1,2,1,2,2,2,1,1,2,1,2,2 }
-
- (a = FO["#scan +, seed {#{nt} 0 0 0}"]).connect 0,e,0
- x.expect([1,2,3,5,7,9,12,15,18]) {
- a.send_in 0,:list,3,3,nt,hm,*(1..9).to_a }
-
- (a = FO["#scan +, seed {#{nt} # 0}"]).connect 0,e,0
- x.expect([1,3,6, 4,9,15, 7,15,24]) {
- a.send_in 0,:list,3,3,nt,hm,*(1..9).to_a }
-
- (a = FO["#outer +"]).connect 0,e,0
- x.expect([9,10,12,17,18,20,33,34,36]) {
- a.send_in 1,:list,nt, 1,2,4
- a.send_in 0,:list,nt, 8,16,32 }
-
- x.expect((0...100).to_a) {
- a.send_in 1,(0...10).to_a
- a.send_in 0,(0...10).map{|i| 10*i }}
-
-if nt!=:b and nt!=:f and nt!=:d
- (a = FO["#outer",:%,[nt,3,-3]]).connect 0,e,0
- x.expect([0,0,1,-2,2,-1,0,0,1,-2,2,-1,0,0]) {
- a.send_in 0,:list,nt, -30,-20,-10,0,+10,+20,+30 }
-
- (a = FO["#outer","swap%".intern,[nt,3,-3]]).connect 0,e,0
- x.expect([-27,-3,-17,-3,-7,-3,0,0,3,7,3,17,3,27]) {
- a.send_in 0,:list,nt, -30,-20,-10,0,+10,+20,+30 }
-end
-
- (a = FO["#import {3}"]).connect 0,e,0; x.expect([2,3,5]) { [2,3,5].each {|v| a.send_in 0,:list,nt,hm,v }}
- (a = FO["#import {3}"]).connect 0,e,0; x.expect([2,3,5]) { [2,3,5].each {|v| a.send_in 0,:list,nt,v }}
- (a = FO["#redim {5}"]).connect 0,e,0; x.expect([2,3,5,2,3]) { a.send_in 0,:list,2,3,5 }
- (a = FO["#redim {5}"]).connect 0,e,0; x.expect([0,0,0,0,0]) { a.send_in 0,:list }
- (a = FO["#redim {0}"]).connect 0,e,0; x.expect([]) { a.send_in 0,:list,42,37,69 }
-
- (a = FO["#inner {2 2 #{nt} # 2 3 5 7}, seed {#{nt} # 0}"]).connect 0,e,0
- (i0 = FO["@redim {2 2}"]).connect 0,a,0
- x.expect([12,17,48,68]) { i0.send_in 0,:list,nt, 1,2,4,8 }
-
- (a = FO["#outer * {3 2 #{nt} # 1 2 3}"]).connect 0,e,0
- b = FO["#dim"]
- c = FO["#export_list"]
- a.connect 0,b,0
- y = Expect.new
- b.connect 0,c,0
- c.connect 0,y,0
-
- y.expect([2,3,2]) {
- x.expect([1,2,3,1,2,3,10,20,30,10,20,30]) {
- a.send_in 0,:list,nt, 1, 10 }}
-
- #pr=GridPrint.new
- (b = FO["#redim {5 5}"]).connect 0,e,0
- (a = FO["#convolve, seed {#{nt} # 0}"]).connect 0,b,0
- (i0 = FO["#redim {5 5 1}"]).connect 0,a,0
- (i1 = FO["#redim {3 1}"]).connect 0,a,1
- i1.send_in 1, 3,3
- x.expect([5,6,5,4,4,4,6,7,6,4,3,3,6,7,5,4,2,3,6,6,5,4,3,4,5]) {
- a.send_in 1,:list,3,3,nt,hm, 1,1,1,1,1,1,1,1,1
- i0.send_in 0,:list,nt, 1,1,1,0,0,0 }
-
- (a = FO["#convolve, seed {#{nt} # 0}"]).connect 0,e,0
- x.expect([1,3,6,4,0]) {
- a.send_in 1, 1,2,nt,hm, 1,1
- a.send_in 0, 1,5,nt,hm, 0,1,2,4,0 }
-
- (a = FO["#import {4}"]).connect 0,e,0
- x.expect([2,3,5,7]) {
- [2,3,5,7].each {|v| a.send_in 0,v }}
- x.expect([1,2,3],[4,5,6],[7,8,9]) {
- a.send_in 1, :list, 3
- a.send_in 0, :list, *(1..9).to_a}
-
- for o in ["#store"]
- (a = FO[o]).connect 0,e,0
- a.send_in 1, 5, 4, nt, hm, 1,2,3,4,5
- x.expect([1,2,3,4,4,5,1,2,2,3,4,5]) {
- a.send_in 0, 3,1, hm, 0,2,4 }
- x.expect([1,2,3,4,5]*24) { a.send_in 0, 2,3,0,hm }
- x.expect([1,2,3,4,5]*4) { a.send_in 0, 0,hm }
- x.expect([1,2,3,4,5]*4) { a.send_in 0 }
- x.expect([1,2,3,4]) { a.send_in 0,[0] }
- a.send_in 1,:put_at,[0,0]
- a.send_in 1,2,2,nt,hm,6,7,8,9
- x.expect([6,7,3,4, 8,9,2,3, 4,5,1,2, 3,4,5,1, 2,3,4,5]) { a.send_in 0 }
- x.expect([6,7,3,4]) { a.send_in 0,[0] }
- x.expect([8,9,2,3]) { a.send_in 0,[1] }
- a.send_in 1,:put_at,[1,1]
- a.send_in 1,2,2,nt,hm,11,13,17,19
- x.expect([6,7,3,4, 8,11,13,3, 4,17,19,2, 3,4,5,1, 2,3,4,5]) { a.send_in 0 }
- end
-
- b = FO["#dim"]
- c = FO["#export_list"]
- a.connect 0,b,0
- y = Expect.new
- b.connect 0,c,0
- c.connect 0,y,0
-
-if nt!=:b and nt!=:f and nt!=:d and nt!=:l
- (a = FO["#for {#{nt} # 0} {#{nt} # 10} {#{nt} # 1}"]).connect 0,e,0
- a.connect 0,b,0
- y.expect([10]) {
- x.expect((0...10).to_a) {
- a.send_in 0 } }
-
- (a = FO["#for {#{nt} # 0} {#{nt} # -10} {#{nt} # 1}"]).connect 0,e,0
- a.connect 0,b,0
- y.expect([0]) { x.expect([]) { a.send_in 0 } }
-
- (a = FO["#for {#{nt} # 0} {#{nt} # -10} {#{nt} # -1}"]).connect 0,e,0
- a.connect 0,b,0
- y.expect([10]) { x.expect([0,-1,-2,-3,-4,-5,-6,-7,-8,-9]) { a.send_in 0 } }
-
- (a = FO["#for {#{nt} 0} {#{nt} 10} {#{nt} 1}"]).connect 0,e,0
- a.connect 0,b,0
- y.expect([10,1]) {
- x.expect((0...10).to_a) {
- a.send_in 0 } }
-
- (a = FO["#for {#{nt} 2 3} {#{nt} 5 7} {#{nt} 1 1}"]).connect 0,e,0
- a.connect 0,b,0
- y.expect([3,4,2]) {
- x.expect([2,3,2,4,2,5,2,6,3,3,3,4,3,5,3,6,4,3,4,4,4,5,4,6]) {
- a.send_in 0 } }
-end
-
- (a = FO["@complex_sq"]).connect 0,e,0
- x.expect([8,0]) { a.send_in 0, 2, 2 }
- x.expect([0,9]) { a.send_in 0, 0, 3 }
-
- (a = FO["#rotate 3000 {1 2 5}"]).connect 0,e,0
- a.send_in 0, "5 5 # 1000 0 0 0 0 0"
-
-#if nt==:f or nt==:d
-# (a = FO["@matrix_solve"]).connect 0,e,0
-# x.expect([1,0,0,0,1,0,0,0,1]) { a.send_in 0, 3, 3, nt, hm, 1,0,0,0,1,0,0,0,1 }
-#end
- GridFlow.gfpost "ending test for #{nt}"
-end # for nt
-
- (a = FO["#pack 2"]).connect 0,e,0
- x.expect([42,0]) { a.send_in 0,42 }
- x.expect([42,28]) { a.send_in 1,28 }
- x.expect([1313,28]) { a.send_in 0,1313 }
-
- (a = FO["#pack 3"]).connect 0,e,0
- x.expect([42,0,0]) { a.send_in 0,42 }
- x.expect([42,28,0]) { a.send_in 1,28 }
- x.expect([42,28,-1]) { a.send_in 2,-1 }
-
- (a = FO["#pack 4"]).connect 0,e,0
- x.expect([42,0,0,0]) { a.send_in 0,42 }
- x.expect([42,0,0,-42]) { a.send_in 3,-42 }
-
- (a = FO["#pack 5"]).connect 0,e,0
- x.expect([3.5,0,0,0]) { a.send_in 0,3.5 }
- x.expect([3.5,0,0,-3.5]) { a.send_in 3,-3.5 }
-
- e = FO["#export_list"]
- e.connect 0,x,0
-
- a = FO["#import per_message"]
- a.connect 0,e,0
- x.expect([1,2,3]) { a.send_in 0,1,2,3 }
- x.expect([102,111,111]) { a.send_in 0,:symbol,:foo }
- x.expect([ 70, 79, 79]) { a.send_in 0,:symbol,:FOO }
-
- a = FO["@join 1"]
- a.connect 0,e,0
- a.send_in 1,2,2,nt,hm,11,13,17,19
- x.expect([2,3,11,13,5,7,17,19]) { a.send_in 0,2,2,nt,hm,2,3,5,7 }
-
-if nt!=:d
- a.send_in 1, 5,1,nt,hm,42
- y.expect([5,4]) {
- x.expect([2,3,5,42,7,11,13,42,17,19,23,42,29,31,37,42,41,43,47,42]) {
- a.send_in 0, 5,3,nt,hm,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47 }}
-end
- a = FO["@join 0"]
- a.connect 0,e,0
- a.send_in 1,2,2,nt,hm,11,13,17,19
- x.expect([2,3,5,7,11,13,17,19]) { a.send_in 0,2,2,nt,hm,2,3,5,7 }
-
- a = FO["@join 0 {2 2 2 #{nt} # 1 2 3}"]
- a.connect 0,e,0
- a.connect 0,b,0
- y.expect([2,2,2]) { x.expect([1,2,3,1,2,3,1,2]) { a.send_in 0,0,2,2,nt,hm }}
-
- a = FO["#ravel"]
- b = FO["#dim"]
- be = FO["#export_list"]
- bx = Expect.new
- a.connect 0,e,0
- a.connect 0,b,0
- b.connect 0,be,0
- be.connect 0,bx,0
- bx.expect([9]) {
- x.expect([1,2,3,2,4,6,3,6,9]) {
- o = FO["#outer *"]
- o.connect 0,a,0
- o.send_in 1,1,2,3
- o.send_in 0,1,2,3
- }
- }
-
- a = FO["#grade"]
- a.connect 0,e,0
- x.expect([0,2,4,6,8,9,7,5,3,1]) { a.send_in 0, 0,9,1,8,2,7,3,6,4,5 }
- x.expect([0,9,1,8,2,7,3,6,4,5]) { a.send_in 0, 0,2,4,6,8,9,7,5,3,1 }
- x.expect([7,6,5,4,3,2,1,0]) { a.send_in 0, 7,6,5,4,3,2,1,0 }
-
- a = FO["#grade"]
- b = FO["#fold +"]
- a.connect 0,b,0
- b.connect 0,e,0
- x.expect([100*99/2]) { a.send_in 0, (0...100).map { (rand*0x10000).to_i }}
- x.expect([100*99/2]) { a.send_in 0, (0...100).map { (rand*0x10).to_i }}
- x.expect([100*99/2]) { a.send_in 0, (0...100).map { 0 }}
-
- a = FO["#perspective"]
- a.connect 0,e,0
- c = []
- 8.times {|v|
- 3.times {|i|
- c << (v[i] * 1000 - 500) + (if i==2 then 2000 else 0 end)
- }
- }
- x.expect([
- -85,-85,85,-85,-85,85,85,85,
- -51,-51,51,-51,-51,51,51,51]) {
- a.send_in 0, 8,3,hm,*c }
-
-# regressiontests for past bugs
- a = FO["#inner"] # that's it.
-end
-
-def test_rtmetro
- rt = FO["rtmetro 1000"]
- pr = FO["rubyprint"]
- rt.connect 0,pr,0
- GridFlow.post "trying to start the rtmetro"
- rt.send_in 0,1
- $mainloop.timers.after(10.0) {
- GridFlow.post "trying to stop the rtmetro (after 10 sec delay)"
- rt.send_in 0,0
- }
- $mainloop.loop
-end
-
-def test_print
- i = FO["#redim {3}"]
- pr = FO["#print"]
-# pr = GridFlow::RubyPrint.new
- i.connect 0,pr,0
- i.send_in 0, 85, 170, 255
- i.send_in 1, 3, 3
- i.send_in 0, 1, 0, 0, 0
- i.send_in 1, 2, 2, 2
- i.send_in 0, 2, 3, 5, 7, 11, 13, 17, 19
-end
-
-class Barf < GridObject
- def _0_rgrid_begin
- raise "barf"
- end
- install_rgrid 0
- install "barf", 1, 0
-end
-
-def test_nonsense
-# (a = FO["@! abs"]).connect 0,e,0
-# x.expect_error {
-# a.send_in 1, 42,42 }
-
- a = FO["#import {3}"]
- b = Barf.new
- a.connect 0,b,0
- begin
- a.send_in 0, 1, 2, 3
- rescue StandardError
- nil
- else
- raise "Expected StandardError"
- end
- p b.inlet_dim(0)
-end
-
-def test_store
- a = FO["#in file #{$imdir}/teapot.png"]
- b = FO["#store"]
- c = FO["#out x11"]
- a.connect 0,b,1
- a.send_in 0,"cast uint8"
- a.send_in 0
- b.connect 0,c,0
- d = FO["#for {0 0} {256 256} {1 1}"]
- e = FO["# ^ 85"]
- d.connect 0,e,0
- e.connect 0,b,0
- f = FO["fps detailed"]
- c.connect 0,f,0
- pr = FO["rubyprint"]
- f.connect 0,pr,0
- GridFlow.verbose = false
- 256.times {|t|
- e.send_in 1,t
- d.send_in 0
- }
-end
-
-# generates recursive checkerboard pattern (munchies) in bluish colours.
-class Munchies < FPatcher
- @FOs = ["fork","fork","#for 0 64 1","#for 0 64 1","#for 2 5 1",
- "#outer ^","#outer *"]
- @wires = [-1,0,0,0, 0,0,1,0, 1,1,4,0, 4,0,6,1,
- 1,0,3,0, 3,0,5,1, 0,0,2,0, 2,0,5,0, 5,0,6,0, 6,0,-1,0 ]
- def initialize() super end
- install "munchies",1,1
-end
-
-def test_munchies
- m=Munchies.new
- gout = FO["#out window"]
- m.connect 0,gout,0
- m.send_in 0
- $mainloop.loop
-end
-
-def test_image command
- gin = FO["#in"]
- gout = FO["#out window"]
- gin.connect 0,gout,0
-# 31.times {
- 3.times {
- gin.send_in 0,"open #{command}"
- gout.send_in 0,"timelog 1"
- gin.send_in 0
- }
- FO["#global"].send_in 0, "profiler_dump"
- $mainloop.loop
-end
-
-def test_ppm2
- gin = FO["#in"]
- store = FO["#store"]
- pa = FO["#convolve << + 0"]
- pb = FO["# / 9"]
- ra = FO["#redim {3 3}"]
- gout = FO["#out window"]
- gin.connect 0,store,1
- store.connect 0,pa,0
- pa.connect 0,pb,0
- pb.connect 0,gout,0
- ra.connect 0,pa,1
- ra.send_in 0,"0 0"
- gout.send_in 0,"timelog 1"
- gin.send_in 0,"open file #{$imdir}/teapot.png"
-# gin.send_in 0,"open file #{$imdir}/g001.jpg"
- gin.send_in 0
-# 40.times { store.send_in 0 }
- loop { store.send_in 0 }
- v4j = FO["#global"]
- v4j.send_in 0,"profiler_dump"
-# $mainloop.loop
-end
-
-def test_foo
- foo = FO["#for {0 0} {64 64} {1 1}"]
- che = FO["#checkers"]
- sca = FO["#scale_by {5 3}"]
- out = FO["#out window"]
- foo.connect 0,che,0
- che.connect 0,sca,0
- sca.connect 0,out,0
- foo.send_in 0
- $mainloop.loop
-end
-
-def test_anim(*msgs)
- GridFlow.verbose = false
- gin = FO["#in"]
- gout1 = FO["#out window"]
- #gout1 = FO["@out quicktime file test.mov"]
- #gout1.send_in 0, :codec, :jpeg
- fps = FO["fps detailed"]
- rpr = FO["rubyprint"]
- gout1.connect 0,fps,0
- #fps.connect 0,rpr,0
-=begin
- gout1 = FO["#downscale_by {3 2}"]
- gout2 = FO["#rgb_to_greyscale"]
- gout3 = FO["#out aalib X11 -height 60 -width 132"]
- gout1.connect 0,gout2,0
- gout2.connect 0,gout3,0
-=end
-
- rpr = FO["rubyprint"]
-# gin.connect 1,rpr,0
-
- gin.connect 0,gout1,0
-=begin
- layer=FO["@layer"]
- gin.connect 0,layer,0
- layer.connect 0,gout1,0
- check=FO["@checkers"]
- phor=FO["@for {0 0} {256 256} {1 1}"]
- phor.connect 0,check,0
- check.connect 0,layer,1
- phor.send_in 0
-=end
-
-# scale = FO["@scale_by 3"]
-# gin.connect 0,scale,0
-# scale.connect 0,gout1,0
-
-# pr = FO["rubyprint time"]; gout.connect 0,pr,0
- msgs.each {|m| gin.send_in 0,m }
- gin.send_in 0, "cast uint8"
-# gout.send_in 0,"timelog 1"
- d=Time.new
- frames=2000
- frames.times {|n|
- #GridFlow.post "%d", n
- gin.send_in 0
- #gin.send_in 0, rand(1000)
- }
-# loop { gin.send_in 0 }
-# metro = FO["rtmetro 80"]
-# metro.connect 0,gin,0
-# metro.send_in 0,1
-# $mainloop.loop
-
- d=Time.new-d
- printf "%d frames in %.6f seconds (avg %.6f ms, %.6f fps)\n",
- frames, d, 1000*d/frames, frames/d
-# global.send_in 0,"dfgdfgdkfjgl"
- gout1.send_in 0, :close
- global = FO["@global"]
- global.send_in 0,"profiler_dump"
-end
-
-class TestTCP < FO
- attr_accessor :idle
- def initialize
- @idle = true
- end
- def _0_bang
- # GridFlow.gfpost "tick"
- # avoid recursion
- $mainloop.timers.after(0) {
- ($in_client.send_in 0; @idle=false) if @idle
- }
- end
- install "tcptest",1,1
-end
-
-def test_tcp
- if fork
- # client (is receiving)
- GridFlow.post_header = "[client] "
- $in_client = in1 = FO["@in"]
- out = FO["@out x11"]
- in1.connect 0,out,0
- out.send_in 0,"timelog 1"
- out.send_in 0,"autodraw 2"
- GridFlow.post "test: waiting 1 second"
- sleep 1
- p "HI"
- #in1.send_in 0,"open grid tcp localhost #{$port}"
- in1.send_in 0,"open grid tcp 127.0.0.1 #{$port}"
- p "HI"
-
- test_tcp = TestTCP.new
-
- out.connect 0,test_tcp,0
- test_tcp.connect 0,in1,0
-
- GridFlow.post "entering mainloop..."
- $mainloop.loop
- else
- # server (is sending)
- GridFlow.post_header = "[server] "
- $in1_server = in1 = FO["@in"]
- $in2_server = in2 = FO["@in"]
- $out = out = FO["@out"]
- toggle = 0
- in1.connect 0,out,0
- in2.connect 0,out,0
- in1.send_in 0,"open #{$imdir}/r001.jpg"
- in2.send_in 0,"open #{$imdir}/b001.jpg"
- out.send_in 0,"open grid tcpserver #{$port}"
- out.send_in 0,"type uint8"
- test_tcp = GridFlow::FO.new
- def test_tcp._0_bang
- # GridFlow.post "tick"
- @toggle ||= 0
- # avoid recursion
- $mainloop.timers.after(0.01) {
- if $out.format.stream
- if @toggle==0; $in1_server else $in2_server end.send_in 0
- @toggle ^= 1
- end
- _0_bang
- }
- end
- out.connect 0,test_tcp,0
- test_tcp.send_in 0
- GridFlow.post "entering mainloop..."
- $mainloop.loop
- end
-end
-
-def test_layer
-
- gin = FO["@in png file ShaunaKennedy/atmosphere-bleu.png"]
-# gin1 = FO["@in file #{$imdir}/r001.jpg"]
-# gin = FO["@join 2 {240 320 1 # 128}"]
-# gin1.connect 0,gin,0
-
-# gfor = FO["@for {0 0} {120 160} {1 1}"]
-# gfor = FO["@for {0 0} {240 320} {1 1}"]
- gfor = FO["@for {0 0} {480 640} {1 1}"]
- gche = FO["@checkers"]
-
- gove = FO["@layer"]
-# gove = FO["@fold + {0 0 0 0}"]
-# gout = FO["@print"]
-# gove = FO["@inner2 * + 0 {3 4 # 1 0 0 0 0}"]
-# gout = FO["@out sdl"]
- gout = FO["@out x11"]
-
- gin.connect 0,gove,0
- gfor.connect 0,gche,0
- gche.connect 0,gove,1
- gove.connect 0,gout,0
-
- gfor.send_in 0
-
- fps = FO["fps detailed"]
- pr = FO["rubyprint"]
- gout.connect 0,fps,0
- fps.connect 0,pr,0
-
- loop{gin.send_in 0}
-# gin.send_in 0
-# gin1.send_in 0
- $mainloop.loop
-end
-
-Images = [
- "png file opensource.png",
- "#{$imdir}/ruby0216.jpg",
- "#{$imdir}/g001.jpg",
-# "#{$imdir}/teapot.tga",
- "grid gzfile #{$imdir}/foo.grid.gz",
- "grid gzfile #{$imdir}/foo2.grid.gz",
-# "videodev /dev/video0",
-]
-
-def test_formats_speed
- gin = FO["@in"]
- gout = FO["@out x11"]
- gin.connect 0,gout,0
- GridFlow.verbose=false
- t1=[]
- Images.each {|command|
- gin.send_in 0,"open #{command}"
- t0 = Time.new
- 10.times {gin.send_in 0}
- t1 << (Time.new - t0)
- sleep 1
- }
- p t1
-end
-
-def test_formats
- gin = FO["@in"]
- gout = FO["@out window"]
- gs = FO["@ + {int16 # 0}"]
- gin.connect 0,gs,0
- gs.connect 0,gout,0
-# GridFlow.verbose=false
- t1=[]
- Images.each {|command|
- GridFlow.post "SENDING open %s", command
- gin.send_in 0,"open #{command}"
- gin.send_in 0,"cast int16"
- # test for load, rewind, load
- 5.times {|x| gs.send_in 1, [:int16, '#'.intern, x*128]; gin.send_in 0}
- # test for filehandle leak
- #1000.times { gin.send_in 0,"open #{command}" }
- sleep 1
- }
- p t1
-end
-
-def test_rewind
- gin = FO["@in videodev /dev/video1 noinit"]
- gin.send_in 0, "transfer read"
- gout = FO["@out ppm file /tmp/foo.ppm"]
-# gout = FO["@out x11"]
- gin.connect 0,gout,0
- loop {
- gin.send_in 0
- gout.send_in 0, "rewind"
- }
-end
-
-def test_formats_write
- # read files, store and save them, reload, compare, expect identical
- a = FO["@in"]
- b = FO["@out"]; a.connect 0,b,0
- c = FO["@ -"]; a.connect 0,c,1
- d = FO["@in"]; d.connect 0,c,0
- e = FO["@fold +"]; c.connect 0,e,0
- f = FO["@fold +"]; e.connect 0,f,0
- g = FO["@fold +"]; f.connect 0,g,0
- h = FO["@ / 15000"]; g.connect 0,h,0
- i = FO["@export_list"]; h.connect 0,i,0
- x = Expect.new; i.connect 0,x,0
- [
- ["ppm file", "#{$imdir}/g001.jpg"],
- ["targa file", "#{$imdir}/teapot.tga"],
- ["targa file", "#{$imdir}/tux.tga"],
- ["jpeg file", "#{$imdir}/ruby0216.jpg"],
- ["grid gzfile", "#{$imdir}/foo.grid.gz", "endian little"],
- ["grid gzfile", "#{$imdir}/foo.grid.gz", "endian big"],
- ].each {|type,file,*rest|
- a.send_in 0, "open #{type} #{file}"
- b.send_in 0, "open #{type} /tmp/patate"
- rest.each {|r| b.send_in 0,r }
- a.send_in 0
- b.send_in 0, "close"
- raise "written file does not exist" if not File.exist? "/tmp/patate"
- d.send_in 0, "open #{type} /tmp/patate"
- x.expect([0]) { d.send_in 0 }
-# d.send_in 0
- }
-end
-
-def test_mpeg_write
- a = FO["@in ppm file /opt/mex/r.ppm.cat"]
- b = FO["@out x11"]
- a.connect 0,b,0
- loop{a.send_in 0}
-end
-
-def test_headerless
- gout = FO["@out"]
- gout.send_in 0, "open grid file #{$imdir}/hello.txt"
- gout.send_in 0, "headerless"
- gout.send_in 0, "type uint8"
- gout.send_in 0, "104 101 108 108 111 32 119 111 114 108 100 33 10"
- gout.send_in 0, "close"
- gin = FO["@in"]
- pr = FO["@print"]
- gin.connect 0,pr,0
- gin.send_in 0, "open grid file #{$imdir}/hello.txt"
- gin.send_in 0, "headerless 13"
- gin.send_in 0, "type uint8"
- gin.send_in 0
-end
-
-
-def test_sound
-# o2 = FO["@ * 359"] # @ 439.775 Hz
-# o1 = FO["@for 0 44100 1"] # 1 sec @ 1.225 Hz ?
- o1 = FO["@for 0 4500 1"]
- o2 = FO["@ * 1600"] # @ 439.775 Hz
- o3 = FO["@ sin* 255"]
- o4 = FO["@ gamma 400"]
- o5 = FO["@ << 7"]
- out = FO["@out"]
- o1.connect 0,o2,0
- o2.connect 0,o3,0
- o3.connect 0,o4,0
- o4.connect 0,o5,0
- o5.connect 0,out,0
-# out.send_in 0,"open raw file /dev/dsp"
- out.send_in 0,"open grid file /dev/dsp"
- out.send_in 0,"type int16"
- x=0
- loop {
- o4.send_in 1, x
- o1.send_in 0
- x+=10
- }
-end
-
-include Math
-def test_polygon
- o1 = FO["@for 0 5 1"]
- o2 = FO["@ * 14400"]
- o3 = FO["@outer + {0 9000}"]
- o4 = FO["@ +"]
- o5 = FO["@ cos* 112"]
- o6 = FO["@ + {120 160}"]
- poly = FO["@draw_polygon + {3 uint8 # 255}"]
-if false
- out1 = FO["@cast int32"]
- out2 = FO["@solarize"]
-# out1 = FO["@downscale_by 2 smoothly"]
- out3 = FO["@out x11"]
- out1.connect 0,out2,0
- out2.connect 0,out3,0
-else
- out1 = FO["@out x11"]
- fps = FO["fps detailed cpu"]
- out1.connect 0,fps,0
- pr = FO["rubyprint"]
- fps.connect 0,pr,0
-end
- store = FO["@store"]; store.send_in 1, "240 320 3 uint8 # 0"
-# store2 = FO["@store"]
- store.connect 0,poly,0
- poly.connect 0,store,1
-# store2.connect 0,store,1
- o1.connect 0,o2,0
- o2.connect 0,o3,0
- o3.connect 0,o4,0
- o4.connect 0,o5,0
- o5.connect 0,o6,0
- o6.connect 0,poly,2
-# cast = FO["@cast int32"]
-# poly.connect 0,cast,0
-# cast.connect 0,out1,0
- poly.connect 0,out1,0
- x=0
- GridFlow.verbose=false
- task=proc {
- o4.send_in 1, 5000*x
- o5.send_in 1, 200+200*sin(x)
- poly.send_in 1,:list,:uint8, *(0..2).map{|i| 4+4*cos(0.2*x+i*PI*2/3) }
- o1.send_in 0
- store.send_in 0
-# store2.send_in 0
- x+=1
- if x<1000 then $mainloop.timers.after(0.0) {task[]}
- else GridGlobal.new.send_in 0,"profiler_dump"; exit end
- }
- task[]
- $mainloop.loop
-end
-
-class FRoute2 < FO
- def initialize(selector)
- @selector = selector.to_s
- end
- def method_missing(sym,*a)
- sym=sym.to_s
- if sym =~ /^_0_(.*)/
- send_out((if $1==@selector then 0 else 1 end), $1.intern, *a)
- else super end
- end
- install "route2", 1, 2
-end
-
-def test_aalib
-# gin = FO["@in ppm file #{$imdir}/r001.jpg"]
- gin = FO["@in ppm file #{$animdir}/b.jpg.cat"]
- grey = FO["@rgb_to_greyscale"]
- cont = FO["@ << 1"]
- clip = FO["@ min 255"]
- gout = FO["@out aalib X11"]
- sto = FO["@store"]
- op = FO["aa_fill_with_text {localhost 4242}"]
- filt = FO["route2 grid"]
- gin.connect 0,grey,0
- grey.connect 0,cont,0
- cont.connect 0,clip,0
- clip.connect 0,gout,0
- gout.connect 0,filt,0
- filt.connect 0,sto,1
- sto.connect 0,op,0
- op.connect 0,gout,0
- gout.send_in 0, :autodraw, 0
- GridFlow.verbose = false
- task=proc{
- gin.send_in 0
- gout.send_in 0, :dump
- sto.send_in 0
- gout.send_in 0, :draw
- $mainloop.timers.after(0.1,&task)
- }
- task[]
- $mainloop.loop
-end
-
-def test_store2
- o = [
- FO["@for {0 0} {240 320} {1 1}"],
- FO["@ / 2"],
- FO["@ + 0"],
- FO["@ + 0"],
- FO["@store"],
- FO["@out x11"]]
- (0..4).each {|x| o[x].connect 0,o[x+1],0 }
- q = FO["@in ppm file images/r001.jpg"]
- q.connect 0,o[4],1
- q.send_in 0
- o[0].send_in 0
- $mainloop.loop
-end
-
-def test_remap
- rem = FO["@remap_image"]
- rot = FO["@rotate 4000"]
- rem.connect 1,rot,0
- rot.connect 0,rem,1
- gin = FO["@in ppm file #{$imdir}/teapot.png"]
- gout = FO["@out x11"]
- gin.connect 0,rem,0
- rem.connect 0,gout,0
- gin.send_in 0
- $mainloop.loop
-end
-
-def test_asm
- GridFlow.verbose=false
- a = FO["@in ppm file images/r001.jpg"]
- aa = FO["@cast uint8"]
- b = FO["@store"]
- d = FO["@store"]
- a.connect 0,aa,0
- aa.connect 0,b,1
- aa.connect 0,d,1
- a.send_in 0
- c = FO["@ + {uint8 # 0}"]
- t0 = Time.new; 1000.times {b.send_in 0}; t1 = Time.new-t0
- t1 *= 1
- b.connect 0,c,0
- stuff=proc{
- 3.times{
- t0 = Time.new; 1000.times {b.send_in 0}; t2 = Time.new-t0
- t2 *= 1
- GridFlow.post " %f %f %f", t1, t2, t2-t1
- }
- }
- puts "map:"
- stuff[]
- d.connect 0,c,1 # for zip
- d.send_in 0
- puts "zip:"
- stuff[]
-end
-
-def test_metro
- o1 = RtMetro.new(1000,:geiger)
- o2 = RubyPrint.new(:time)
- o1.connect 0,o2,0
- o1.send_in 0,1
- $mainloop.loop
-end
-
-def test_outer
- o = FO["@outer + {0}"]
- o.send_in 0, 25, 240, 320, 3, "#".intern, 42
- g = FO["@global"]
- g.send_in 0, :profiler_dump
-end
-
-def test_jmax_to_pd filename
- require "gridflow/extra/jmax_format.rb"
- require "gridflow/extra/puredata_format.rb"
- jfr = JMaxFileReader.new(File.open(filename),FO)
- FO.broken_ok = true
- my_patcher = jfr.parse
-# my_patcher.subobjects.each {|x,| x.trigger if LoadBang===x }
-# $mainloop.loop
-# $p=my_patcher; ARGV.clear; load "/home/matju/bin/iruby"
- filename = File.basename filename
- filename[File.extname(filename)]=".pd"
- filename[0,0]="pd_examples/"
- pfw = PureDataFileWriter.new(filename)
- pfw.write_patcher my_patcher
- pfw.close
-end
-
-def test_error
- x = FO["@store"]
- x.send_in 0
-end
-
-if ARGV[0] then
- name = ARGV.shift
- send "test_#{name}", *ARGV
-# ARGV.each {|a| send "test_#{a}" }
- exit 0
-end
-
-#test_polygon
-#test_math
-#test_munchies
-#test_image "grid file #{$imdir}/foo.grid"
-#test_image "grid gzfile #{$imdir}/foo.grid.gz"
-#test_print
-#test_nonsense
-#test_ppm2
-#test_anim "open file #{$imdir}/g001.jpg"#,"loop 0"
-#test_anim "open ppm file #{$animdir}/b.ppm.cat"
-#test_anim "open jpeg file #{$imdir}/rgb.jpeg.cat"
-#test_anim "open quicktime file BLAH"
-#test_anim "open quicktime file #{$imdir}/rgb_uncompressed.mov"
-#test_anim "open quicktime file #{$imdir}/test_mjpega.mov"
-#test_anim "open ppm gzfile motion_tracking.ppm.cat.gz"
-#test_anim "open videodev /dev/video","channel 1","size 480 640"
-#test_anim "open videodev /dev/video1 noinit","transfer read"
-#test_anim "open videodev /dev/video","channel 1","size 120 160"
-#test_anim "open mpeg file /home/matju/net/Animations/washington_zoom_in.mpeg"
-#test_anim "open quicktime file /home/matju/Shauna/part_1.mov"
-#test_anim "open quicktime file #{$imdir}/gt.mov"
-#test_anim "open quicktime file /home/matju/pics/domopers_hi.mov"
-#test_anim "open quicktime file /home/matju/net/c.mov"
-#test_formats
-#test_tcp
-#test_sound
-#test_metro
-#$mainloop.loop
-
-=begin
-a = FO["@print"]
-a.send_in 0, "3 3 #{nt} # 1 0 0 0"
-a.send_in 0, "3 3 3 #{nt} # 1 2 3 4"
-a.send_in 0, "base 16"
-a.send_in 0, "3 3 3 #{nt} # 255 0 0 0"
-=end