Update of /cvsroot/pure-data/externals/miXed/shared/hammer In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10934/shared/hammer
Modified Files: gui.c gui.h tree.c tree.h Log Message: various bug-fixes, maxmode, toxy .#args
Index: gui.c =================================================================== RCS file: /cvsroot/pure-data/externals/miXed/shared/hammer/gui.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** gui.c 31 Mar 2004 10:24:17 -0000 1.3 --- gui.c 8 Dec 2004 15:40:13 -0000 1.4 *************** *** 6,9 **** --- 6,10 ----
#include <stdio.h> + #include <string.h> #include "m_pd.h" #include "g_canvas.h" *************** *** 13,17 ****
static t_class *hammergui_class = 0; ! static t_hammergui *sink = 0; static t_symbol *ps__up; static t_symbol *ps__focus; --- 14,20 ----
static t_class *hammergui_class = 0; ! static t_hammergui *hammergui_sink = 0; ! static t_symbol *ps_hashhammergui; ! static t_symbol *ps__hammergui; static t_symbol *ps__up; static t_symbol *ps__focus; *************** *** 27,31 **** startpost("%s", s->s_name); postatom(ac, av); ! endpost(); #endif } --- 30,34 ---- startpost("%s", s->s_name); postatom(ac, av); ! post(" (sink %x)", (int)snk); #endif } *************** *** 35,50 **** { #ifdef HAMMERGUI_DEBUG ! post("_up %g", f); #endif if ((int)f) { ! if (!snk->g_up) { ! snk->g_up = 1; ! if (snk->g_mouse->s_thing) { t_atom at; SETFLOAT(&at, 1); ! pd_typedmess(snk->g_mouse->s_thing, ps__up, 1, &at); } } --- 38,58 ---- { #ifdef HAMMERGUI_DEBUG ! post("_up %g (sink %x)", f, (int)snk); #endif + if (!snk->g_psmouse) + { + bug("hammergui__up"); + return; + } if ((int)f) { ! if (!snk->g_isup) { ! snk->g_isup = 1; ! if (snk->g_psmouse->s_thing) { t_atom at; SETFLOAT(&at, 1); ! pd_typedmess(snk->g_psmouse->s_thing, ps__up, 1, &at); } } *************** *** 52,63 **** else { ! if (snk->g_up) { ! snk->g_up = 0; ! if (snk->g_mouse->s_thing) { t_atom at; SETFLOAT(&at, 0); ! pd_typedmess(snk->g_mouse->s_thing, ps__up, 1, &at); } } --- 60,71 ---- else { ! if (snk->g_isup) { ! snk->g_isup = 0; ! if (snk->g_psmouse->s_thing) { t_atom at; SETFLOAT(&at, 0); ! pd_typedmess(snk->g_psmouse->s_thing, ps__up, 1, &at); } } *************** *** 68,79 **** { #ifdef HAMMERGUI_DEBUG ! if (s) post("_focus %s %g", s->s_name, f); #endif ! if (snk->g_focus->s_thing) { t_atom at[2]; SETSYMBOL(&at[0], s); SETFLOAT(&at[1], f); ! pd_typedmess(snk->g_focus->s_thing, ps__focus, 2, at); } } --- 76,92 ---- { #ifdef HAMMERGUI_DEBUG ! post("_focus %s %g (sink %x)", (s ? s->s_name : "???"), f, (int)snk); #endif ! if (!snk->g_psfocus) ! { ! bug("hammergui__focus"); ! return; ! } ! if (snk->g_psfocus->s_thing) { t_atom at[2]; SETSYMBOL(&at[0], s); SETFLOAT(&at[1], f); ! pd_typedmess(snk->g_psfocus->s_thing, ps__focus, 2, at); } } *************** *** 82,93 **** { #ifdef HAMMERGUI_DEBUG ! if (s) post("_vised %s %g", s->s_name, f); #endif ! if (snk->g_vised->s_thing) { t_atom at[2]; SETSYMBOL(&at[0], s); SETFLOAT(&at[1], f); ! pd_typedmess(snk->g_vised->s_thing, ps__vised, 2, at); } #if 0 --- 95,111 ---- { #ifdef HAMMERGUI_DEBUG ! post("_vised %s %g (sink %x)", (s ? s->s_name : "???"), f, (int)snk); #endif ! if (!snk->g_psvised) ! { ! bug("hammergui__vised"); ! return; ! } ! if (snk->g_psvised->s_thing) { t_atom at[2]; SETSYMBOL(&at[0], s); SETFLOAT(&at[1], f); ! pd_typedmess(snk->g_psvised->s_thing, ps__vised, 2, at); } #if 0 *************** *** 102,122 **** static void hammergui_dobindmouse(t_hammergui *snk) { #if 0 /* How to be notified about changes of button state, prior to gui objects in a canvas? LATER find a reliable way -- delete if failed */ sys_vgui("bind hammertag <<hammerdown>> {pd [concat %s _up 0 \;]}\n", ! snk->g_gui->s_name); sys_vgui("bind hammertag <<hammerup>> {pd [concat %s _up 1 \;]}\n", ! snk->g_gui->s_name); #endif sys_vgui("bind all <<hammerdown>> {pd [concat %s _up 0 \;]}\n", ! snk->g_gui->s_name); sys_vgui("bind all <<hammerup>> {pd [concat %s _up 1 \;]}\n", ! snk->g_gui->s_name); }
static void hammergui__remouse(t_hammergui *snk) { ! if (snk->g_mouse->s_thing) { /* if a new master was bound in a gray period, we need to --- 120,148 ---- static void hammergui_dobindmouse(t_hammergui *snk) { + #ifdef HAMMERGUI_DEBUG + post("dobindmouse (sink %x)", (int)snk); + #endif #if 0 /* How to be notified about changes of button state, prior to gui objects in a canvas? LATER find a reliable way -- delete if failed */ sys_vgui("bind hammertag <<hammerdown>> {pd [concat %s _up 0 \;]}\n", ! snk->g_psgui->s_name); sys_vgui("bind hammertag <<hammerup>> {pd [concat %s _up 1 \;]}\n", ! snk->g_psgui->s_name); #endif sys_vgui("bind all <<hammerdown>> {pd [concat %s _up 0 \;]}\n", ! snk->g_psgui->s_name); sys_vgui("bind all <<hammerup>> {pd [concat %s _up 1 \;]}\n", ! snk->g_psgui->s_name); }
static void hammergui__remouse(t_hammergui *snk) { ! if (!snk->g_psmouse) ! { ! bug("hammergui__remouse"); ! return; ! } ! if (snk->g_psmouse->s_thing) { /* if a new master was bound in a gray period, we need to *************** *** 133,145 **** sys_vgui("bind Canvas <<hammerfocusin>> \ {if {[hammergui_ispatcher %%W]} \ ! {pd [concat %s _focus %%W 1 \;]}}\n", snk->g_gui->s_name); sys_vgui("bind Canvas <<hammerfocusout>> \ {if {[hammergui_ispatcher %%W]} \ ! {pd [concat %s _focus %%W 0 \;]}}\n", snk->g_gui->s_name); }
static void hammergui__refocus(t_hammergui *snk) { ! if (snk->g_focus->s_thing) { /* if a new master was bound in a gray period, we need to --- 159,176 ---- sys_vgui("bind Canvas <<hammerfocusin>> \ {if {[hammergui_ispatcher %%W]} \ ! {pd [concat %s _focus %%W 1 \;]}}\n", snk->g_psgui->s_name); sys_vgui("bind Canvas <<hammerfocusout>> \ {if {[hammergui_ispatcher %%W]} \ ! {pd [concat %s _focus %%W 0 \;]}}\n", snk->g_psgui->s_name); }
static void hammergui__refocus(t_hammergui *snk) { ! if (!snk->g_psfocus) ! { ! bug("hammergui__refocus"); ! return; ! } ! if (snk->g_psfocus->s_thing) { /* if a new master was bound in a gray period, we need to *************** *** 154,168 **** static void hammergui_dobindvised(t_hammergui *snk) { sys_vgui("bind Canvas <<hammervised>> \ {if {[hammergui_ispatcher %%W]} \ ! {pd [concat %s _vised %%W 1 \;]}}\n", snk->g_gui->s_name); sys_vgui("bind Canvas <<hammerunvised>> \ {if {[hammergui_ispatcher %%W]} \ ! {pd [concat %s _vised %%W 0 \;]}}\n", snk->g_gui->s_name); }
static void hammergui__revised(t_hammergui *snk) { ! if (snk->g_vised->s_thing) { /* if a new master was bound in a gray period, we need to --- 185,207 ---- static void hammergui_dobindvised(t_hammergui *snk) { + #ifdef HAMMERGUI_DEBUG + post("dobindvised (sink %x)", (int)snk); + #endif sys_vgui("bind Canvas <<hammervised>> \ {if {[hammergui_ispatcher %%W]} \ ! {pd [concat %s _vised %%W 1 \;]}}\n", snk->g_psgui->s_name); sys_vgui("bind Canvas <<hammerunvised>> \ {if {[hammergui_ispatcher %%W]} \ ! {pd [concat %s _vised %%W 0 \;]}}\n", snk->g_psgui->s_name); }
static void hammergui__revised(t_hammergui *snk) { ! if (!snk->g_psvised) ! { ! bug("hammergui__revised"); ! return; ! } ! if (snk->g_psvised->s_thing) { /* if a new master was bound in a gray period, we need to *************** *** 175,181 **** }
! static void hammergui_setup(void) { ! hammergui_class = class_new(gensym("_hammergui"), 0, 0, sizeof(t_hammergui), CLASS_PD | CLASS_NOINLET, 0); --- 214,246 ---- }
! static int hammergui_setup(void) { ! ps_hashhammergui = gensym("#hammergui"); ! ps__hammergui = gensym("_hammergui"); ! ps__up = gensym("_up"); ! ps__focus = gensym("_focus"); ! ps__vised = gensym("_vised"); ! if (ps_hashhammergui->s_thing) ! { ! char *cname = class_getname(*ps_hashhammergui->s_thing); ! #ifdef HAMMERGUI_DEBUG ! post("'%s' already registered as the global hammergui sink ", ! (cname ? cname : "???")); ! #endif ! if (strcmp(cname, ps__hammergui->s_name)) ! { ! /* FIXME protect against the danger of someone else ! (e.g. receive) binding to #hammergui */ ! bug("hammergui_setup"); ! return (0); ! } ! else ! { ! /* FIXME compatibility test */ ! hammergui_class = *ps_hashhammergui->s_thing; ! return (1); ! } ! } ! hammergui_class = class_new(ps__hammergui, 0, 0, sizeof(t_hammergui), CLASS_PD | CLASS_NOINLET, 0); *************** *** 187,197 **** class_addmethod(hammergui_class, (t_method)hammergui__revised, gensym("_revised"), 0); - ps__up = gensym("_up"); class_addmethod(hammergui_class, (t_method)hammergui__up, ps__up, A_FLOAT, 0); - ps__focus = gensym("_focus"); class_addmethod(hammergui_class, (t_method)hammergui__focus, ps__focus, A_SYMBOL, A_FLOAT, 0); - ps__vised = gensym("_vised"); class_addmethod(hammergui_class, (t_method)hammergui__vised, ps__vised, A_SYMBOL, A_FLOAT, 0); --- 252,259 ---- *************** *** 256,274 **** sys_gui(" pd [concat #hammergui _revised \;]\n"); sys_gui("}\n"); }
static int hammergui_validate(int dosetup) { ! if (dosetup) { ! if (!hammergui_class) hammergui_setup(); ! if (!sink) { ! sink = (t_hammergui *)pd_new(hammergui_class); ! sink->g_gui = gensym("#hammergui"); ! pd_bind((t_pd *)sink, sink->g_gui); } } ! if (hammergui_class && sink) return (1); else --- 318,340 ---- sys_gui(" pd [concat #hammergui _revised \;]\n"); sys_gui("}\n"); + return (1); }
static int hammergui_validate(int dosetup) { ! if (dosetup && !hammergui_sink ! && (hammergui_class || hammergui_setup())) { ! if (ps_hashhammergui->s_thing) ! hammergui_sink = (t_hammergui *)ps_hashhammergui->s_thing; ! else { ! hammergui_sink = (t_hammergui *)pd_new(hammergui_class); ! hammergui_sink->g_psgui = ps_hashhammergui; ! pd_bind((t_pd *)hammergui_sink, ! ps_hashhammergui); /* never unbound */ } } ! if (hammergui_class && hammergui_sink) return (1); else *************** *** 281,291 **** static int hammergui_mousevalidate(int dosetup) { ! if (dosetup && !sink->g_mouse) { ! sink->g_mouse = gensym("#hammermouse"); sys_gui("event add <<hammerdown>> <ButtonPress>\n"); sys_gui("event add <<hammerup>> <ButtonRelease>\n"); } ! if (sink->g_mouse) return (1); else --- 347,357 ---- static int hammergui_mousevalidate(int dosetup) { ! if (dosetup && !hammergui_sink->g_psmouse) { ! hammergui_sink->g_psmouse = gensym("#hammermouse"); sys_gui("event add <<hammerdown>> <ButtonPress>\n"); sys_gui("event add <<hammerup>> <ButtonRelease>\n"); } ! if (hammergui_sink->g_psmouse) return (1); else *************** *** 298,307 **** static int hammergui_pollvalidate(int dosetup) { ! if (dosetup && !sink->g_poll) { ! sink->g_poll = gensym("#hammerpoll"); ! pd_bind((t_pd *)sink, sink->g_poll); /* never unbound */ } ! if (sink->g_poll) return (1); else --- 364,374 ---- static int hammergui_pollvalidate(int dosetup) { ! if (dosetup && !hammergui_sink->g_pspoll) { ! hammergui_sink->g_pspoll = gensym("#hammerpoll"); ! pd_bind((t_pd *)hammergui_sink, ! hammergui_sink->g_pspoll); /* never unbound */ } ! if (hammergui_sink->g_pspoll) return (1); else *************** *** 314,324 **** static int hammergui_focusvalidate(int dosetup) { ! if (dosetup && !sink->g_focus) { ! sink->g_focus = gensym("#hammerfocus"); sys_gui("event add <<hammerfocusin>> <FocusIn>\n"); sys_gui("event add <<hammerfocusout>> <FocusOut>\n"); } ! if (sink->g_focus) return (1); else --- 381,391 ---- static int hammergui_focusvalidate(int dosetup) { ! if (dosetup && !hammergui_sink->g_psfocus) { ! hammergui_sink->g_psfocus = gensym("#hammerfocus"); sys_gui("event add <<hammerfocusin>> <FocusIn>\n"); sys_gui("event add <<hammerfocusout>> <FocusOut>\n"); } ! if (hammergui_sink->g_psfocus) return (1); else *************** *** 331,337 **** static int hammergui_visedvalidate(int dosetup) { ! if (dosetup && !sink->g_vised) { ! sink->g_vised = gensym("#hammervised"); /* subsequent map events have to be filtered out at the caller's side, LATER investigate */ --- 398,404 ---- static int hammergui_visedvalidate(int dosetup) { ! if (dosetup && !hammergui_sink->g_psvised) { ! hammergui_sink->g_psvised = gensym("#hammervised"); /* subsequent map events have to be filtered out at the caller's side, LATER investigate */ *************** *** 339,343 **** sys_gui("event add <<hammerunvised>> <Destroy>\n"); } ! if (sink->g_vised) return (1); else --- 406,410 ---- sys_gui("event add <<hammerunvised>> <Destroy>\n"); } ! if (hammergui_sink->g_psvised) return (1); else *************** *** 350,358 **** void hammergui_bindmouse(t_pd *master) { hammergui_validate(1); hammergui_mousevalidate(1); ! if (!sink->g_mouse->s_thing) ! hammergui_dobindmouse(sink); ! pd_bind(master, sink->g_mouse); }
--- 417,428 ---- void hammergui_bindmouse(t_pd *master) { + #ifdef HAMMERGUI_DEBUG + post("bindmouse, master %x", (int)master); + #endif hammergui_validate(1); hammergui_mousevalidate(1); ! if (!hammergui_sink->g_psmouse->s_thing) ! hammergui_dobindmouse(hammergui_sink); ! pd_bind(master, hammergui_sink->g_psmouse); }
*************** *** 360,367 **** { if (hammergui_validate(0) && hammergui_mousevalidate(0) ! && sink->g_mouse->s_thing) { ! pd_unbind(master, sink->g_mouse); ! if (!sink->g_mouse->s_thing) sys_gui("hammergui_remouse\n"); } --- 430,437 ---- { if (hammergui_validate(0) && hammergui_mousevalidate(0) ! && hammergui_sink->g_psmouse->s_thing) { ! pd_unbind(master, hammergui_sink->g_psmouse); ! if (!hammergui_sink->g_psmouse->s_thing) sys_gui("hammergui_remouse\n"); } *************** *** 385,390 **** if (hammergui_validate(0) && hammergui_pollvalidate(0)) { ! int doinit = (sink->g_poll->s_thing == (t_pd *)sink); ! pd_bind(master, sink->g_poll); if (doinit) { --- 455,461 ---- if (hammergui_validate(0) && hammergui_pollvalidate(0)) { ! int doinit = ! (hammergui_sink->g_pspoll->s_thing == (t_pd *)hammergui_sink); ! pd_bind(master, hammergui_sink->g_pspoll); if (doinit) { *************** *** 401,406 **** if (hammergui_validate(0) && hammergui_pollvalidate(0)) { ! pd_unbind(master, sink->g_poll); ! if (sink->g_poll->s_thing == (t_pd *)sink) { sys_gui("after cancel hammergui_poll\n"); --- 472,477 ---- if (hammergui_validate(0) && hammergui_pollvalidate(0)) { ! pd_unbind(master, hammergui_sink->g_pspoll); ! if (hammergui_sink->g_pspoll->s_thing == (t_pd *)hammergui_sink) { sys_gui("after cancel hammergui_poll\n"); *************** *** 416,422 **** hammergui_validate(1); hammergui_focusvalidate(1); ! if (!sink->g_focus->s_thing) ! hammergui_dobindfocus(sink); ! pd_bind(master, sink->g_focus); }
--- 487,493 ---- hammergui_validate(1); hammergui_focusvalidate(1); ! if (!hammergui_sink->g_psfocus->s_thing) ! hammergui_dobindfocus(hammergui_sink); ! pd_bind(master, hammergui_sink->g_psfocus); }
*************** *** 424,431 **** { if (hammergui_validate(0) && hammergui_focusvalidate(0) ! && sink->g_focus->s_thing) { ! pd_unbind(master, sink->g_focus); ! if (!sink->g_focus->s_thing) sys_gui("hammergui_refocus\n"); } --- 495,502 ---- { if (hammergui_validate(0) && hammergui_focusvalidate(0) ! && hammergui_sink->g_psfocus->s_thing) { ! pd_unbind(master, hammergui_sink->g_psfocus); ! if (!hammergui_sink->g_psfocus->s_thing) sys_gui("hammergui_refocus\n"); } *************** *** 435,443 **** void hammergui_bindvised(t_pd *master) { hammergui_validate(1); hammergui_visedvalidate(1); ! if (!sink->g_vised->s_thing) ! hammergui_dobindvised(sink); ! pd_bind(master, sink->g_vised); }
--- 506,517 ---- void hammergui_bindvised(t_pd *master) { + #ifdef HAMMERGUI_DEBUG + post("bindvised, master %x", (int)master); + #endif hammergui_validate(1); hammergui_visedvalidate(1); ! if (!hammergui_sink->g_psvised->s_thing) ! hammergui_dobindvised(hammergui_sink); ! pd_bind(master, hammergui_sink->g_psvised); }
*************** *** 445,452 **** { if (hammergui_validate(0) && hammergui_visedvalidate(0) ! && sink->g_vised->s_thing) { ! pd_unbind(master, sink->g_vised); ! if (!sink->g_vised->s_thing) sys_gui("hammergui_revised\n"); } --- 519,526 ---- { if (hammergui_validate(0) && hammergui_visedvalidate(0) ! && hammergui_sink->g_psvised->s_thing) { ! pd_unbind(master, hammergui_sink->g_psvised); ! if (!hammergui_sink->g_psvised->s_thing) sys_gui("hammergui_revised\n"); }
Index: gui.h =================================================================== RCS file: /cvsroot/pure-data/externals/miXed/shared/hammer/gui.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** gui.h 23 May 2003 12:29:52 -0000 1.1.1.1 --- gui.h 8 Dec 2004 15:40:13 -0000 1.2 *************** *** 1,3 **** ! /* Copyright (c) 2003 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ --- 1,3 ---- ! /* Copyright (c) 2003-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. */ *************** *** 9,18 **** { t_pd g_pd; ! t_symbol *g_gui; ! t_symbol *g_mouse; ! t_symbol *g_poll; ! t_symbol *g_focus; ! t_symbol *g_vised; ! int g_up; } t_hammergui;
--- 9,18 ---- { t_pd g_pd; ! t_symbol *g_psgui; ! t_symbol *g_psmouse; ! t_symbol *g_pspoll; ! t_symbol *g_psfocus; ! t_symbol *g_psvised; ! int g_isup; } t_hammergui;
Index: tree.h =================================================================== RCS file: /cvsroot/pure-data/externals/miXed/shared/hammer/tree.h,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** tree.h 23 May 2003 12:29:52 -0000 1.1.1.1 --- tree.h 8 Dec 2004 15:40:13 -0000 1.2 *************** *** 1,3 **** ! /* Copyright (c) 2003 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ --- 1,3 ---- ! /* Copyright (c) 2003-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. */ *************** *** 6,16 **** #define __HAMMERTREE_H__
#define HAMMERTREE_DEBUG
typedef struct _hammernode { ! int n_index; ! float n_value; ! int n_black; struct _hammernode *n_left; struct _hammernode *n_right; --- 6,23 ---- #define __HAMMERTREE_H__
+ #ifdef KRZYSZCZ #define HAMMERTREE_DEBUG + #endif + + typedef enum + { + HAMMERTYPE_FLOAT, HAMMERTYPE_SYMBOL, HAMMERTYPE_ATOM, + HAMMERTYPE_CUSTOM, HAMMERTYPE_ILLEGAL + } t_hammertype;
typedef struct _hammernode { ! int n_key; ! int n_black; struct _hammernode *n_left; struct _hammernode *n_right; *************** *** 20,23 **** --- 27,48 ---- } t_hammernode;
+ typedef struct _hammernode_float + { + t_hammernode nf_node; + t_float nf_value; + } t_hammernode_float; + + typedef struct _hammernode_symbol + { + t_hammernode ns_node; + t_symbol *ns_value; + } t_hammernode_symbol; + + typedef struct _hammernode_atom + { + t_hammernode na_node; + t_atom na_value; + } t_hammernode_atom; + typedef struct _hammertree { *************** *** 25,37 **** t_hammernode *t_first; t_hammernode *t_last; } t_hammertree;
! t_hammernode *hammertree_insert(t_hammertree *tree, int ndx); void hammertree_delete(t_hammertree *tree, t_hammernode *np); ! t_hammernode *hammertree_search(t_hammertree *tree, int ndx); ! t_hammernode *hammertree_closest(t_hammertree *tree, int ndx, int geqflag); ! void hammertree_init(t_hammertree *tree, int freecount); void hammertree_clear(t_hammertree *tree, int freecount); ! void hammertree_debug(t_hammertree *tree, int level);
#endif --- 50,86 ---- t_hammernode *t_first; t_hammernode *t_last; + t_hammertype t_valuetype; + size_t t_nodesize; } t_hammertree;
! #define HAMMERNODE_GETFLOAT(np) (((t_hammernode_float *)(np))->nf_value) ! #define HAMMERNODE_GETSYMBOL(np) (((t_hammernode_symbol *)(np))->ns_value) ! #define HAMMERNODE_GETATOMPTR(np) (&((t_hammernode_atom *)(np))->na_value) ! ! typedef void (*t_hammernode_vshowhook)(t_hammernode *, char *, unsigned); ! ! t_hammernode *hammertree_search(t_hammertree *tree, int key); ! t_hammernode *hammertree_closest(t_hammertree *tree, int key, int geqflag); ! ! t_hammernode *hammertree_insert(t_hammertree *tree, int key, int *foundp); ! t_hammernode *hammertree_multiinsert(t_hammertree *tree, int key, int fifoflag); ! t_hammernode *hammertree_insertfloat(t_hammertree *tree, int key, t_float f, ! int replaceflag); ! t_hammernode *hammertree_insertsymbol(t_hammertree *tree, int key, t_symbol *s, ! int replaceflag); ! t_hammernode *hammertree_insertatom(t_hammertree *tree, int key, t_atom *ap, ! int replaceflag); void hammertree_delete(t_hammertree *tree, t_hammernode *np); ! ! void hammertree_inittyped(t_hammertree *tree, ! t_hammertype vtype, int freecount); ! void hammertree_initcustom(t_hammertree *tree, ! size_t nodesize, int freecount); void hammertree_clear(t_hammertree *tree, int freecount); ! ! #ifdef HAMMERTREE_DEBUG ! void hammertree_debug(t_hammertree *tree, int level, ! t_hammernode_vshowhook hook); ! #endif
#endif
Index: tree.c =================================================================== RCS file: /cvsroot/pure-data/externals/miXed/shared/hammer/tree.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** tree.c 23 May 2003 12:29:52 -0000 1.1.1.1 --- tree.c 8 Dec 2004 15:40:13 -0000 1.2 *************** *** 1,3 **** ! /* Copyright (c) 2003 krzYszcz and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ --- 1,3 ---- ! /* Copyright (c) 2003-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. */ *************** *** 11,16 **** /* LATER freelist */
#ifdef HAMMERTREE_DEBUG ! /* returns bh or 0 if failed */ static int hammernode_verify(t_hammernode *np) { --- 11,18 ---- /* LATER freelist */
+ typedef t_hammernode *(*t_hammertree_inserthook)(t_hammernode *); + #ifdef HAMMERTREE_DEBUG ! /* returns black-height or 0 if failed */ static int hammernode_verify(t_hammernode *np) { *************** *** 44,48 **** }
! /* returns bh or 0 if failed */ static int hammertree_verify(t_hammertree *tree) { --- 46,50 ---- }
! /* returns black-height or 0 if failed */ static int hammertree_verify(t_hammertree *tree) { *************** *** 50,96 **** }
! static void hammernode_post(t_hammernode *np) { ! startpost("%d %g %d (", np->n_index, np->n_value, np->n_black); if (np->n_left) ! startpost("%d, ", np->n_left->n_index); else startpost("nul, "); if (np->n_right) ! post("%d)", np->n_right->n_index); else ! post("nul)"); }
! /* this is a standard stackless traversal, not the best one, obviously... ! (used only for debugging) */ ! static int hammertree_traverse(t_hammertree *tree, int postit) { ! t_hammernode *np = tree->t_root; int count = 0; ! while (np) { ! t_hammernode *prev = np->n_left; if (prev) { ! while (prev->n_right && prev->n_right != np) prev = prev->n_right; if (prev->n_right) { prev->n_right = 0; - if (postit) hammernode_post(np); count++; ! np = np->n_right; } else { ! prev->n_right = np; ! np = np->n_left; } } else { - if (postit) hammernode_post(np); count++; ! np = np->n_right; } } --- 52,172 ---- }
! static int hammernode_checkmulti(t_hammernode *np1, t_hammernode *np2) { ! if (np1 && np2 && np1->n_key == np2->n_key) ! { ! if (np1 == np2) ! bug("hammernode_checkmulti"); ! else ! return (1); ! } ! return (0); ! } ! ! static void hammernode_post(t_hammertree *tree, t_hammernode *np, ! t_hammernode_vshowhook hook, char *message) ! { ! startpost("%d ", np->n_key); ! if (tree->t_valuetype == HAMMERTYPE_FLOAT) ! startpost("%g ", HAMMERNODE_GETFLOAT(np)); ! else if (tree->t_valuetype == HAMMERTYPE_SYMBOL) ! startpost("%s ", HAMMERNODE_GETSYMBOL(np)->s_name); ! else if (tree->t_valuetype == HAMMERTYPE_ATOM) ! { ! t_atom *ap = HAMMERNODE_GETATOMPTR(np); ! if (ap->a_type == A_FLOAT) ! startpost("%g ", ap->a_w.w_float); ! else if (ap->a_type == A_SYMBOL) ! startpost("%s ", ap->a_w.w_symbol->s_name); ! } ! else if (hook) ! { ! char buf[MAXPDSTRING]; ! (*hook)(np, buf, MAXPDSTRING); ! startpost("%s ", buf); ! } ! else startpost("0x%08x ", (int)HAMMERNODE_GETSYMBOL(np)); ! startpost("%s ", (np->n_black ? "black" : "red")); ! ! if (hammernode_checkmulti(np, np->n_parent) || ! hammernode_checkmulti(np, np->n_left) || ! hammernode_checkmulti(np, np->n_right) || ! hammernode_checkmulti(np->n_parent, np->n_left) || ! hammernode_checkmulti(np->n_parent, np->n_right) || ! hammernode_checkmulti(np->n_left, np->n_right)) ! startpost("multi "); ! ! if (np->n_parent) ! startpost("(%d -> ", np->n_parent->n_key); ! else ! startpost("(nul -> "); if (np->n_left) ! startpost("%d, ", np->n_left->n_key); else startpost("nul, "); if (np->n_right) ! startpost("%d)", np->n_right->n_key); else ! startpost("nul)"); ! if (message) ! post(": %s", message); ! else ! endpost(); }
! /* Assert a standard stackless traversal producing the same sequence, ! as the auxiliary list. */ ! static int hammertree_checktraversal(t_hammertree *tree) { ! t_hammernode *treewalk = tree->t_root; ! t_hammernode *listwalk = tree->t_first; int count = 0; ! while (treewalk) { ! t_hammernode *prev = treewalk->n_left; if (prev) { ! while (prev->n_right && prev->n_right != treewalk) ! prev = prev->n_right; if (prev->n_right) { prev->n_right = 0; count++; ! if (treewalk == listwalk) ! listwalk = listwalk->n_next; ! else ! { ! bug("hammertree_checktraversal 1"); ! hammernode_post(tree, treewalk, 0, "treewalk"); ! if (listwalk) ! hammernode_post(tree, listwalk, 0, "listwalk"); ! else ! post("empty listwalk pointer"); ! listwalk = treewalk; ! } ! treewalk = treewalk->n_right; } else { ! prev->n_right = treewalk; ! treewalk = treewalk->n_left; } } else { count++; ! if (treewalk == listwalk) ! listwalk = listwalk->n_next; ! else ! { ! bug("hammertree_checktraversal 2"); ! hammernode_post(tree, treewalk, 0, "treewalk"); ! if (listwalk) ! hammernode_post(tree, listwalk, 0, "listwalk"); ! else ! post("empty listwalk pointer"); ! listwalk = treewalk; ! } ! treewalk = treewalk->n_right; } } *************** *** 109,128 **** }
! void hammertree_debug(t_hammertree *tree, int level) { t_hammernode *np; int count; post("------------------------"); ! count = hammertree_traverse(tree, level); ! if (level > 1) { ! post("***"); ! for (np = tree->t_last; np; np = np->n_prev) ! startpost("%d ", np->n_index); ! endpost(); } ! post("count %d, height %d, root %d:", ! count, hammernode_height(tree->t_root), ! (tree->t_root ? tree->t_root->n_index : 0)); post("...verified (black-height is %d)", hammertree_verify(tree)); post("------------------------"); --- 185,221 ---- }
! void hammertree_debug(t_hammertree *tree, int level, ! t_hammernode_vshowhook hook) { t_hammernode *np; int count; post("------------------------"); ! count = hammertree_checktraversal(tree); ! if (level) { ! for (np = tree->t_first; np; np = np->n_next) ! hammernode_post(tree, np, hook, 0); ! if (level > 1) ! { ! post("************"); ! for (np = tree->t_last; np; np = np->n_prev) ! startpost("%d ", np->n_key); ! endpost(); ! } } ! if (tree->t_root) ! { ! t_hammernode *first = tree->t_root, *last = tree->t_root; ! while (first->n_left && first->n_left != tree->t_root) ! first = first->n_left; ! while (last->n_right && last->n_right != tree->t_root) ! last = last->n_right; ! post("count %d, height %d, root %d", ! count, hammernode_height(tree->t_root), tree->t_root->n_key); ! post("first %d, root->left* %d, last %d, root->right* %d", ! (tree->t_first ? tree->t_first->n_key : 0), first->n_key, ! (tree->t_last ? tree->t_last->n_key : 0), last->n_key); ! } ! else post("empty"); post("...verified (black-height is %d)", hammertree_verify(tree)); post("------------------------"); *************** *** 162,175 **** }
! /* returns a newly inserted or already existing node ! (or 0 if allocation failed) */ ! t_hammernode *hammertree_insert(t_hammertree *tree, int ndx) { t_hammernode *np, *parent, *result; if (!(np = tree->t_root)) { ! if (!(np = getbytes(sizeof(*np)))) return (0); ! np->n_index = ndx; np->n_black = 1; tree->t_root = tree->t_first = tree->t_last = np; --- 255,310 ---- }
! static t_hammernode *hammertree_preinserthook(t_hammernode *np) ! { ! while (np->n_prev && np->n_prev->n_key == np->n_key) ! np = np->n_prev; ! if (np->n_left) ! { ! np = np->n_prev; ! if (np->n_right) ! { ! /* LATER revisit */ ! bug("hammertree_preinserthook"); ! return (0); /* do nothing */ ! } ! } ! return (np); ! } ! ! static t_hammernode *hammertree_postinserthook(t_hammernode *np) ! { ! while (np->n_next && np->n_next->n_key == np->n_key) ! np = np->n_next; ! if (np->n_right) ! { ! np = np->n_next; ! if (np->n_left) ! { ! /* LATER revisit */ ! bug("hammertree_postinserthook"); ! return (0); /* do nothing */ ! } ! } ! return (np); ! } ! ! /* Returns a newly inserted or already existing node (or 0 if allocation ! failed). A caller is responsible for assigning a value. If hook is ! supplied, it is called iff key is found. In case of key being found ! (which means foundp returns 1), a new node is inserted, unless hook is ! either empty, or returns null. Hook's nonempty return is the parent ! for the new node. It is expected to have no more than one child. */ ! static t_hammernode *hammertree_doinsert(t_hammertree *tree, int key, ! t_hammertree_inserthook hook, ! int *foundp) { t_hammernode *np, *parent, *result; + int leftchild; + *foundp = 0; if (!(np = tree->t_root)) { ! if (!(np = getbytes(tree->t_nodesize))) return (0); ! np->n_key = key; np->n_black = 1; tree->t_root = tree->t_first = tree->t_last = np; *************** *** 178,192 ****
do ! if (np->n_index == ndx) ! return (np); ! else ! parent = np; ! while (np = (ndx < np->n_index ? np->n_left : np->n_right)); ! ! if (!(np = getbytes(sizeof(*np)))) return (0); ! np->n_index = ndx; np->n_parent = parent; ! if (ndx < parent->n_index) { parent->n_left = np; --- 313,353 ----
do ! { ! if (np->n_key == key) ! { ! *foundp = 1; ! if (hook && (parent = (*hook)(np))) ! { ! if (parent->n_left && parent->n_right) ! { ! bug("hammertree_insert, callback return 1"); ! parent = parent->n_next; ! } ! if (leftchild = (key < parent->n_key)) ! { ! if (parent->n_left) ! { ! bug("hammertree_insert, callback return 2"); ! leftchild = 0; ! } ! } ! else if (parent->n_right) ! leftchild = 1; ! goto addit; ! } ! else return (np); /* a caller may then keep or replace the value */ ! } ! else parent = np; ! } ! while (np = (key < np->n_key ? np->n_left : np->n_right)); ! leftchild = (key < parent->n_key); ! addit: ! /* parent has no more than one child, new node becomes ! parent's immediate successor or predecessor */ ! if (!(np = getbytes(tree->t_nodesize))) return (0); ! np->n_key = key; np->n_parent = parent; ! if (leftchild) { parent->n_left = np; *************** *** 270,302 ****
/* assuming that requested node exists */ ! void hammertree_delete(t_hammertree *tree, t_hammernode *np) { ! t_hammernode *gone, *parent, *child; ! /* gone is the actual node to be deleted ! -- it has to be the parent of no more than one child: */ ! if (np->n_left && np->n_right) { ! gone = np->n_next; /* gone always exists */ ! child = gone->n_right; /* there is no left child of gone */ ! /* gone is not a requested node, so we replace fields to be ! deleted with gone's fields: */ ! np->n_index = gone->n_index; ! np->n_value = gone->n_value; /* update the auxiliary linked list structure */ ! /* np->n_prev is up-to-date */ ! if (np->n_prev) ! np->n_prev->n_next = np; ! else tree->t_first = np; ! if (np->n_next = gone->n_next) ! np->n_next->n_prev = np; ! else tree->t_last = np; } else { - gone = np; - if (gone->n_left) - child = gone->n_left; - else - child = gone->n_right; /* update the auxiliary linked list structure */ if (gone->n_prev) --- 431,491 ----
/* assuming that requested node exists */ ! void hammertree_delete(t_hammertree *tree, t_hammernode *gone) { ! t_hammernode *parent; /* parent of gone, after relinking */ ! t_hammernode *child; /* gone's only child (or null), after relinking */ ! /* gone has to be the parent of no more than one child */ ! if (gone->n_left && gone->n_right) { ! /* Successor is the new parent of gone's children, and a new child ! of gone's parent (if any). Successor always exists in this context, ! and it has no left child. The simplistic scheme is to replace ! gone's fields with successor's fields, and delete the successor. ! We cannot do so, however, because successor may be pointed at... */ ! t_hammernode *successor = gone->n_next; ! child = successor->n_right; ! successor->n_left = gone->n_left; ! successor->n_left->n_parent = successor; ! if (successor == gone->n_right) ! parent = successor; ! else ! { ! /* successor's parent always exists in this context, ! successor is the left child of its parent */ ! parent = successor->n_parent; ! parent->n_left = child; ! if (child) /* (sentinel not used) */ ! child->n_parent = parent; ! successor->n_right = gone->n_right; ! successor->n_right->n_parent = successor; ! } ! if (gone->n_parent) ! { ! int swp; ! if (gone == gone->n_parent->n_left) ! gone->n_parent->n_left = successor; ! else ! gone->n_parent->n_right = successor; ! successor->n_parent = gone->n_parent; ! swp = gone->n_black; ! gone->n_black = successor->n_black; ! successor->n_black = swp; ! } ! else ! { ! tree->t_root = successor; ! successor->n_parent = 0; ! gone->n_black = successor->n_black; ! successor->n_black = 1; /* LATER rethink */ ! } ! /* update the auxiliary linked list structure */ ! if (successor->n_prev = gone->n_prev) ! gone->n_prev->n_next = successor; ! else ! tree->t_first = successor; } else { /* update the auxiliary linked list structure */ if (gone->n_prev) *************** *** 308,330 **** else tree->t_last = gone->n_prev; ! } ! /* connect gone's child with gone's parent */ ! if (!(parent = gone->n_parent)) ! { ! if (tree->t_root = child) { ! child->n_parent = 0; ! child->n_black = 1; /* LATER rethink */ } - goto done; - } - else - { - if (child) /* (sentinel not used) */ - child->n_parent = parent; - if (gone == parent->n_left) - parent->n_left = child; else ! parent->n_right = child; }
--- 497,524 ---- else tree->t_last = gone->n_prev; ! ! /* connect gone's child with gone's parent */ ! if (gone->n_left) ! child = gone->n_left; ! else ! child = gone->n_right; ! if (parent = gone->n_parent) { ! if (child) /* (sentinel not used) */ ! child->n_parent = parent; ! if (gone == parent->n_left) ! parent->n_left = child; ! else ! parent->n_right = child; } else ! { ! if (tree->t_root = child) ! { ! child->n_parent = 0; ! child->n_black = 1; /* LATER rethink */ ! } ! goto done; ! } }
*************** *** 432,436 **** } done: ! freebytes(gone, sizeof(*gone)); #ifdef HAMMERTREE_DEBUG hammertree_verify(tree); --- 626,630 ---- } done: ! freebytes(gone, tree->t_nodesize); #ifdef HAMMERTREE_DEBUG hammertree_verify(tree); *************** *** 438,450 **** }
! t_hammernode *hammertree_search(t_hammertree *tree, int ndx) { t_hammernode *np = tree->t_root; ! while (np && np->n_index != ndx) ! np = (ndx < np->n_index ? np->n_left : np->n_right); return (np); }
! t_hammernode *hammertree_closest(t_hammertree *tree, int ndx, int geqflag) { t_hammernode *np, *parent; --- 632,644 ---- }
! t_hammernode *hammertree_search(t_hammertree *tree, int key) { t_hammernode *np = tree->t_root; ! while (np && np->n_key != key) ! np = (key < np->n_key ? np->n_left : np->n_right); return (np); }
! t_hammernode *hammertree_closest(t_hammertree *tree, int key, int geqflag) { t_hammernode *np, *parent; *************** *** 452,470 **** return (0); do ! if (np->n_index == ndx) return (np); else parent = np; ! while (np = (ndx < np->n_index ? np->n_left : np->n_right)); if (geqflag) ! return (ndx > parent->n_index ? parent->n_next : parent); else ! return (ndx < parent->n_index ? parent->n_prev : parent); }
/* LATER preallocate 'freecount' nodes */ ! void hammertree_init(t_hammertree *tree, int freecount) { tree->t_root = tree->t_first = tree->t_last = 0; }
--- 646,772 ---- return (0); do ! if (np->n_key == key) return (np); else parent = np; ! while (np = (key < np->n_key ? np->n_left : np->n_right)); if (geqflag) ! return (key > parent->n_key ? parent->n_next : parent); else ! return (key < parent->n_key ? parent->n_prev : parent); ! } ! ! t_hammernode *hammertree_insert(t_hammertree *tree, int key, int *foundp) ! { ! return (hammertree_doinsert(tree, key, 0, foundp)); ! } ! ! t_hammernode *hammertree_multiinsert(t_hammertree *tree, int key, int fifoflag) ! { ! int found; ! return (hammertree_doinsert(tree, key, (fifoflag ? ! hammertree_postinserthook : ! hammertree_preinserthook), &found)); ! } ! ! t_hammernode *hammertree_insertfloat(t_hammertree *tree, int key, t_float f, ! int replaceflag) ! { ! int found; ! t_hammernode *np = hammertree_doinsert(tree, key, 0, &found); ! if (np && (!found || replaceflag)) ! { ! if (tree->t_valuetype == HAMMERTYPE_FLOAT) ! { ! t_hammernode_float *npf = (t_hammernode_float *)np; ! npf->nf_value = f; ! } ! else if (tree->t_valuetype == HAMMERTYPE_ATOM) ! { ! t_hammernode_atom *npa = (t_hammernode_atom *)np; ! t_atom *ap = &npa->na_value; ! SETFLOAT(ap, f); ! } ! else bug("hammertree_insertfloat"); ! } ! return (np); ! } ! ! t_hammernode *hammertree_insertsymbol(t_hammertree *tree, int key, t_symbol *s, ! int replaceflag) ! { ! int found; ! t_hammernode *np = hammertree_doinsert(tree, key, 0, &found); ! if (np && (!found || replaceflag)) ! { ! if (tree->t_valuetype == HAMMERTYPE_SYMBOL) ! { ! t_hammernode_symbol *nps = (t_hammernode_symbol *)np; ! nps->ns_value = s; ! } ! else if (tree->t_valuetype == HAMMERTYPE_ATOM) ! { ! t_hammernode_atom *npa = (t_hammernode_atom *)np; ! t_atom *ap = &npa->na_value; ! SETSYMBOL(ap, s); ! } ! else bug("hammertree_insertsymbol"); ! } ! return (np); ! } ! ! t_hammernode *hammertree_insertatom(t_hammertree *tree, int key, t_atom *ap, ! int replaceflag) ! { ! int found; ! t_hammernode *np = hammertree_doinsert(tree, key, 0, &found); ! if (np && (!found || replaceflag)) ! { ! if (tree->t_valuetype == HAMMERTYPE_ATOM) ! { ! t_hammernode_atom *npa = (t_hammernode_atom *)np; ! npa->na_value = *ap; ! } ! else bug("hammertree_insertatom"); ! } ! return (np); }
/* LATER preallocate 'freecount' nodes */ ! static void hammertree_doinit(t_hammertree *tree, t_hammertype vtype, ! size_t nodesize, int freecount) { tree->t_root = tree->t_first = tree->t_last = 0; + tree->t_valuetype = vtype; + tree->t_nodesize = nodesize; + } + + void hammertree_inittyped(t_hammertree *tree, + t_hammertype vtype, int freecount) + { + size_t nsize; + switch (vtype) + { + case HAMMERTYPE_FLOAT: + nsize = sizeof(t_hammernode_float); + break; + case HAMMERTYPE_SYMBOL: + nsize = sizeof(t_hammernode_symbol); + break; + case HAMMERTYPE_ATOM: + nsize = sizeof(t_hammernode_atom); + break; + default: + bug("hammertree_inittyped"); + vtype = HAMMERTYPE_ILLEGAL; + nsize = sizeof(t_hammernode); + } + hammertree_doinit(tree, vtype, nsize, freecount); + } + + void hammertree_initcustom(t_hammertree *tree, + size_t nodesize, int freecount) + { + hammertree_doinit(tree, HAMMERTYPE_CUSTOM, nodesize, freecount); }
*************** *** 477,482 **** np = next; next = next->n_next; ! freebytes(np, sizeof(*np)); } ! hammertree_init(tree, 0); } --- 779,784 ---- np = next; next = next->n_next; ! freebytes(np, tree->t_nodesize); } ! hammertree_doinit(tree, tree->t_valuetype, tree->t_nodesize, 0); }