[PD-cvs] externals/miXed/shared/hammer gui.c,1.3,1.4 gui.h,1.1.1.1,1.2 tree.c,1.1.1.1,1.2 tree.h,1.1.1.1,1.2

Krzysztof Czaja krzyszcz at users.sourceforge.net
Wed Dec 8 16:40:15 CET 2004


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);
  }





More information about the Pd-cvs mailing list