[xiph-commits] r13782 - trunk/sushivision

xiphmont at svn.xiph.org xiphmont at svn.xiph.org
Tue Sep 11 12:57:16 PDT 2007


Author: xiphmont
Date: 2007-09-11 12:57:15 -0700 (Tue, 11 Sep 2007)
New Revision: 13782

Removed:
   trunk/sushivision/sushimacro.h
Modified:
   trunk/sushivision/Makefile
   trunk/sushivision/example_fractal.c
   trunk/sushivision/gtksucks.c
   trunk/sushivision/internal.h
   trunk/sushivision/main.c
   trunk/sushivision/objective.c
   trunk/sushivision/objective.h
   trunk/sushivision/panel-2d.c
   trunk/sushivision/panel-2d.h
   trunk/sushivision/panel.c
   trunk/sushivision/slider.c
   trunk/sushivision/sushivision.h
   trunk/sushivision/tokens.c
Log:
Broad front of work in progress:

Begin new objective function mapping work
Extend locking model to directional/multistage 
Begin abstracting plane rendering out of 2d
Begin collapsing all panels into single panel type



Modified: trunk/sushivision/Makefile
===================================================================
--- trunk/sushivision/Makefile	2007-09-09 22:27:05 UTC (rev 13781)
+++ trunk/sushivision/Makefile	2007-09-11 19:57:15 UTC (rev 13782)
@@ -24,16 +24,15 @@
 SOCFLAGS  = -fPIC
 SOLDFLAGS = -shared -nostdlib -Wl,-soname="lib$(NAME).so.$(MAJOR)"
 
-SRC       = main.c scale.c plot.c slider.c slice.c spinner.c panel.c panel-1d.c panel-2d.c \
-	panel-xy.c mapping.c dimension.c function.c objective.c undo.c gtksucks.c xml.c \
+SRC       = main.c scale.c plot.c slider.c slice.c spinner.c objective.c panel.c panel-2d.c \
+	mapping.c dimension.c function.c undo.c gtksucks.c xml.c \
 	tokens.c example_fractal.c example_discrete.c example_chirp.c example_spirograph.c
 INC       = sushivision.h sushimacro.h
 MAN	  =
 EXAMPLES  = sushivision_fractal #sushivision_discrete sushivision_chirp
 EX_OBJ    = example_fractal.o #example_discrete.o example_chirp.o example_spirograph.o
-OBJ       = main.o scale.o plot.o slider.o slice.o spinner.c panel.o panel-1d.o panel-2d.o \
-	panel-xy.o mapping.o dimension.o function.o objective.o undo.o gtksucks.o xml.o \
-	tokens.c
+OBJ       = main.o scale.o plot.o slider.o slice.o spinner.c objective.o panel.o panel-2d.o \
+	mapping.o dimension.o function.o undo.o gtksucks.o xml.o tokens.c
 LIBS      = -lpthread -ldl
 CAIROVER  =  >= 1.4.1
 GTKVER    =  >= 2.10.0

Modified: trunk/sushivision/example_fractal.c
===================================================================
--- trunk/sushivision/example_fractal.c	2007-09-09 22:27:05 UTC (rev 13781)
+++ trunk/sushivision/example_fractal.c	2007-09-11 19:57:15 UTC (rev 13782)
@@ -78,23 +78,15 @@
 		    "100000:one hundred thousand");
   sv_dim_set_value(100);
 
-  sv_func_t *f = sv_func_new(0, 2, fractal_objective, 0);
-  
-  sv_obj_new("outer",
-	     (sv_func_t *[]){f},
-	     (int []){0},
-	     "Y");
+  sv_obj_new("outer",fractal_objective,"rc,ic,rz,iz,it", "Z,*");
   sv_obj_make_scale("0, .001, .01, .1, 1.0");
   
-  sv_obj_new("inner",
-	     (sv_func_t *[]){f},
-	     (int []){1},
-	     "Y");
+  sv_obj_new("inner",fractal_objective,"rc,ic,rz,iz,it", "*,Z");
   sv_obj_make_scale("0, .001, .01, .1, 1.0");
   
   sv_panel_new_2d(0,"Mandel/Julia Fractal",
 		  "inner, outer",
-		  "rc,ic,rz,iz,it",
+		  "rc(X,Y), ic(X,Y), rz(X,Y), iz(X,Y), it",
 		  0);
   
   sv_go();

Modified: trunk/sushivision/gtksucks.c
===================================================================
--- trunk/sushivision/gtksucks.c	2007-09-09 22:27:05 UTC (rev 13781)
+++ trunk/sushivision/gtksucks.c	2007-09-11 19:57:15 UTC (rev 13782)
@@ -37,14 +37,14 @@
    behaviors. */
 
 /**********************************************************************/
-/* fixup number 1: insensitive widgets (except children of viewports,
-   a special case) eat mouse events.  This doesn't seem like a big
-   deal, but if you're implementing a right-click context menu, this
-   means you cannot pop a menu if the user was unlucky enough to have
-   right-clicked over an insensitive widget.  Wrap the widget
-   sensitivity setting method to also also set/unset the
-   GDK_BUTTON_PRESS_MASK on a widget; when insensitive, this will
-   remove its ability to silently swallow mouse events. */
+/* Insensitive widgets (except children of viewports, a special case)
+   eat mouse events.  This doesn't seem like a big deal, but if you're
+   implementing a right-click context menu, this means you cannot pop
+   a menu if the user was unlucky enough to have right-clicked over an
+   insensitive widget.  Wrap the widget sensitivity setting method to
+   also also set/unset the GDK_BUTTON_PRESS_MASK on a widget; when
+   insensitive, this will remove its ability to silently swallow mouse
+   events. */
 
 /* Note that this only works after the widget is realized, as
    realization will clobber the event mask */
@@ -127,16 +127,15 @@
 }
 
 /**********************************************************************/
-/* fixup number 2: Buttons (and their subclasses) don't do anything
-   with mousebutton3, but they swallow the events anyway preventing
-   them from cascading.  The 'supported' way of implementing a
-   context-sensitive right-click menu is to recursively bind a new
-   handler to each and every button on a toplevel.  This is mad
-   whack.  The below 'fixes' buttons at the class level by ramming a
-   new button press handler into the GtkButtonClass structure (and,
-   unfortunately, button subclasses as their classes have also already
-   initialized and made a copy of the Button's class structure and
-   handlers */ 
+/* Buttons (and their subclasses) don't do anything with mousebutton3,
+   but they swallow the events anyway preventing them from cascading.
+   The 'supported' way of implementing a context-sensitive right-click
+   menu is to recursively bind a new handler to each and every button
+   on a toplevel.  This is mad whack.  The below 'fixes' buttons at
+   the class level by ramming a new button press handler into the
+   GtkButtonClass structure (and, unfortunately, button subclasses as
+   their classes have also already initialized and made a copy of the
+   Button's class structure and handlers */ 
 
 static gboolean _gtk_button_button_press_new (GtkWidget      *widget,
 					     GdkEventButton *event){
@@ -197,58 +196,6 @@
 }
 
 /**********************************************************************/
-/* fixup number 3: GDK uses whatever default mutex type offered by the
-   system, and this usually means non-recursive ('fast') mutextes.
-   The problem with this is that gdk_threads_enter() and
-   gdk_threads_leave() cannot be used in any call originating from the
-   main loop, but are required in calls from idle handlers and other
-   threads. In effect we would need seperate identical versions of
-   each widget method, one locked, one unlocked, depending on where
-   the call originated.  Eliminate this problem by installing a
-   recursive mutex. */
-
-static pthread_mutex_t gdkm;
-static pthread_mutexattr_t gdkma;
-static int depth = 0;
-static int firstunder = 0;
-
-static void recursive_gdk_lock(void){
-  pthread_mutex_lock(&gdkm);
-  depth++;
-}
-
-static void recursive_gdk_unlock(void){
-  depth--;
-  if(depth<0){
-    if(!firstunder){ // annoying detail of gtk locking; in apps that
-      // don't normally use threads, onr does not lock before entering
-      // mainloop; in apps that do thread, the mainloop must be
-      // locked.  We can't tell which situation was in place before
-      // setting up our own threading, so allow one refcount error
-      // which we assume was the unlocked mainloop of a normally
-      // unthreaded gtk app.
-      firstunder++;
-      depth=0;
-    }else{
-      fprintf(stderr,"Internal locking error; refcount < 0. Dumping core for debugging\n");
-      abort();
-    }
-  }else
-    pthread_mutex_unlock(&gdkm);
-}
-
-void _gtk_mutex_fixup(){
-  pthread_mutexattr_init(&gdkma);
-  pthread_mutexattr_settype(&gdkma,PTHREAD_MUTEX_RECURSIVE);
-  pthread_mutex_init(&gdkm,&gdkma);
-  gdk_threads_set_lock_functions(recursive_gdk_lock,recursive_gdk_unlock);
-}
-
-pthread_mutex_t *_gtk_get_mutex(void){
-  return &gdkm;
-}
-
-/**********************************************************************/
 /* Not really a fixup; generate menus that declare what the keyboard
    shortcuts are */
 

Modified: trunk/sushivision/internal.h
===================================================================
--- trunk/sushivision/internal.h	2007-09-09 22:27:05 UTC (rev 13781)
+++ trunk/sushivision/internal.h	2007-09-11 19:57:15 UTC (rev 13782)
@@ -29,6 +29,38 @@
 #include <libxml/tree.h>
 #include "sushivision.h"
 
+/* locking *****************************************************/
+
+// strict mutex acquisation ordering: 
+// gdk -> panel -> objective -> dimension -> scale
+// functions below check/enforce
+
+extern void _sv_gdk_lock_i(const char *func, int line);
+extern void _sv_gdk_unlock_i(const char *func, int line);
+extern void _sv_panel_lock_i(const char *func, int line);
+extern void _sv_panel_unlock_i(const char *func, int line);
+extern void _sv_objective_lock_i(const char *func, int line);
+extern void _sv_objective_unlock_i(const char *func, int line);
+extern void _sv_dimension_lock_i(const char *func, int line);
+extern void _sv_dimension_unlock_i(const char *func, int line);
+extern void _sv_scale_lock_i(const char *func, int line);
+extern void _sv_scale_unlock_i(const char *func, int line);
+
+#define gdk_lock() _sv_gdk_lock_i(__FUNCTION__,__LINE__);
+#define gdk_unlock() _sv_gdk_lock_i(__FUNCTION__,__LINE__);
+
+#define panel_lock() _sv_panel_lock_i(__FUNCTION__,__LINE__);
+#define panel_unlock() _sv_panel_lock_i(__FUNCTION__,__LINE__);
+
+#define obj_lock() _sv_objective_lock_i(__FUNCTION__,__LINE__);
+#define obj_unlock() _sv_objective_lock_i(__FUNCTION__,__LINE__);
+
+#define dim_lock() _sv_dimension_lock_i(__FUNCTION__,__LINE__);
+#define dim_unlock() _sv_dimension_lock_i(__FUNCTION__,__LINE__);
+
+#define scale_lock() _sv_scale_lock_i(__FUNCTION__,__LINE__);
+#define scale_unlock() _sv_scale_lock_i(__FUNCTION__,__LINE__);
+
 typedef struct {
   char *s;
   double v;
@@ -47,6 +79,8 @@
   _sv_token **list;
 } _sv_tokenlist;
 
+/* tokenization and API argument parsing *****************************/
+
 // name           string
 // labelname      name[:string]
 // displayvalue   number[:string]
@@ -70,12 +104,14 @@
 extern _sv_token *_sv_tokenize_nameparam(char *in);
 extern _sv_token *_sv_tokenize_declparam(char *in);
 extern _sv_tokenlist *_sv_tokenize_namelist(char *in);
+extern _sv_tokenlist *_sv_tokenize_noparamlist(char *in);
 extern void _sv_tokenval_free(_sv_tokenval *t);
 extern void _sv_token_free(_sv_token *t);
 extern void _sv_tokenlist_free(_sv_tokenlist *l);
 extern char *_sv_tokenize_escape(char *a);
 
-// used to glue numeric settings to semantic labels for menus/save files
+
+/* used to glue numeric settings to semantic labels for menus/save files **/
 typedef struct _sv_propmap _sv_propmap_t;
 struct _sv_propmap {
   char *left;
@@ -246,8 +282,6 @@
 extern char *_sv_dirname;
 extern char *_sv_cwdname;
 
-extern int _sv_functions;
-extern sv_func_t **_sv_function_list;
 extern int _sv_dimensions;
 extern sv_dim_t **_sv_dimension_list;
 extern int _sv_objectives;
@@ -261,3 +295,5 @@
 extern pthread_key_t _sv_dim_key;
 extern pthread_key_t _sv_obj_key;
 
+extern sv_obj_t *_sv_obj(char *name);
+extern sv_dim_t *_sv_dim(char *name);

Modified: trunk/sushivision/main.c
===================================================================
--- trunk/sushivision/main.c	2007-09-09 22:27:05 UTC (rev 13781)
+++ trunk/sushivision/main.c	2007-09-11 19:57:15 UTC (rev 13782)
@@ -39,18 +39,285 @@
 #include "internal.h"
 #include "sushi-gtkrc.h"
 
-static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t mc = PTHREAD_COND_INITIALIZER;
+// strict mutex acquisation ordering: gdk -> panel -> objective -> dimension -> scale
+typedef struct {
+  int holding_gdk;
+
+  int holding_panel;
+  const char *func_panel;
+  int line_panel;
+
+  int holding_obj;
+  const char *func_obj;
+  int line_obj;
+
+  int holding_dim;
+  const char *func_dim;
+  int line_dim;
+
+  int holding_scale;
+  const char *func_scale;
+  int line_scale;
+
+} mutexcheck;
+
+static pthread_mutex_t panel_m = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t obj_m = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t dim_m = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t scale_m = PTHREAD_MUTEX_INITIALIZER;
+static pthread_key_t   _sv_mutexcheck_key;
+
+/**********************************************************************/
+/* GDK uses whatever default mutex type offered by the system, and
+   this usually means non-recursive ('fast') mutextes.  The problem
+   with this is that gdk_threads_enter() and gdk_threads_leave()
+   cannot be used in any call originating from the main loop, but are
+   required in calls from idle handlers and other threads. In effect
+   we would need seperate identical versions of each widget method,
+   one locked, one unlocked, depending on where the call originated.
+   Eliminate this problem by installing a recursive mutex. */
+
+static pthread_mutex_t gdk_m;
+static pthread_mutexattr_t gdk_ma;
+static int gdk_firstunder = 0;
+
+void _sv_gdk_lock_i(const char *func, int line){
+  mutexcheck *check = pthread_getspecific(_sv_mutexcheck_key);
+  const char *m=NULL;
+  const char *f=NULL;
+  int l=-1;
+  
+  if(!check){
+    check = calloc(1,sizeof(*check));
+    pthread_setspecific(_sv_mutexcheck_key, (void *)check);
+  }
+
+  if(check->holding_panel){ m="panel"; f=check->func_panel; l=check->line_panel; }
+  if(check->holding_obj){ m="objective"; f=check->func_obj; l=check->line_obj; }
+  if(check->holding_dim){ m="dimension"; f=check->func_dim; l=check->line_dim; }
+  if(check->holding_scale){ m="scale"; f=check->func_scale; l=check->line_scale; }
+    
+  if(f){
+    if(func)
+      fprintf(stderr,"sushivision: Out of order locking error.\n"
+	      "\tTrying to acquire gdk lock in %s line %d,\n"
+	      "\t%s lock already held from %s line %d.\n",
+	      func,line,m,f,l);
+    else
+      fprintf(stderr,"sushivision: Out of order locking error.\n"
+	      "\tTrying to acquire gdk lock, %s lock already held\n"
+	      "\tfrom %s line %d.\n",
+	      m,f,l);
+  }
+
+  pthread_mutex_lock(&gdk_m);
+  check->holding_gdk++;
+
+}
+
+void _sv_gdk_unlock_i(const char *func, int line){
+  mutexcheck *check = pthread_getspecific(_sv_mutexcheck_key);
+
+  if(!check){
+    if(!gdk_firstunder){ // annoying detail of gtk locking; in apps that
+      // don't normally use threads, one does not lock before entering
+      // mainloop; in apps that do thread, the mainloop must be
+      // locked.  We can't tell which situation was in place before
+      // setting up our own threading, so allow one refcount error
+      // which we assume was the unlocked mainloop of a normally
+      // unthreaded gtk app.
+      check = calloc(1,sizeof(*check));
+      pthread_setspecific(_sv_mutexcheck_key, (void *)check);
+      gdk_firstunder++;
+    }else{
+      if(func)
+	fprintf(stderr,"sushivision: locking error.\n"
+		"\tTrying to unlock gdk when no gdk lock held\n"
+		"\tin %s line %d.\n",
+		func,line);
+      else
+	fprintf(stderr,"sushivision: locking error.\n"
+		"\tTrying to unlock gdk when no gdk lock held.\n");
+      
+    }
+  }else{
+    check->holding_gdk--;
+    pthread_mutex_unlock(&gdk_m);
+  }
+}
+
+// dumbed down version to pass into gdk
+static void replacement_gdk_lock(void){
+  _sv_gdk_lock_i(NULL,-1);
+}
+
+static void replacement_gdk_unlock(void){
+  _sv_gdk_unlock_i(NULL,-1);
+}
+
+static mutexcheck *lockcheck(){
+  mutexcheck *check = pthread_getspecific(_sv_mutexcheck_key);
+  if(!check){
+    check = calloc(1,sizeof(*check));
+    pthread_setspecific(_sv_mutexcheck_key, (void *)check);
+  }
+  return check;
+}
+
+void _sv_panel_lock_i(const char *func, int line){
+  mutexcheck *check = lockcheck();
+  const char *m=NULL, *f=NULL;
+  int l=-1;
+  
+  if(check->holding_obj){ m="objective"; f=check->func_obj; l=check->line_obj; }
+  if(check->holding_dim){ m="dimension"; f=check->func_dim; l=check->line_dim; }
+  if(check->holding_scale){ m="scale"; f=check->func_scale; l=check->line_scale; }
+    
+  if(f)
+    fprintf(stderr,"sushivision: Out of order locking error.\n"
+	    "\tTrying to acquire panel lock in %s line %d,\n"
+	    "\t%s lock already held from %s line %d.\n",
+	    func,line,m,f,l);
+
+  pthread_mutex_lock(&panel_m);
+  check->holding_panel++;
+  check->func_panel = func;
+  check->line_panel = line;
+
+}
+
+void _sv_panel_unlock_i(const char *func, int line){
+  mutexcheck *check = pthread_getspecific(_sv_mutexcheck_key);
+  
+  if(!check || check->holding_panel<1){
+    fprintf(stderr,"sushivision: locking error.\n"
+	    "\tTrying to unlock panel when no panel lock held\n"
+	    "\tin %s line %d.\n",
+	    func,line);
+  }else{
+
+    check->holding_panel--;
+    check->func_panel = "(unknown)";
+    check->line_panel = -1;
+    pthread_mutex_unlock(&panel_m);
+
+  }
+}
+
+void _sv_objective_lock_i(const char *func, int line){
+  mutexcheck *check = lockcheck();
+  const char *m=NULL, *f=NULL;
+  int l=-1;
+  
+  if(check->holding_dim){ m="dimension"; f=check->func_dim; l=check->line_dim; }
+  if(check->holding_scale){ m="scale"; f=check->func_scale; l=check->line_scale; }
+    
+  if(f)
+    fprintf(stderr,"sushivision: Out of order locking error.\n"
+	    "\tTrying to acquire objective lock in %s line %d,\n"
+	    "\t%s lock already held from %s line %d.\n",
+	    func,line,m,f,l);
+
+  pthread_mutex_lock(&obj_m);
+  check->holding_obj++;
+  check->func_obj = func;
+  check->line_obj = line;
+
+}
+
+void _sv_objective_unlock_i(const char *func, int line){
+  mutexcheck *check = pthread_getspecific(_sv_mutexcheck_key);
+  
+  if(!check || check->holding_obj<1){
+    fprintf(stderr,"sushivision: locking error.\n"
+	    "\tTrying to unlock objective when no objective lock held\n"
+	    "\tin %s line %d.\n",
+	    func,line);
+  }else{
+
+    check->holding_obj--;
+    check->func_obj = "(unknown)";
+    check->line_obj = -1;
+    pthread_mutex_unlock(&obj_m);
+
+  }
+}
+
+void _sv_dimension_lock_i(const char *func, int line){
+  mutexcheck *check = lockcheck();
+  const char *m=NULL, *f=NULL;
+  int l=-1;
+  
+  if(check->holding_scale){ m="scale"; f=check->func_scale; l=check->line_scale; }
+    
+  if(f)
+    fprintf(stderr,"sushivision: Out of order locking error.\n"
+	    "\tTrying to acquire dimension lock in %s line %d,\n"
+	    "\t%s lock already held from %s line %d.\n",
+	    func,line,m,f,l);
+
+  pthread_mutex_lock(&dim_m);
+  check->holding_dim++;
+  check->func_dim = func;
+  check->line_dim = line;
+
+}
+
+void _sv_dimension_unlock_i(const char *func, int line){
+  mutexcheck *check = pthread_getspecific(_sv_mutexcheck_key);
+  
+  if(!check || check->holding_dim<1){
+    fprintf(stderr,"sushivision: locking error.\n"
+	    "\tTrying to unlock dimension when no dimension lock held\n"
+	    "\tin %s line %d.\n",
+	    func,line);
+  }else{
+
+    check->holding_dim--;
+    check->func_dim = "(unknown)";
+    check->line_dim = -1;
+    pthread_mutex_unlock(&dim_m);
+
+  }
+}
+
+void _sv_scale_lock_i(const char *func, int line){
+  mutexcheck *check = lockcheck();
+  
+  pthread_mutex_lock(&scale_m);
+  check->holding_scale++;
+  check->func_scale = func;
+  check->line_scale = line;
+
+}
+
+void _sv_scale_unlock_i(const char *func, int line){
+  mutexcheck *check = pthread_getspecific(_sv_mutexcheck_key);
+  
+  if(!check || check->holding_scale<1){
+    fprintf(stderr,"sushivision: locking error.\n"
+	    "\tTrying to unlock scale when no scale lock held\n"
+	    "\tin %s line %d.\n",
+	    func,line);
+  }else{
+
+    check->holding_scale--;
+    check->func_scale = "(unknown)";
+    check->line_scale = -1;
+    pthread_mutex_unlock(&scale_m);
+
+  }
+}
+
+// mutex condm is only for protecting the condvar
+static pthread_mutex_t worker_condm = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t worker_cond = PTHREAD_COND_INITIALIZER;
 sig_atomic_t _sv_exiting=0;
 static int wake_pending = 0;
 static int num_threads;
 
-int _sv_functions=0;
-sv_func_t **_sv_function_list=NULL;
 int _sv_dimensions=0;
 sv_dim_t **_sv_dimension_list=NULL;
-int _sv_objectives=0;
-sv_obj_t **_sv_objective_list=NULL;
 int _sv_panels=0;
 sv_panel_t **_sv_panel_list=NULL;
 int _sv_undo_level=0;
@@ -61,22 +328,22 @@
 pthread_key_t   _sv_obj_key;
 
 void _sv_wake_workers(){
-  pthread_mutex_lock(&m);
+  pthread_mutex_lock(&worker_condm);
   wake_pending = num_threads;
-  pthread_cond_broadcast(&mc);
-  pthread_mutex_unlock(&m);
+  pthread_cond_broadcast(&worker_cond);
+  pthread_mutex_unlock(&worker_condm);
 }
 
 void _sv_clean_exit(){
   _sv_exiting = 1;
   _sv_wake_workers();
 
-  gdk_threads_enter();
+  gdk_lock();
   if(!gtk_main_iteration_do(FALSE)) // side effect: returns true if
 				    // there are no main loops active
     gtk_main_quit();
-  gdk_threads_leave();
-
+  
+  gdk_unlock();
 }
 
 static int num_proccies(){
@@ -117,7 +384,7 @@
 	if(_sv_exiting)break;
 	
 	// pending remap work?
-	gdk_threads_enter();
+	gdk_lock();
 	if(p && p->private && p->private->realized && p->private->graph){
 	  
 	  // pending computation work?
@@ -153,21 +420,21 @@
 	     !p->private->map_active)
 	    _sv_spinner_set_idle(p->private->spinner);
 	}
-	gdk_threads_leave ();
+	gdk_unlock ();
       }
       if(flag==1)continue;
     }
     
     // nothing to do, wait
-    pthread_mutex_lock(&m);
+    pthread_mutex_lock(&worker_condm);
     if(!wake_pending)
-      pthread_cond_wait(&mc,&m);
+      pthread_cond_wait(&worker_cond,&worker_condm);
     else
       wake_pending--;
-    pthread_mutex_unlock(&m);
+    pthread_mutex_unlock(&worker_condm);
   }
   
-  pthread_mutex_unlock(&m);
+  pthread_mutex_unlock(&worker_condm);
   return 0;
 }
 
@@ -192,16 +459,16 @@
 
 static void *event_thread(void *dummy){
 
-  gdk_threads_enter();
+  gdk_lock();
   gtk_main ();
-  gdk_threads_leave();
+  gdk_unlock();
   
 // in case there's another mainloop in the main app
-  gdk_threads_enter();
+  gdk_lock();
   if(!gtk_main_iteration_do(FALSE)) // side effect: returns true if
 				    // there are no main loops active
     gtk_main_quit();
-  gdk_threads_leave();
+  gdk_unlock();
 
   return 0;
 }
@@ -209,11 +476,20 @@
 /* externally visible interface */
 int sv_init(){
   int ret=0;
+  if((ret=pthread_key_create(&_sv_mutexcheck_key,NULL)))
+    return ret;
   if((ret=pthread_key_create(&_sv_dim_key,NULL)))
-     return ret;
+    return ret;
+  if((ret=pthread_key_create(&_sv_obj_key,NULL)))
+    return ret;
+  
+  num_threads = num_proccies();
 
-  num_threads = num_proccies();
-  _gtk_mutex_fixup();
+  pthread_mutexattr_init(&gdk_ma);
+  pthread_mutexattr_settype(&gdk_ma,PTHREAD_MUTEX_RECURSIVE);
+  pthread_mutex_init(&gdk_m,&gdk_ma);
+  gdk_threads_set_lock_functions(replacement_gdk_lock,
+				 replacement_gdk_unlock);
   gtk_init (NULL,NULL);
 
   return 0;
@@ -221,9 +497,9 @@
 
 int sv_join(){
   while(!_sv_exiting){
-    pthread_mutex_lock(&m);
-    pthread_cond_wait(&mc,&m);
-    pthread_mutex_unlock(&m);
+    pthread_mutex_lock(&worker_condm);
+    pthread_cond_wait(&worker_cond,&worker_condm);
+    pthread_mutex_unlock(&worker_condm);
   }
   return 0;
 }
@@ -235,7 +511,7 @@
   gtk_rc_parse_string(gtkrc_string());
   gtk_rc_add_default_file("sushi-gtkrc");
 
-  gdk_threads_enter();
+  gdk_lock();
   _sv_realize_all();
   _gtk_button3_fixup();
   
@@ -293,9 +569,10 @@
   //signal(SIGINT,_sv_clean_exit);
   //signal(SIGSEGV,_sv_clean_exit);
 
+  gdk_unlock();
+  
   {
     pthread_t dummy;
-    gdk_threads_leave();
     return pthread_create(&dummy, NULL, &event_thread,NULL);
   }
 }

Modified: trunk/sushivision/objective.c
===================================================================
--- trunk/sushivision/objective.c	2007-09-09 22:27:05 UTC (rev 13781)
+++ trunk/sushivision/objective.c	2007-09-11 19:57:15 UTC (rev 13782)
@@ -25,22 +25,30 @@
 #include <errno.h>
 #include "internal.h"
 
-sv_obj_t *sv_obj_new(char *name,
-		     sv_func_t **function_map,
-		     int *function_output_map,
-		     char *output_type_map){
-  
-  sv_obj_t *o;
-  sv_obj_internal_t *p;
-  int i;
-  int outputs = strlen(output_type_map);
+int _sv_objectives=0;
+sv_obj_t **_sv_objective_list=NULL;
+
+static char *objective_axismap[]={
+  "X","Y","Z"
+};
+
+#define map_axes ((int)sizeof(objective_axismap)/(int)sizeof(*objective_axismap))
+
+int sv_obj_new(char *name,
+	       void(*function)(double *,double *),
+	       char *input_map,
+	       char *output_map){
+
+  sv_obj_t *o = NULL;
+  int i,j;
   int number;
   _sv_token *decl = _sv_tokenize_declparam(name);
+  _sv_tokenlist *in = NULL;
+  _sv_tokenlist *out = NULL;
   
   if(!decl){
     fprintf(stderr,"sushivision: Unable to parse objective declaration \"%s\".\n",name);
-    errno = -EINVAL;
-    return NULL;
+    goto err;
   }
 
   if(_sv_objectives == 0){
@@ -57,133 +65,82 @@
   }
   
   o = _sv_objective_list[number] = calloc(1, sizeof(**_sv_objective_list));
-  p = o->private = calloc(1,sizeof(*o->private));
+  o->name = strdup(decl->name);
+  o->legend = strdup(decl->label);
+  o->number = number;
+  o->function = function;
 
-  /* sanity check the maps */
-  for(i=0;i<outputs;i++){
-    if(!function_map[i]){
-      fprintf(stderr,"Objectve %d (\"%s\"): function %d missing.\n",
-	      number,name,i);
-      errno = -EINVAL;
-      return NULL;
+  /* parse and sanity check the maps */
+  in = _sv_tokenize_noparamlist(input_map);
+  out = _sv_tokenize_noparamlist(output_map);
+  
+  /* input dimensions */
+  if(!in){
+    fprintf(stderr,"sushivision: Unable to parse objective \"%s\" dimenension list \"%s\".\n",
+	    o->name,input_map);
+    goto err;
+  }
+      
+  o->inputs = in->n;
+  o->input_dims = calloc(in->n,sizeof(*o->input_dims));
+  for(i=0;i<in->n;i++){
+    sv_dim_t *id = sv_dim(in->list[i]->name);
+    if(!id){
+      fprintf(stderr,"sushivision: Dimension \"%s\" does not exist in declaration of objective \"%s\".\n",
+	      in->list[i]->name,o->name);
+      goto err;
     }
-    if(function_output_map[i]<0 ||
-       function_output_map[i]>=function_map[i]->outputs){
-      fprintf(stderr,"Objectve %d (\"%s\"): function %d does not have an output %d.\n",
-	      number,name,function_map[i]->number,function_output_map[i]);
-      errno = -EINVAL;
-      return NULL;
-    }
-    switch(output_type_map[i]){
-    case 'X':
-      if(p->x_func){
-	fprintf(stderr,"Objective %d: More than one X dimension specified.\n",
-		number);
-	errno = -EINVAL;
-	return NULL;
-      }
-      p->x_fout = function_output_map[i];
-      p->x_func = (sv_func_t *)function_map[i];
-      break;
+    o->input_dims[i] = id;
+  }
 
-    case 'Y':
-      if(p->y_func){
-	fprintf(stderr,"Objective %d: More than one Y dimension specified.\n",
-		number);
-	errno = -EINVAL;
-	return NULL;
-      }
-      p->y_fout = function_output_map[i];
-      p->y_func = (sv_func_t *)function_map[i];
-      break;
+  /* output axes */
+  o->outputs = out->n;
+  o->output_axes = malloc(map_axes * sizeof(*o->output_axes));
+  for(i=0;i<map_axes;i++)
+    o->output_axes[i]=-1;
 
-    case 'Z':
-      if(p->z_func){
-	fprintf(stderr,"Objective %d: More than one Z dimension specified.\n",
-		number);
-	errno = -EINVAL;
-	return NULL;
-      }
-      p->z_fout = function_output_map[i];
-      p->z_func = (sv_func_t *)function_map[i];
-      break;
+  for(i=0;i<out->n;i++){
+    char *s = out->list[i]->name;
+    if(!s || !strcasecmp(s,"*")){
+      // output unused by objective
+      // do nothing
+    }else{
+      for(j=0;j<map_axes;j++){
+	if(!strcasecmp(s,objective_axismap[j])){
 
-    case 'M':
-      if(p->m_func){
-	fprintf(stderr,"Objective %d: More than one magnitude [M] dimension specified.\n",
-		number);
-	errno = -EINVAL;
-	return NULL;
+	  if(o->output_axes[j] != -1){
+	    fprintf(stderr,"sushivision: Objective \"%s\" declares multiple %s axis outputs.\n",
+		    o->name,objective_axismap[j]);
+	    goto err;
+	  }
+	  o->output_axes[j] = i;
+	}
       }
-      p->m_fout = function_output_map[i];
-      p->m_func = (sv_func_t *)function_map[i];
-      break;
-
-    case 'E':
-      if(p->e2_func){
-	fprintf(stderr,"Objective %d: More than two error [E] dimensions specified.\n",
-		number);
-	errno = -EINVAL;
-	return NULL;
+      if(j==map_axes){
+	fprintf(stderr,"sushivision: No such output axis \"%s\" in declaration of objective \"%s\"\n",
+		s,o->name);
       }
-      if(p->e1_func){
-	p->e2_fout = function_output_map[i];
-	p->e2_func = (sv_func_t *)function_map[i];
-      }else{
-	p->e1_fout = function_output_map[i];
-	p->e1_func = (sv_func_t *)function_map[i];
-      }
-      break;
-
-    case 'P':
-      if(p->p2_func){
-	fprintf(stderr,"Objective %d: More than two phase [P] dimensions specified.\n",
-		number);
-	errno = -EINVAL;
-	return NULL;
-      }
-      if(p->p1_func){
-	p->p2_fout = function_output_map[i];
-	p->p2_func = (sv_func_t *)function_map[i];
-      }else{
-	p->p1_fout = function_output_map[i];
-	p->p1_func = (sv_func_t *)function_map[i];
-      }
-      break;
-
-    default:
-      fprintf(stderr,"Objective %d: '%c' is an usupported output type.\n",
-	      number,output_type_map[i]);
-      errno = -EINVAL;
-      return NULL;
     }
   }
 
-  o->number = number;
-  o->name = strdup(decl->name);
-  o->legend = strdup(decl->label);
-  o->output_types = strdup(output_type_map);
-  o->type = SV_OBJ_BASIC;
-  o->outputs = outputs;
-  
-  /* copy in the maps */
-  o->function_map = malloc(outputs * sizeof(*o->function_map));
-  o->output_map = malloc(outputs * sizeof(*o->output_map));
-  memcpy(o->output_map,function_output_map,outputs * sizeof(*o->output_map));
-  
-  for(i=0;i<outputs;i++)
-    o->function_map[i] = function_map[i]->number;
-  
   pthread_setspecific(_sv_obj_key, (void *)o);
+
   _sv_token_free(decl);
+  _sv_tokenlist_free(in);
+  _sv_tokenlist_free(out);
 
-  return o;
+  return 0;
+
+ err:
+  // XXXXX
+
+  return -EINVAL;
 }
 
 // XXXX need to recompute after
 // XXXX need to add scale cloning to compute to make this safe in callbacks
 int sv_obj_set_scale(sv_scale_t *scale){
-  sv_obj_t *o = sv_obj(0);
+  sv_obj_t *o = _sv_obj(0);
 
   if(o->scale)
     sv_scale_free(o->scale); // always a deep copy we own
@@ -198,7 +155,7 @@
 // XXXX need to recompute after
 // XXXX need to add scale cloning to compute to make this safe in callbacks
 int sv_obj_make_scale(char *format){
-  sv_obj_t *o = sv_obj(0);
+  sv_obj_t *o = _sv_obj(0);
   sv_scale_t *scale;
   int ret;
 
@@ -224,7 +181,7 @@
   return ret;
 }
 
-sv_obj_t *sv_obj(char *name){
+sv_obj_t *_sv_obj(char *name){
   int i;
   
   if(name == NULL || name == 0 || !strcmp(name,"")){
@@ -240,3 +197,9 @@
   }
   return NULL;
 }
+
+int sv_obj(char *name){
+  sv_obj_t *o = _sv_obj(name);
+  if(o)return 0;
+  return -EINVAL;
+}

Modified: trunk/sushivision/objective.h
===================================================================
--- trunk/sushivision/objective.h	2007-09-09 22:27:05 UTC (rev 13781)
+++ trunk/sushivision/objective.h	2007-09-11 19:57:15 UTC (rev 13782)
@@ -19,23 +19,18 @@
  * 
  */
 
-struct _sv_obj_internal {
-  sv_func_t *x_func;
-  sv_func_t *y_func;
-  sv_func_t *z_func;
-  sv_func_t *e1_func;
-  sv_func_t *e2_func;
-  sv_func_t *p1_func;
-  sv_func_t *p2_func;
-  sv_func_t *m_func;
+struct _sv_obj { 
+  int number;
+  char *name;
+  char *legend;
 
-  int x_fout;
-  int y_fout;
-  int z_fout;
-  int e1_fout;
-  int e2_fout;
-  int p1_fout;
-  int p2_fout;
-  int m_fout;
-};
+  sv_scale_t *scale;
 
+  void (*function)(double *,double *);
+  int inputs;
+  sv_dim_t **input_dims;
+  int outputs;
+  int *output_axes;
+
+  int flags;
+};

Modified: trunk/sushivision/panel-2d.c
===================================================================
--- trunk/sushivision/panel-2d.c	2007-09-09 22:27:05 UTC (rev 13781)
+++ trunk/sushivision/panel-2d.c	2007-09-11 19:57:15 UTC (rev 13782)
@@ -80,7 +80,7 @@
     }
   }
 
-  gdk_threads_enter ();
+  gdk_lock ();
   if(p->private->plot_serialno == serialno){
     for(j=0;j<p2->y_obj_num;j++){
       int *d = p2->y_map[j] + y*dw;
@@ -90,7 +90,7 @@
       
     }
   }
-  gdk_threads_leave ();
+  gdk_unlock ();
 }
 
 // call with lock
@@ -132,11 +132,6 @@
   double x;
   double y;
   double z;
-  double e1;
-  double e2;
-  double p1;
-  double p2;
-  double m;
 } compute_result;
 
 // used by the legend code. this lets us get away with having only a mapped display pane
@@ -156,7 +151,7 @@
     dim_vals[i]=dim->val;
   }
 
-  gdk_threads_leave ();
+  gdk_unlock ();
 
   dim_vals[x_d] = x;
   dim_vals[y_d] = y;
@@ -209,7 +204,7 @@
       }
     }
   }
-  gdk_threads_enter ();
+  gdk_lock ();
 
 }
 
@@ -421,7 +416,7 @@
 
     memcpy(data,in_data+ystart*dw,sizeof(data));
 
-    gdk_threads_leave();
+    gdk_unlock();
 
     unsigned char *xdelA = c->xdelA;
     unsigned char *xdelB = c->xdelB;
@@ -492,7 +487,7 @@
 
     int data[dw];
     memcpy(data,in_data+i*dw,sizeof(data));
-    gdk_threads_leave();      
+    gdk_unlock();      
 
     for(j=0;j<pw;j++){
 
@@ -506,7 +501,7 @@
     }
   }
 
-  gdk_threads_enter ();  
+  gdk_lock ();  
   if(plot_serialno != p->private->plot_serialno ||
      map_serialno != p->private->map_serialno)
     return -1;
@@ -564,7 +559,7 @@
   p2->bg_next_line++;
 
   /* gray background checks */
-  gdk_threads_leave();
+  gdk_unlock();
 
   switch(bgmode){
   case SV_BG_WHITE:
@@ -584,7 +579,7 @@
   for(j=0;j<p->objectives;j++){
     int o_ynum = p2->y_obj_from_panel[j];
     
-    gdk_threads_enter();
+    gdk_lock();
     if(plot_serialno != p->private->plot_serialno ||
        map_serialno != p->private->map_serialno) return -1;
 
@@ -596,11 +591,11 @@
       _sv_ucolor_t *rect = p2->y_planes[o_ynum] + i*pw;
       memcpy(work_pl,rect,sizeof(work_pl));
       
-      gdk_threads_leave();
+      gdk_unlock();
       for(x=0;x<pw;x++)
 	work_bg[x] = mixfunc(work_pl[x],work_bg[x]);
     }else
-      gdk_threads_leave();
+      gdk_unlock();
 
     /**** mix Z plane */
     
@@ -608,7 +603,7 @@
 
   }
 
-  gdk_threads_enter();
+  gdk_lock();
   if(plot_serialno != p->private->plot_serialno ||
      map_serialno != p->private->map_serialno) return -1;
 
@@ -1383,9 +1378,9 @@
   _sv_panel2d_update_legend(p);
   _sv_panel_clean_legend(p);
 
-  gdk_threads_leave();
+  gdk_unlock();
   _sv_plot_draw_scales(plot);
-  gdk_threads_enter();
+  gdk_lock();
 
   _sv_plot_expose_request(plot);
   return 1;
@@ -1508,9 +1503,9 @@
       _sv_panel2d_mark_map_full(p);
       _sv_panel_dirty_map(p);
 
-      gdk_threads_leave ();      
+      gdk_unlock ();      
       _sv_plot_draw_scales(plot); // this should happen outside lock
-      gdk_threads_enter ();      
+      gdk_lock ();      
     }
 
     _sv_map_set_throttle_time(p); // swallow the first 'throttled' remap which would only be a single line;
@@ -1554,12 +1549,12 @@
   }
 
   /* unlock for computation */
-  gdk_threads_leave ();
+  gdk_unlock ();
     
   dim_vals[y_d]=_sv_scalespace_value(&sy_i, y);
   _sv_panel2d_compute_line(p, serialno, dw, y, x_d, sx_i, dim_vals, &c->p2);
 
-  gdk_threads_enter ();
+  gdk_lock ();
 
   if(p->private->plot_serialno == serialno){
     p->private->plot_complete_count++;
@@ -1580,7 +1575,7 @@
   sv_panel_t *p = (sv_panel_t *)ptr;
   int i;
 
-  gdk_threads_enter ();
+  gdk_lock ();
   _sv_panel2d_mark_recompute(p);
   _sv_panel2d_compute(p,NULL); // initial scale setup
 
@@ -1591,7 +1586,7 @@
   for(i=0;i<ph;i++)
     render_checks((_sv_ucolor_t *)plot->datarect+pw*i, pw, i);
   
-  gdk_threads_leave();
+  gdk_unlock();
 }
 
 static void _sv_panel2d_undo_log(_sv_panel_undo_t *u, sv_panel_t *p){

Modified: trunk/sushivision/panel-2d.h
===================================================================
--- trunk/sushivision/panel-2d.h	2007-09-09 22:27:05 UTC (rev 13781)
+++ trunk/sushivision/panel-2d.h	2007-09-11 19:57:15 UTC (rev 13782)
@@ -19,34 +19,42 @@
  * 
  */
 
+#define PLANE_Z 1
+ 
+union {
+  _sv_planez_t z;
+} _sv_plane_t;
+
 typedef struct {
+  // common
+  int plane_type;
+  int working;
+  sv_obj_t *o;
+  _sv_plane_t *share_next;
+  _sv_plane_t *share_prev;
+  
+  // subtype 
+  float         *data;   // native data size
+  int32_t       *map;    // native data size
+  _sv_ucolor_t  *buffer; // resampled data size;
 
+  unsigned char *line_status; 
+  int            progress;
+} _sv_planez_t;
+
+typedef struct {
+
   GtkWidget *obj_table;
   GtkWidget *dim_table;
 
-  /* only run those functions used by this panel */
-  int used_functions;
-  sv_func_t **used_function_list;
-
   unsigned char *bg_todo;
   int bg_next_line;
   int bg_first_line;
   int bg_last_line;
 
-  /**** Y PLANES ******/
-  int y_obj_num;
-  int **y_map; // indirected, dw*dh
-  _sv_ucolor_t **y_planes; // indirected, dw*dh
-  unsigned char **y_planetodo; // indirected, dh
-  int partial_remap;
-
-  int y_next_plane; // which y plane to issue next render
-  int y_next_line; // incremented when a line is claimed, per plane [0-ph)
-
-  sv_obj_t **y_obj_list; // list of objectives with a y plane
-  int *y_obj_to_panel; /* maps from position in condensed list to position in full list */
-  int *y_obj_from_panel; /* maps from position in full list to position in condensed list */
-  int *y_fout_offset; 
+  int planes;
+  _sv_plane_t **plane_list;
+  int next_plane; 
   
   /* cached resampling helpers */
   int resample_serialno;
@@ -83,11 +91,9 @@
 } _sv_panel2d_t;
 
 typedef struct {
-  double *fout; // [function number * outval_number]
+  double *fout; 
+  int fout_size;
 
-  int **y_map; // [y_obj_list[i]][px]
-  int storage_width;
-
   /* cached resampling helpers; x is here becasue locking overhead
      would be prohibitive to share between threads */
   int serialno;
@@ -96,6 +102,5 @@
   int *xnumA;
   int *xnumB;
   float xscalemul;
-  
+
 } _sv_bythread_cache_2d_t;
-

Modified: trunk/sushivision/panel.c
===================================================================
--- trunk/sushivision/panel.c	2007-09-09 22:27:05 UTC (rev 13781)
+++ trunk/sushivision/panel.c	2007-09-11 19:57:15 UTC (rev 13782)
@@ -849,7 +849,7 @@
   p->objective_list = malloc(p->objectives*sizeof(*p->objective_list));
   for(i=0;i<p->objectives;i++){
     char *name = obj_tokens->list[i]->name;
-    p->objective_list[i].o = sv_obj(name);
+    p->objective_list[i].o = _sv_obj(name);
     p->objective_list[i].p = p;
   }
 

Modified: trunk/sushivision/slider.c
===================================================================
--- trunk/sushivision/slider.c	2007-09-09 22:27:05 UTC (rev 13781)
+++ trunk/sushivision/slider.c	2007-09-11 19:57:15 UTC (rev 13782)
@@ -471,17 +471,21 @@
 
 double _sv_slider_val_to_del(_sv_slider_t *s,double v){
   if(isnan(v))return NAN;
-  int j;
+  int j=s->labels-2;
   int flip = (s->neg? 1: 0);
+  double del;
   
-  for(j=0;j<s->labels;j++){
-    if(((v<=s->label_vals[j+1]) ^ flip) || (j+2)==s->labels){
-      double del=(v-s->label_vals[j])/(s->label_vals[j+1]-s->label_vals[j]);
-      return (j+del)/(s->labels-1);
-    }
+  if((v>s->label_vals[j+1]) ^ flip){
+    del=(v-s->label_vals[j])/(s->label_vals[j+1]-s->label_vals[j]);
+    return (j+del)/(s->labels-1);
+  }else{
+    j=0;
+    while(1)
+      if((v<=s->label_vals[++j]) ^ flip)break;
+    --j;
+    del=(v-s->label_vals[j])/(s->label_vals[j+1]-s->label_vals[j]);
+    return (j+del)/(s->labels-1);
   }
-
-  return NAN;
 }
 
 void _sv_slider_expose_slice(_sv_slider_t *s, int slicenum){

Deleted: trunk/sushivision/sushimacro.h
===================================================================
--- trunk/sushivision/sushimacro.h	2007-09-09 22:27:05 UTC (rev 13781)
+++ trunk/sushivision/sushimacro.h	2007-09-11 19:57:15 UTC (rev 13782)
@@ -1,144 +0,0 @@
-/*
- *
- *     sushivision copyright (C) 2006-2007 Monty <monty at xiph.org>
- *
- *  sushivision 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, or (at your option)
- *  any later version.
- *   
- *  sushivision 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 sushivision; see the file COPYING.  If not, write to the
- *  Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * 
- */
-
-#ifndef _SUSHIMACRO_
-#define _SUSHIMACRO_
-  
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "sushivision.h"
-
-static sv_instance_t *svm_instance_curr = NULL; 
-static int svm_instance_number = 0;
-
-static double *svm_scale_vals_curr = NULL;
-static int svm_scale_vsize_curr = 0;
-static char **svm_scale_labels_curr = NULL;
-static int svm_scale_lsize_curr = 0;
-      
-static sv_dim_t *svm_dim_curr = NULL;
-static unsigned svm_scale_flags_curr = 0;
-static sv_dim_t **svm_dim_list = NULL;
-static int svm_dim_listsize = 0;
-
-// helpers
-
-#define svm_scale_check(a, b, c)					\
-  ( svm_scale_vals_curr ?						\
-    (fprintf(stderr,"No scale defined for %s %d (\"%s\")\n",#a,(b),c), \
-     1 ):								\
-    (svm_scale_labels_curr  && svm_scale_vsize_curr != svm_scale_lsize_curr ? \
-     (fprintf(stderr,"Scale values and labels list size mismatch for %s %d (\"%s\")\n",#a,(b),c), \
-      1 ):								\
-     (0) ))
-
-#define svm_dim_check(f) \
-  ( !svm_dim_curr ?						\
-    (fprintf(stderr,"No dimension currently set at %s\n",#f),	\
-     1):							\
-    (0) )
-
-#define svm_dim_list_add(d) \
-  ( (svm_dim_list && svm_dim_listsize ?					\
-     (svm_dim_list = realloc(svm_dim_list, sizeof(*svm_dim_list)*(svm_dim_listsize+2))): \
-     (svm_dim_list = calloc(2, sizeof(*svm_dim_list)))),		\
-    svm_dim_list[svm_dim_listsize] = (d) ,				\
-    svm_dim_listsize++)
-
-#define svm_dim_list_clear()			\
-  ( (svm_dim_list ?				\
-     (free(svm_dim_list),			\
-      svm_dim_list = NULL) : 0),		\
-    svm_dim_listsize = 0 )
-
-// toplevel
-
-#define svm_new(name)					   \
-  ( svm_instance_curr = sv_new(svm_instance_number, name), \
-    svm_instance_number++,				   \
-    svm_instance_curr )
-
-#define svm_scale_vals(...)						\
-  svm_scale_vals_curr = (double []){__VA_ARGS__};			\
-  svm_scale_vsize_curr = (sizeof((double []){__VA_ARGS__})/sizeof(double));
-
-#define svm_scale_labels(...)						\
-  svm_scale_labels_curr = (char []){__VA_ARGS__};			\
-  svm_scale_lsize_curr = (sizeof((char *[]){__VA_ARGS__})/sizeof(char *));
-
-#define svm_scale_flags(number)			\
-  (svm_scale_flags_curr = (number))
-
-#define svm_dim(number, name)						\
-  ( svm_scale_check(dimension,number,name) ?				\
-    (svm_dim_curr = NULL ):						\
-    (svm_dim_curr = sv_dim_new(svm_instance_curr, number, name, 0),	\
-     sv_dim_make_scale(svm_dim_curr, svm_scale_vsize_curr, svm_scale_vals_curr, svm_scale_labels_curr, svm_scale_flags_curr), \
-     svm_scale_vals_curr = NULL,					\
-     svm_scale_labels_curr = NULL,					\
-     svm_scale_vsize_curr = 0,						\
-     svm_scale_lsize_curr = 0,						\
-     svm_scale_flags_curr = 0,						\
-     svm_dim_list_add(svm_dim_curr),					\
-     svm_dim_curr) )
-
-#define svm_dim_set(number) \
-  ( !svm_instance_curr ?						\
-    (fprintf(stderr,"No instance currently set while trying to retrieve dimension %d\n",(number)), \
-     svm_dim_curr = NULL ):						\
-    ( number<0 || number >= svm_instance_curr->dimensions ?		\
-      (fprintf(stderr,"Dimension %d does not exist in instance \"%s\"\n", (number), svm_instance_curr->name), \
-       svm_dim_curr = NULL) :						\
-      (svm_dim_curr = svm_instance_curr->dimension_list[(number)])) )
-
-#define svm_dim_discrete(num,den)					\
-  ( svm_dim_check(svm_dim_curr)?					\
-    1 :	sv_dim_set_discrete(svm_dim_curr,num,den))
-
-#define svm_dim_value(a,b,c)						\
-  ( svm_dim_check(svm_dim_disabled)?					\
-    (1) :								\
-    ( !isnan(a) ? sv_dim_set_value(svm_dim_curr,0,(a)) : 0,		\
-      !isnan(b) ? sv_dim_set_value(svm_dim_curr,1,(b)) : 0,		\
-      !isnan(c) ? sv_dim_set_value(svm_dim_curr,2,(c)) : 0,		\
-      (0)))
-
-#define svm_dim_list(...)						\
-  ( svm_dim_list_clear(),						\
-    svm_dim_listsize = sizeof((sv_dim_t *[]){__VA_ARGS__}) / sizeof(sv_dim_t *), \
-    svm_dim_list = calloc(svm_dim_listsize + 1, sizeof(sv_dim_t *)),	\
-    memcpy(svm_dim_list, (sv_dim_t *[]){__VA_ARGS__}, svm_dim_listsize * sizeof(sv_dim_t *)) )
-
-#define svm_obj_simple(num,name,func,map)				\
-  ( svm_func_list_clear(),						\
-    svm_func_curr = sv_func(svm_instance_curr, svm_func_curr_num, strlen(map), func, 0), \
-    svm_obj_curr = sv_obj_new(svm_obj_curr, num, name, (sv_func_t *[]){svm_func_curr}, \
-			      (int []){0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16},map,0), \
-    (svm_scale_vals_curr ?						\
-     (svm_scale_check(objective,number,name) ?				\
-      (sv_obj_make_scale(svm_obj_curr, svm_scale_vsize_curr, svm_scale_vals_curr, svm_scale_labels_curr, svm_scale_flags_curr)):\
-      (0)):0),								\
-    svm_scale_clear(),							\
-    svm_obj_curr)
-
-
-#endif

Modified: trunk/sushivision/sushivision.h
===================================================================
--- trunk/sushivision/sushivision.h	2007-09-09 22:27:05 UTC (rev 13781)
+++ trunk/sushivision/sushivision.h	2007-09-11 19:57:15 UTC (rev 13782)
@@ -25,15 +25,10 @@
 typedef struct sv_scale sv_scale_t;
 typedef struct sv_panel sv_panel_t;
 typedef struct sv_dim   sv_dim_t;
-typedef struct sv_obj   sv_obj_t;
-typedef struct sv_func  sv_func_t;
+typedef struct _sv_obj   sv_obj_t;
 typedef struct _sv_scale_internal sv_scale_internal_t;
 typedef struct _sv_dim_internal sv_dim_internal_t;
 typedef union  _sv_dim_subtype sv_dim_subtype_t;
-typedef struct _sv_func_internal sv_func_internal_t;
-typedef union  _sv_func_subtype sv_func_subtype_t;
-typedef struct _sv_obj_internal sv_obj_internal_t;
-typedef union  _sv_obj_subtype sv_obj_subtype_t;
 typedef struct _sv_panel_internal sv_panel_internal_t;
 typedef union  _sv_panel_subtype sv_panel_subtype_t;
 
@@ -110,56 +105,15 @@
 int       sv_dim_callback_value (int (*callback)(sv_dim_t *, void*),
 				 void *callback_data);
 
-/* functions *****************************************************/
+/* objectives ****************************************************/
 
-enum sv_func_type  { SV_FUNC_BASIC };
-
-struct sv_func {
-  int number;
-  enum sv_func_type type;
-  int inputs;
-  int outputs;
-  
-  void (*callback)(double *,double *);
-  unsigned flags;
-
-  sv_func_subtype_t *subtype;
-  sv_func_internal_t *private;
-};
-
-sv_func_t          *sv_func_new (int number,
-				 int out_vals,
+int                  sv_obj_new (char *decl,
 				 void (*function)(double *,double *),
-				 unsigned flags);
+				 char *input_map,
+				 char *output_map);
 
-/* objectives ****************************************************/
+int                      sv_obj (char *name);
 
-enum sv_obj_type { SV_OBJ_BASIC };
-
-struct sv_obj { 
-  int number;
-  char *name;
-  char *legend;
-  enum sv_obj_type type;
-
-  sv_scale_t *scale;
-  int outputs;
-  int *function_map;
-  int *output_map;
-  char *output_types;
-  unsigned flags;
-
-  sv_obj_subtype_t *subtype;
-  sv_obj_internal_t *private;
-};
-
-sv_obj_t            *sv_obj_new (char *decl,
-				 sv_func_t **function_map,
-				 int *function_output_map,
-				 char *output_type_map);
-
-sv_obj_t                *sv_obj (char *name);
-
 int            sv_obj_set_scale (sv_scale_t *scale);
 
 int           sv_obj_make_scale (char *format);

Modified: trunk/sushivision/tokens.c
===================================================================
--- trunk/sushivision/tokens.c	2007-09-09 22:27:05 UTC (rev 13781)
+++ trunk/sushivision/tokens.c	2007-09-11 19:57:15 UTC (rev 13782)
@@ -610,3 +610,25 @@
   return ret;
 }
 
+_sv_tokenlist *_sv_tokenize_noparamlist(char *in){
+  if(!in)return NULL;
+
+  char *l=strdup(in);
+  in=l;
+
+  int i,n = splitcount(l,',');
+  _sv_tokenlist *ret = calloc(1,sizeof(*ret));
+
+  ret->n = n;
+  ret->list = calloc(n,sizeof(*ret->list));
+
+  for(i=0;i<n;i++){
+    char *next = split(l,',');
+    ret->list[i] = _sv_tokenize_name(l);
+    l=next;
+  }
+  free(in);
+  
+  return ret;
+}
+



More information about the commits mailing list