[PD-cvs] externals/miXed/cyclone/hammer Table.c,NONE,1.1

Krzysztof Czaja krzyszcz at users.sourceforge.net
Sat Apr 17 19:47:46 CEST 2004


Update of /cvsroot/pure-data/externals/miXed/cyclone/hammer
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14763/cyclone/hammer

Added Files:
	Table.c 
Log Message:


--- NEW FILE: Table.c ---
/* Copyright (c) 2004 krzYszcz and others.
 * For information on usage and redistribution, and for a DISCLAIMER OF ALL
 * WARRANTIES, see the file, "LICENSE.txt," in this distribution.  */

#include <stdio.h>
#include <string.h>
#include "m_pd.h"
#include "g_canvas.h"
#include "common/loud.h"
#include "common/grow.h"
#include "hammer/file.h"

#define TABLE_DEBUG

#define TABLE_INISIZE      256  /* LATER rethink */
#define TABLE_DEFLENGTH    128
#define TABLE_MINLENGTH      2
#define TABLE_MAXLENGTH  16383

typedef struct _tablecommon
{
    t_pd            c_pd;
    struct _table  *c_refs;  /* used in read-banging and dirty flag handling */
    int             c_embedflag;  /* common field (CHECKED in 'TEXT') */
    int             c_loading;
    int             c_relinked;
    int             c_size;    /* as allocated */
    int             c_length;  /* as used */
    int            *c_table;
    int             c_tableini[TABLE_INISIZE];
    t_symbol       *c_filename;
    t_canvas       *c_lastcanvas;
    t_hammerfile   *c_filehandle;
} t_tablecommon;

typedef struct _table
{
    t_object        x_ob;
    t_canvas       *x_canvas;
    t_symbol       *x_name;
    t_tablecommon  *x_common;
    t_float         x_value;
    int             x_valueset;
    int             x_head;
    t_hammerfile   *x_filehandle;
    t_outlet       *x_bangout;
    struct _table  *x_next;
} t_table;

static t_class *table_class;
static t_class *tablecommon_class;

static void tablecommon_modified(t_tablecommon *cc, int relinked)
{
    if (cc->c_loading)
	return;
    if (relinked)
    {
	cc->c_relinked = 1;
    }
    if (cc->c_embedflag)
    {
	t_table *x;
	for (x = cc->c_refs; x; x = x->x_next)
	    if (x->x_canvas && glist_isvisible(x->x_canvas))
		canvas_dirty(x->x_canvas, 1);
    }
}

static void tablecommon_doread(t_tablecommon *cc, t_symbol *fn, t_canvas *cv)
{
    /* FIXME */
}

static void tablecommon_readhook(t_pd *z, t_symbol *fn, int ac, t_atom *av)
{
    tablecommon_doread((t_tablecommon *)z, fn, 0);
}

static void tablecommon_dowrite(t_tablecommon *cc, t_symbol *fn, t_canvas *cv)
{
    /* FIXME */
}

static void tablecommon_writehook(t_pd *z, t_symbol *fn, int ac, t_atom *av)
{
    tablecommon_dowrite((t_tablecommon *)z, fn, 0);
}

static void table_embedhook(t_pd *z, t_binbuf *bb, t_symbol *bindsym)
{
    /* FIXME */
}

static void tablecommon_editorhook(t_pd *z, t_symbol *s, int ac, t_atom *av)
{
    /* FIXME */
}

static t_tablecommon *table_checkcommon(t_table *x)
{
    if (x->x_name &&
	x->x_common != (t_tablecommon *)pd_findbyclass(x->x_name,
						       tablecommon_class))
    {
	bug("table_checkcommon");
	return (0);
    }
    return (x->x_common);
}

static void table_unbind(t_table *x)
{
    /* LATER consider calling table_checkcommon(x) */
    t_tablecommon *cc = x->x_common;
    t_table *prev, *next;
    if ((prev = cc->c_refs) == x)
    {
	if (!(cc->c_refs = x->x_next))
	{
	    hammerfile_free(cc->c_filehandle);
	    cc->c_loading = 1;  /* disable dirty-flag handling, LATER rethink */
	    if (cc->c_table != cc->c_tableini)
		freebytes(cc->c_table, cc->c_size * sizeof(*cc->c_table));
	    if (x->x_name) pd_unbind(&cc->c_pd, x->x_name);
	    pd_free(&cc->c_pd);
	}
    }
    else if (prev)
    {
	while (next = prev->x_next)
	{
	    if (next == x)
	    {
		prev->x_next = next->x_next;
		break;
	    }
	    prev = next;
	}
    }
    x->x_common = 0;
    x->x_name = 0;
    x->x_next = 0;
}

static void table_bind(t_table *x, t_symbol *name)
{
    t_tablecommon *cc = 0;
    if (name == &s_)
	name = 0;
    else if (name)
	cc = (t_tablecommon *)pd_findbyclass(name, tablecommon_class);
    if (!cc)
    {
	cc = (t_tablecommon *)pd_new(tablecommon_class);
	cc->c_refs = 0;
	cc->c_embedflag = 0;
	cc->c_loading = 0;
	cc->c_size = TABLE_INISIZE;
	cc->c_length = TABLE_DEFLENGTH;
	cc->c_table = cc->c_tableini;
	if (name)
	{
	    pd_bind(&cc->c_pd, name);
	    /* LATER rethink canvas unpredictability */
	    tablecommon_doread(cc, name, x->x_canvas);
	}
	else
	{
	    cc->c_filename = 0;
	    cc->c_lastcanvas = 0;
	}
	cc->c_filehandle = hammerfile_new((t_pd *)cc, 0, tablecommon_readhook,
					  tablecommon_writehook,
					  tablecommon_editorhook);
    }
    x->x_common = cc;
    x->x_name = name;
    x->x_next = cc->c_refs;
    cc->c_refs = x;
}

static int table_rebind(t_table *x, t_symbol *name)
{
    t_tablecommon *cc;
    if (name && name != &s_ &&
	(cc = (t_tablecommon *)pd_findbyclass(name, tablecommon_class)))
    {
	table_unbind(x);
	x->x_common = cc;
	x->x_name = name;
	x->x_next = cc->c_refs;
	cc->c_refs = x;
	return (1);
    }
    else return (0);
}

static void table_dooutput(t_table *x, int ndx)
{
    t_tablecommon *cc = x->x_common;
    /* CHECKED ndx silently truncated */
    if (ndx < 0)
	ndx = 0;
    else if (ndx > cc->c_length)
	ndx = cc->c_length - 1;
    outlet_float(((t_object *)x)->ob_outlet, (t_float)cc->c_table[ndx]);
}

static void table_setvalue(t_table *x, int ndx, int v)
{
    t_tablecommon *cc = x->x_common;
    /* CHECKED ndx silently truncated */
    if (ndx < 0)
	ndx = 0;
    else if (ndx > cc->c_length)
	ndx = cc->c_length - 1;
    cc->c_table[ndx] = v;  /* CHECKED no truncation */
}

static void table_bang(t_table *x)
{
    /* FIXME */
}

static void table_float(t_table *x, t_float f)
{
    int ndx = (int)f;  /* CHECKED floats are truncated */
    if (x->x_valueset)
    {
	table_setvalue(x, ndx, x->x_value);
	x->x_valueset = 0;
    }
    else table_dooutput(x, ndx);
    /* CHECKME if head is updated */
    x->x_head = ndx;
}

static void table_ft1(t_table *x, t_floatarg f)
{
    x->x_value = (int)f;  /* CHECKED floats are truncated */
    x->x_valueset = 1;
}

static void table_cancel(t_table *x)
{
    x->x_valueset = 0;
}

static void table_clear(t_table *x)
{
    t_tablecommon *cc = x->x_common;
    int ndx = cc->c_length;
    int *ptr = cc->c_table;
    while (ndx--) *ptr++ = 0;
    /* CHECKME head */
}

static void table_next(t_table *x)
{
    table_dooutput(x, x->x_head++);
    if (x->x_head >= x->x_common->c_length)
	x->x_head = 0;
}

static void table_prev(t_table *x)
{
    table_dooutput(x, x->x_head--);
    if (x->x_head < 0)
	x->x_head = x->x_common->c_length - 1;
}

static void table_goto(t_table *x, t_floatarg f)
{
    t_tablecommon *cc = x->x_common;
    int ndx = (int)f;  /* CHECKED floats are truncated */
    /* CHECKED ndx silently truncated */
    if (ndx < 0)
	ndx = 0;
    else if (ndx > cc->c_length)
	ndx = cc->c_length - 1;
    x->x_head = ndx;
}

static void table_length(t_table *x)
{
    outlet_float(((t_object *)x)->ob_outlet, (t_float)x->x_common->c_length);
}

static void table_min(t_table *x)
{
    /* FIXME */
}

static void table_max(t_table *x)
{
    /* FIXME */
}

static void table_refer(t_table *x, t_symbol *s)
{
    if (!table_rebind(x, s))
    {
	/* LATER consider complaining */
    }
}

static void table_flags(t_table *x, t_float f1, t_float f2)
{
    int i1;
    if (loud_checkint((t_pd *)x, f1, &i1, gensym("flags")))
    {
	t_tablecommon *cc = x->x_common;
	cc->c_embedflag = (i1 != 0);
    }
    /* FIXME don't save flag */
}

static void table_read(t_table *x, t_symbol *s)
{
    t_tablecommon *cc = x->x_common;
    if (s && s != &s_)
	tablecommon_doread(cc, s, x->x_canvas);
    else
	hammerpanel_open(cc->c_filehandle, 0);
}

static void table_write(t_table *x, t_symbol *s)
{
    t_tablecommon *cc = x->x_common;
    if (s && s != &s_)
	tablecommon_dowrite(cc, s, x->x_canvas);
    else
	hammerpanel_save(cc->c_filehandle, 0, 0);  /* CHECKME default name */
}

static void table_dump(t_table *x)
{
    t_tablecommon *cc = x->x_common;
    /* FIXME */
}

static void table_open(t_table *x)
{
    t_tablecommon *cc = x->x_common;
    /* FIXME */
}

static void table_wclose(t_table *x)
{
    /* FIXME */
}

static void table_click(t_table *x, t_floatarg xpos, t_floatarg ypos,
			t_floatarg shift, t_floatarg ctrl, t_floatarg alt)
{
    table_open(x);
}

#ifdef TABLE_DEBUG
static void table_debug(t_table *x, t_floatarg f)
{
    t_tablecommon *cc = table_checkcommon(x);
    if (cc)
    {
	t_table *x1 = cc->c_refs;
	int i = 0;
	while (x1) i++, x1 = x1->x_next;
	post("refcount %d", i);
    }
}
#endif

static void table_free(t_table *x)
{
    hammerfile_free(x->x_filehandle);
    table_unbind(x);
}

static void *table_new(t_symbol *s)
{
    t_table *x = (t_table *)pd_new(table_class);
    static int warned = 0;
    if (!warned)
    {
	loud_warning((t_pd *)x, 0, "Table is not ready yet");
	warned = 1;
    }
    x->x_canvas = canvas_getcurrent();
    x->x_valueset = 0;
    x->x_head = 0;
    inlet_new((t_object *)x, (t_pd *)x, &s_float, gensym("ft1"));
    outlet_new((t_object *)x, &s_float);
    x->x_bangout = outlet_new((t_object *)x, &s_bang);
    x->x_filehandle = hammerfile_new((t_pd *)x, table_embedhook, 0, 0, 0);
    table_bind(x, s);
    return (x);
}

void Table_setup(void)
{
    table_class = class_new(gensym("Table"),
			    (t_newmethod)table_new,
			    (t_method)table_free,
			    sizeof(t_table), 0, A_DEFSYM, 0);
    class_addbang(table_class, table_bang);
    class_addfloat(table_class, table_float);
    class_addmethod(table_class, (t_method)table_ft1,
		    gensym("ft1"), A_FLOAT, 0);
    class_addmethod(table_class, (t_method)table_cancel,
		    gensym("cancel"), 0);
    class_addmethod(table_class, (t_method)table_clear,
		    gensym("clear"), 0);
    class_addmethod(table_class, (t_method)table_next,
		    gensym("next"), 0);
    class_addmethod(table_class, (t_method)table_prev,
		    gensym("prev"), 0);
    class_addmethod(table_class, (t_method)table_goto,
		    gensym("goto"), A_FLOAT, 0);
    class_addmethod(table_class, (t_method)table_length,
		    gensym("length"), 0);
    class_addmethod(table_class, (t_method)table_min,
		    gensym("min"), 0);
    class_addmethod(table_class, (t_method)table_max,
		    gensym("max"), 0);
    class_addmethod(table_class, (t_method)table_refer,
		    gensym("refer"), A_SYMBOL, 0);
    class_addmethod(table_class, (t_method)table_flags,
		    gensym("flags"), A_FLOAT, A_FLOAT, 0);
    class_addmethod(table_class, (t_method)table_read,
		    gensym("read"), A_DEFSYM, 0);
    class_addmethod(table_class, (t_method)table_write,
		    gensym("write"), A_DEFSYM, 0);
    class_addmethod(table_class, (t_method)table_dump,
		    gensym("dump"), 0);
    class_addmethod(table_class, (t_method)table_open,
		    gensym("open"), 0);
    class_addmethod(table_class, (t_method)table_wclose,
		    gensym("wclose"), 0);
    class_addmethod(table_class, (t_method)table_click,
		    gensym("click"),
		    A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
#ifdef TABLE_DEBUG
    class_addmethod(table_class, (t_method)table_debug,
		    gensym("debug"), A_DEFFLOAT, 0);
#endif
    hammerfile_setup(table_class, 1);
    tablecommon_class = class_new(gensym("Table"), 0, 0,
				 sizeof(t_tablecommon), CLASS_PD, 0);
    /* this call is a nop (tablecommon does not embed, and the hammerfile
       class itself has been already set up above), but it is better to
       have it around, just in case... */
    hammerfile_setup(tablecommon_class, 0);
}





More information about the Pd-cvs mailing list