From 0727bfcaf2bd48bf501a7fa95515c400a1996902 Mon Sep 17 00:00:00 2001 From: Bryan Jurish Date: Thu, 2 Feb 2006 12:49:19 +0000 Subject: initial cvs import svn path=/trunk/externals/moocow/; revision=4536 --- gfsm/src/pd_alphabet.c | 494 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 494 insertions(+) create mode 100644 gfsm/src/pd_alphabet.c (limited to 'gfsm/src/pd_alphabet.c') diff --git a/gfsm/src/pd_alphabet.c b/gfsm/src/pd_alphabet.c new file mode 100644 index 0000000..480a74a --- /dev/null +++ b/gfsm/src/pd_alphabet.c @@ -0,0 +1,494 @@ +/*=============================================================================*\ + * File: pd_alphabet.c + * Author: Bryan Jurish + * Description: finite state automata for Pd: alphabet + * + * Copyright (c) 2004 Bryan Jurish. + * + * For information on usage and redistribution, and for a DISCLAIMER OF ALL + * WARRANTIES, see the file, "LICENSE.txt," in this distribution. + * + * 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 LICENSE 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. + *=============================================================================*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +/*===================================================================== + * DEBUG + *=====================================================================*/ +//#define ALPHABET_DEBUG + +/*===================================================================== + * Pd Constants + *=====================================================================*/ +static t_class *pd_gfsm_alphabet_pd_class; +static t_class *pd_gfsm_alphabet_obj_class; + +/*===================================================================== + * pd_gfsm_alphabet_pd: Methods + *=====================================================================*/ + +/*-------------------------------------------------------------------- + * pd_gfsm_alphabet_pd: new + */ +static void *pd_gfsm_alphabet_pd_new(t_symbol *name) +{ + t_pd_gfsm_alphabet_pd *x = (t_pd_gfsm_alphabet_pd *)pd_new(pd_gfsm_alphabet_pd_class); + +#ifdef ALPHABET_DEBUG + post("pd_gfsm_alphabet_pd_new() called ; name=%s ; x=%p", + (name ? name->s_name : "(null)"), + x); +#endif + + //-- defaults + x->x_refcnt = 0; + x->x_name = name; + x->x_alphabet = (gfsmAlphabet*)gfsm_pd_atom_alphabet_new(); + + //-- bindings + if (name != &s_) pd_bind((t_pd*)x, name); + + return (void *)x; +} + + +/*-------------------------------------------------------------------- + * pd_gfsm_alphabet_pd: free + */ +static void pd_gfsm_alphabet_pd_free(t_pd_gfsm_alphabet_pd *x) +{ +#ifdef ALPHABET_DEBUG + post("pd_gfsm_alphabet_pd_free() called ; x=%p", x); +#endif + + if (x->x_alphabet) gfsm_pd_atom_alphabet_free((gfsmPdAtomAlphabet*)(x->x_alphabet)); + + /* unbind the symbol of the name of hashtable in pd's global namespace */ + if (x->x_name != &s_) pd_unbind((t_pd*)x, x->x_name); +} + +/*-------------------------------------------------------------------- + * pd_gfsm_alphabet_pd: find + */ +t_pd_gfsm_alphabet_pd *pd_gfsm_alphabet_pd_find(t_symbol *name) +{ + if (name != &s_) + return (t_pd_gfsm_alphabet_pd*)pd_findbyclass(name,pd_gfsm_alphabet_pd_class); + return NULL; +} + +/*-------------------------------------------------------------------- + * pd_gfsm_alphabet_pd: get + */ +t_pd_gfsm_alphabet_pd *pd_gfsm_alphabet_pd_get(t_symbol *name) +{ + t_pd_gfsm_alphabet_pd *x = pd_gfsm_alphabet_pd_find(name); + if (!x) { + x = (t_pd_gfsm_alphabet_pd*)pd_gfsm_alphabet_pd_new(name); + x->x_refcnt = 0; + } + return x; +} + +/*-------------------------------------------------------------------- + * pd_gfsm_alphabet_pd: release + */ +void pd_gfsm_alphabet_pd_release(t_pd_gfsm_alphabet_pd *x) +{ + if (x) { + if (x->x_refcnt) --x->x_refcnt; + if (!x->x_refcnt) pd_gfsm_alphabet_pd_free(x); + } +} + +/*-------------------------------------------------------------------- + * pd_gfsm_alphabet_pd: setup + */ +void pd_gfsm_alphabet_pd_setup(void) +{ + //-- class + pd_gfsm_alphabet_pd_class = class_new(gensym("gfsm_alphabet_pd"), + (t_newmethod)pd_gfsm_alphabet_pd_new, + (t_method)pd_gfsm_alphabet_pd_free, + sizeof(t_pd_gfsm_alphabet_pd), + CLASS_PD, + A_DEFSYM, + A_NULL); +} + + +/*===================================================================== + * pd_gfsm_alphabet: Methods + *=====================================================================*/ + +/*-------------------------------------------------------------------- + * pd_gfsm_alphabet_obj: new + */ +static void *pd_gfsm_alphabet_obj_new(t_symbol *name) +{ + t_pd_gfsm_alphabet_obj *x = (t_pd_gfsm_alphabet_obj *)pd_new(pd_gfsm_alphabet_obj_class); + +#ifdef ALPHABET_DEBUG + post("pd_gfsm_alphabet_obj_new() called: name=%s ; x=%p", + (name ? name->s_name : "(null)"), + x); +#endif + + //-- defaults + x->x_alphabet_pd = NULL; + + //-- bindings + x->x_alphabet_pd = pd_gfsm_alphabet_pd_get(name); + x->x_alphabet_pd->x_refcnt++; + + //-- outlets + x->x_labout = outlet_new(&x->x_obj, &s_float); //-- label / "char" outlet + x->x_keyout = outlet_new(&x->x_obj, &s_anything); //-- atom outlet + + return (void *)x; +} + + +/*-------------------------------------------------------------------- + * pd_gfsm_alphabet_obj: free + */ +static void pd_gfsm_alphabet_obj_free(t_pd_gfsm_alphabet_obj *x) +{ +#ifdef ALPHABET_DEBUG + post("pd_gfsm_alphabet_obj_free() called: x=%p", x); +#endif + + pd_gfsm_alphabet_pd_release(x->x_alphabet_pd); + + //-- do we need to do this? + outlet_free(x->x_labout); + outlet_free(x->x_keyout); +} + +/*-------------------------------------------------------------------- + * pd_gfsm_alphabet_obj: set + */ +static void pd_gfsm_alphabet_obj_alphabet(t_pd_gfsm_alphabet_obj *x, t_symbol *name) +{ +#ifdef ALPHABET_DEBUG + post("pd_gfsm_alphabet_obj_alphabet() called ; oldname=%p=%s ; newname=%p=%s", + x->x_alphabet_pd->x_name, x->x_alphabet_pd->x_name->s_name, name, name->s_name); +#endif + if (name == x->x_alphabet_pd->x_name) return; + pd_gfsm_alphabet_pd_release(x->x_alphabet_pd); + + x->x_alphabet_pd = pd_gfsm_alphabet_pd_get(name); + ++x->x_alphabet_pd->x_refcnt; +} + +/*-------------------------------------------------------------------- + * pd_gfsm_alphabet_obj: load + */ +static void pd_gfsm_alphabet_obj_load(t_pd_gfsm_alphabet_obj *x, t_symbol *s) +{ + gfsmError *errp = NULL; + gfsm_alphabet_load_filename(x->x_alphabet_pd->x_alphabet, s->s_name, &errp); + if (errp != NULL) { + error("gfsm_alphabet: load %s: %s", s->s_name, errp->message); + g_error_free(errp); + } +} + +/*-------------------------------------------------------------------- + * pd_gfsm_alphabet_obj: print + */ +static void pd_gfsm_alphabet_obj_print(t_pd_gfsm_alphabet_obj *x) +{ + gfsmError *errp = NULL; + gfsmIOHandle *ioh = pd_gfsm_console_handle_new(); + gfsm_alphabet_save_handle(x->x_alphabet_pd->x_alphabet, ioh, &errp); + if (errp != NULL) { + error("gfsm_alphabet: print: %s", errp->message); + g_error_free(errp); + } + pd_gfsm_console_handle_free(ioh); +} + +/*-------------------------------------------------------------------- + * pd_gfsm_alphabet_obj: save + */ +static void pd_gfsm_alphabet_obj_save(t_pd_gfsm_alphabet_obj *x, t_symbol *s) +{ + gfsmError *errp = NULL; + gfsm_alphabet_save_filename(x->x_alphabet_pd->x_alphabet, s->s_name, &errp); + if (errp != NULL) { + error("gfsm_alphabet: save %s: %s", s->s_name, errp->message); + g_error_free(errp); + } +} + +/*-------------------------------------------------------------------- + * pd_gfsm_alphabet_obj: clear + */ +static void pd_gfsm_alphabet_obj_clear(t_pd_gfsm_alphabet_obj *x) +{ + gfsm_alphabet_clear(x->x_alphabet_pd->x_alphabet); +} + + +/*-------------------------------------------------------------------- + * pd_gfsm_alphabet_obj: outlet_pair + */ +static void pd_gfsm_alphabet_obj_outlet_pair(t_pd_gfsm_alphabet_obj *x, t_float lab, t_atom *a) +{ + if (a) { + switch (a->a_type) { + case A_SYMBOL: + outlet_symbol(x->x_keyout, a->a_w.w_symbol); + break; + case A_FLOAT: + outlet_float(x->x_keyout, a->a_w.w_float); + break; + default: + outlet_symbol(x->x_keyout, atom_getsymbol(a)); + break; + } + } else { + outlet_bang(x->x_keyout); + } + + if (lab != gfsmNoLabel) outlet_float(x->x_obj.ob_outlet, lab); + else outlet_bang(x->x_obj.ob_outlet); +} + +/*-------------------------------------------------------------------- + * pd_gfsm_alphabet_obj: insert + */ +static void pd_gfsm_alphabet_obj_insert(t_pd_gfsm_alphabet_obj *x, t_symbol *s, int argc, t_atom *argv) +{ + if (argc < 1) { + error("pd_gfsm_alphabet_obj_insert(): no atom to insert?"); + return; + } + t_float labf = argc > 1 ? atom_getfloat(argv+1) : (t_float)gfsmNoLabel; + + gfsm_alphabet_get_full(x->x_alphabet_pd->x_alphabet, argv, (gfsmLabelVal)labf); +} + +/*-------------------------------------------------------------------- + * pd_gfsm_alphabet_obj: atom2label + */ +static void pd_gfsm_alphabet_obj_atom2label(t_pd_gfsm_alphabet_obj *x, t_symbol *s, int argc, t_atom *argv) +{ + if (argc < 1) { + error("pd_gfsm_alphabet_obj_atom2label(): no arguments?"); + return; + } + t_float labf = (t_float)(gfsm_alphabet_find_label(x->x_alphabet_pd->x_alphabet, argv)); + + pd_gfsm_alphabet_obj_outlet_pair(x, labf, argv); +} + +/*-------------------------------------------------------------------- + * pd_gfsm_alphabet_obj: atom2label_force + */ +static void pd_gfsm_alphabet_obj_atom2label_force(t_pd_gfsm_alphabet_obj *x, t_symbol *s, int argc, t_atom *argv) +{ + if (argc < 1) { + error("pd_gfsm_alphabet_obj_atom2label_force(): no arguments?"); + return; + } + t_float labf = (t_float)(gfsm_alphabet_get_label(x->x_alphabet_pd->x_alphabet, argv)); + + pd_gfsm_alphabet_obj_outlet_pair(x, labf, argv); +} + +/*-------------------------------------------------------------------- + * pd_gfsm_alphabet_obj: label2atom + */ +static void pd_gfsm_alphabet_obj_label2atom(t_pd_gfsm_alphabet_obj *x, t_float labf) +{ + t_atom *key = (t_atom*)gfsm_alphabet_find_key(x->x_alphabet_pd->x_alphabet, (gfsmLabelVal)labf); + + if (key==NULL) pd_gfsm_alphabet_obj_outlet_pair(x, labf, NULL); + else pd_gfsm_alphabet_obj_outlet_pair(x, labf, key); +} + +/*-------------------------------------------------------------------- + * pd_gfsm_alphabet_obj: label2atom_force + */ +static void pd_gfsm_alphabet_obj_label2atom_force(t_pd_gfsm_alphabet_obj *x, t_float labf) +{ + t_atom *key = (t_atom*)gfsm_alphabet_find_key(x->x_alphabet_pd->x_alphabet, + (gfsmLabelVal)labf); + if (key==NULL) { + t_atom labatom; + SETFLOAT(&labatom, labf); + gfsm_alphabet_insert(x->x_alphabet_pd->x_alphabet, &labatom, (gfsmLabelVal)labf); + pd_gfsm_alphabet_obj_outlet_pair(x, labf, &labatom); + } + else { + pd_gfsm_alphabet_obj_outlet_pair(x, labf, key); + } +} + +/*-------------------------------------------------------------------- + * pd_gfsm_alphabet_obj: rmatom() + */ +static void pd_gfsm_alphabet_obj_rmatom(t_pd_gfsm_alphabet_obj *x, t_symbol *sel, int argc, t_atom *argv) +{ + if (argc < 1) return; + gfsm_alphabet_remove_key(x->x_alphabet_pd->x_alphabet, argv); +} + +/*-------------------------------------------------------------------- + * pd_gfsm_alphabet_obj: rmlabel() + */ +static void pd_gfsm_alphabet_obj_rmlabel(t_pd_gfsm_alphabet_obj *x, t_float labf) +{ + gfsm_alphabet_remove_label(x->x_alphabet_pd->x_alphabet, (gfsmLabelVal)labf); +} + + +/*-------------------------------------------------------------------- + * pd_gfsm_alphabet: setup + */ +void pd_gfsm_alphabet_setup(void) +{ + //-- pd_gfsm_alphabet_pd + pd_gfsm_alphabet_pd_setup(); + + //-- class + pd_gfsm_alphabet_obj_class = class_new(gensym("gfsm_alphabet"), + (t_newmethod)pd_gfsm_alphabet_obj_new, + (t_method)pd_gfsm_alphabet_obj_free, + sizeof(t_pd_gfsm_alphabet_obj), + CLASS_DEFAULT, + A_DEFSYM, + A_NULL); + + //-- methods: I/O + class_addmethod(pd_gfsm_alphabet_obj_class, + (t_method)pd_gfsm_alphabet_obj_print, + gensym("print"), + A_NULL); + class_addmethod(pd_gfsm_alphabet_obj_class, + (t_method)pd_gfsm_alphabet_obj_load, + gensym("load"), + A_SYMBOL, + A_NULL); + class_addmethod(pd_gfsm_alphabet_obj_class, + (t_method)pd_gfsm_alphabet_obj_save, + gensym("save"), + A_SYMBOL, + A_NULL); + + + //-- methods: whole-object manipulation + class_addmethod(pd_gfsm_alphabet_obj_class, + (t_method)pd_gfsm_alphabet_obj_clear, + gensym("clear"), + A_NULL); + class_addmethod(pd_gfsm_alphabet_obj_class, + (t_method)pd_gfsm_alphabet_obj_alphabet, + gensym("alphabet"), + A_DEFSYM, + A_NULL); + + + //-- methods: insert + class_addmethod(pd_gfsm_alphabet_obj_class, + (t_method)pd_gfsm_alphabet_obj_insert, + gensym("insert"), + A_GIMME, + A_NULL); + + //-- methods: safe access: atom->label + class_addmethod(pd_gfsm_alphabet_obj_class, + (t_method)pd_gfsm_alphabet_obj_atom2label, + gensym("atom2char"), + A_GIMME, + A_NULL); + /* + class_addmethod(pd_gfsm_alphabet_obj_class, + (t_method)pd_gfsm_alphabet_obj_atom2label, + gensym("a2c"), + A_GIMME, + A_NULL); + */ + + //-- methods: destructive access: atom->label + class_addmethod(pd_gfsm_alphabet_obj_class, + (t_method)pd_gfsm_alphabet_obj_atom2label_force, + gensym("atom2char!"), + A_GIMME, + A_NULL); + /* + class_addmethod(pd_gfsm_alphabet_obj_class, + (t_method)pd_gfsm_alphabet_obj_atom2label_force, + gensym("a2c!"), + A_GIMME, + A_NULL); + */ + + + //-- methods: safe access: label->atom + class_addmethod(pd_gfsm_alphabet_obj_class, + (t_method)pd_gfsm_alphabet_obj_label2atom, + gensym("char2atom"), + A_FLOAT, + A_NULL); + /* + class_addmethod(pd_gfsm_alphabet_obj_class, + (t_method)pd_gfsm_alphabet_obj_label2atom, + gensym("c2a"), + A_FLOAT, + A_NULL); + */ + + //-- methods: destructive access: label->atom + class_addmethod(pd_gfsm_alphabet_obj_class, + (t_method)pd_gfsm_alphabet_obj_label2atom_force, + gensym("char2atom!"), + A_FLOAT, + A_NULL); + /* + class_addmethod(pd_gfsm_alphabet_obj_class, + (t_method)pd_gfsm_alphabet_obj_label2atom_force, + gensym("c2a!"), + A_FLOAT, + A_NULL); + */ + + //-- methods: removal + class_addmethod(pd_gfsm_alphabet_obj_class, + (t_method)pd_gfsm_alphabet_obj_rmatom, + gensym("rmatom"), + A_GIMME, + A_NULL); + class_addmethod(pd_gfsm_alphabet_obj_class, + (t_method)pd_gfsm_alphabet_obj_rmlabel, + gensym("rmchar"), + A_FLOAT, + A_NULL); + + + //-- help symbol + class_sethelpsymbol(pd_gfsm_alphabet_obj_class, gensym("gfsm_alphabet-help.pd")); +} -- cgit v1.2.1