gnugo-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [gnugo-devel] view.pike enhancement


From: Arend Bayer
Subject: Re: [gnugo-devel] view.pike enhancement
Date: Sun, 18 Apr 2004 22:47:29 +0200 (CEST)

This patch revivies some of the responsiveness that got broken with my
big patch. Technically, I tried to make GtpEngine thread safe by adding
some primitive locking.

Further, it adds an option to automatically start an SGF viewer in the
"reading" section. It can e.g. automatically load the SGF trees computed
by gnugo in cgoban. Of course, for all engines running simultaneously.

So comparing the owl reading that caused an unexpected  regression result
of the CVS and of a patched version is only a few mouse clicks away.

Arend

Index: regression/view.pike
===================================================================
RCS file: /cvsroot/gnugo/gnugo/regression/view.pike,v
retrieving revision 1.7
diff -u -p -r1.7 view.pike
--- regression/view.pike        10 Apr 2004 14:56:31 -0000      1.7
+++ regression/view.pike        18 Apr 2004 21:43:22 -0000
@@ -1,7 +1,7 @@
 #!/usr/bin/env pike
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
- * This distributed with GNU Go, a go program.                      * 
+ * This program is distributed with GNU Go, a go program.           * 
  *                                                                   *
  * Copyright 2003 and 2004                                          *
  * by the Free Software Foundation.                                  *
@@ -48,17 +48,21 @@ class SimpleGtp
 {
     static object engine;
     static function crash_callback = 0;
-    function trace_callback = 0;
+    static function trace_callback;
+    Thread.Mutex gtpmutex = Thread.Mutex();
     
     Stdio.File engine_in;
     Stdio.FILE engine_out;
     Stdio.FILE engine_err;
     
-    int id_number = 1;
+    static int id_number = 1;
     
-    // Send a command to the go engine.
-    GtpResponse send_command(string s)
+    // Send a command to the go engine, and collect the traces via
+    // the call-back function t.
+    GtpResponse get_traces(string s, function t)
     {
+       Thread.MutexKey gtpmutex_key = gtpmutex->lock(1);
+       trace_callback = t;
        s = id_number + " " + s + "\n";
        id_number++;
        engine_in->write(s);
@@ -94,6 +98,12 @@ class SimpleGtp
        }
        return response;
     }
+    
+    // Send a command to the go engine.
+    GtpResponse send_command(string s)
+    {
+        return get_traces(s, 0);
+    }
 
     // Tell the program to stop playing.
     void quit()
@@ -129,6 +139,11 @@ class SimpleGtp
                                          "stderr":engine_err->pipe()]));
        thread_create(program_trace_reader);
     }
+
+    void reload()
+    {
+    }
+       
 }
 
 class Goban
@@ -501,7 +516,9 @@ class RegressionViewer
     SimpleGtp engine;
     array(string) traces;
 
+    int id;
     string windowtitle;
+    string idstring;
     GTK.Window board_window;
     GTK.Window data_window;
     GTK.ScrolledWindow scrolled_data_window;
@@ -511,36 +528,38 @@ class RegressionViewer
     GTK.Clist clist;
 
     Controller parent; //Evil. Used for callbacks.
+    GTK.Hbox my_engines_box_entry;
 
     mapping(string:array(string)) worms = ([]);
     mapping(string:array(string)) dragons = ([]);
-
-    string result;
+    static int worms_initialized = 0;
+    static int dragons_initialized = 0;
+       
+    string result = "";
     string testcase_command;
     array(string) fulltest;
+    Thread.Condition testcase_finished = Thread.Condition();
+    Thread.Mutex finished_mutex = Thread.Mutex();
 
-    function on_board_click_callback;
-
-    static void create(SimpleGtp engine_, string title,
+    static void create(SimpleGtp engine_, string title, int id_,
                       array(string) fulltest_, string testcase_command_,
-                      function callback, Controller parent_)
+                      Controller parent_)
     {
        engine = engine_;
        parent = parent_;
        fulltest = fulltest_;
         testcase_command = testcase_command_;
+       id = id_;
+       idstring = (string) (id) + ": ";
 
        load_testcase();
        werror("%s\n", send_command("showboard"));
        int boardsize = (int) send_command("query_boardsize");
         windowtitle = title;
-       on_board_click_callback = callback;
+       get_worms();
 
-       foreach (send_command("worm_stones") / "\n", string worm)
-           worms[(worm / " ")[0]] = worm / " " - ({""});
-       
        board_window = GTK.Window(GTK.WindowToplevel);
-       board_window->signal_connect("destroy", exit, 0);
+       board_window->signal_connect("destroy", close, 0);
        goban = Goban(boardsize, 600);
        goban->add_stones("WHITE", send_command("list_stones white") / " ");
        goban->add_stones("BLACK", send_command("list_stones black") / " ");
@@ -554,7 +573,7 @@ class RegressionViewer
        board_window->signal_connect_new("key_press_event",
                                         key_pressed_on_board);
        board_window->add(gtk_image);
-       board_window->set_title(windowtitle);
+       board_window->set_title(idstring + windowtitle);
        board_window->show_all();
        
        data_window = GTK.Window(GTK.WindowToplevel);
@@ -568,11 +587,9 @@ class RegressionViewer
        clist = GTK.Clist(3);
        data_window->add(scrolled_data_window);
        scrolled_data_window->add(clist);
-       data_window->set_title(windowtitle);
+       data_window->set_title(idstring + windowtitle);
        data_window->show_all();
-       
-//     thread_create(handle_testcase);
-       handle_testcase();
+
     }
 
     static void load_testcase()
@@ -586,26 +603,57 @@ class RegressionViewer
 
     static void handle_testcase()
     {
+        Thread.MutexKey key = finished_mutex->lock(1);
        traces = ({});
-       engine->trace_callback = collect_traces;
-        result = send_command(testcase_command);
-       engine->trace_callback = 0;
-
-       // Due to a bug in the examine_position caching, we can't do
-       // this before a genmove call.
-       foreach (send_command("dragon_stones") / "\n", string dragon)
-           dragons[(dragon / " ")[0]] = dragon / " " - ({""});
-
+       result = engine->get_traces(testcase_command, collect_traces)->text;
        redraw_board();
+       testcase_finished->broadcast();
+        /* Important: destruct the key before notifying controller, otherwise
+        * we deadlock when trying for the finished_mutex->lock() in
+        * the move generation markup function.
+        */
+       destruct(key);
+       parent->notify_finished_testcase();
+    }
+    
+    void start_testcase()
+    {
+       /* If the active page is s.th. else than "move generation", we want
+        * to generate this info first. If it is "move generation", we
+        * have to handle the test case first.
+        */
+       if (parent->active_page != 1) {
+           add_markup();
+           thread_create(handle_testcase);
+       }
+       else {
+           thread_create(handle_testcase());
+           thread_create(add_markup());
+       }
     }
 
-    static void collect_traces(string s)
+    void collect_traces(string s)
     {
        traces += ({s});
     }
+
+    void get_dragons()
+    {
+       foreach (send_command("dragon_stones") / "\n", string dragon)
+           dragons[(dragon / " ")[0]] = dragon / " " - ({""});
+       dragons_initialized = 1;
+    }
     
-    void add_markup(int mode)
+    void get_worms()
     {
+       foreach (send_command("worm_stones") / "\n", string worm)
+           worms[(worm / " ")[0]] = worm / " " - ({""});
+       worms_initialized = 1;
+    }
+    
+    void add_markup()
+    {
+       int mode = parent->active_page;
        goban->clear_markup();
        if (mode <= 4) {
            function add_suitable_markup = ({add_worms_and_dragons_markup,
@@ -632,9 +680,12 @@ class RegressionViewer
                                  "strongly alive":"blue",
                                  "invincible":"purple",
                                  "inessential":"orange"]);
+
        
        if (parent->dragon_status_button->get_active())
        {
+           if (!dragons_initialized)
+               get_dragons();
            foreach (dragons; string dragon; array(string) stones)
            {
                string status = get_worm_or_dragon_data("dragon", "status",
@@ -646,6 +697,8 @@ class RegressionViewer
        }
        else if (parent->dragon_safety_button->get_active())
        {
+           if (!dragons_initialized)
+               get_dragons();
            foreach (dragons; string dragon; array(string) stones)
            {
                string safety = get_worm_or_dragon_data("dragon", "safety",
@@ -657,6 +710,8 @@ class RegressionViewer
        }
        else if (parent->worm_status_button->get_active())
        {
+           if (!worms_initialized)
+               get_worms();
            foreach (worms; string worm; array(string) stones)
            {
                string attack = get_worm_or_dragon_data("worm", "attack_code",
@@ -686,6 +741,7 @@ class RegressionViewer
            && (has_prefix(testcase_command, "reg_genmove")
                || has_prefix(testcase_command, "restricted_genmove")))
        {
+           Thread.MutexKey key;
            string color = "green";
            string answers = parent->expected_result;
            if (answers[0..0] == "!") {
@@ -708,6 +764,11 @@ class RegressionViewer
 
            
            color = (testcase_command / " ")[1];
+           key = finished_mutex->lock(1);
+           if (result == "") {
+               // Testcase hasn't been handled yet.
+               testcase_finished->wait(key);
+           }
            goban->add_symbol(result, "stone", color);
        }
 
@@ -763,7 +824,7 @@ class RegressionViewer
                }
            }
            clist->columns_autosize();
-           data_window->set_title("Delta territory for "
+           data_window->set_title(idstring + "Delta territory for "
                                   + parent->delta_territory_move);
        }
     }
@@ -950,9 +1011,8 @@ class RegressionViewer
     {
        if ((parent->connection_reading_button->get_active()
             || parent->semeai_reading_button->get_active())
-           && parent->first_semeai_or_connection_vertex != "")
-           goban->add_symbol(parent->first_semeai_or_connection_vertex,
-                             "big_dot", "green");
+           && parent->first_vertex != "")
+           goban->add_symbol(parent->first_vertex, "big_dot", "green");
     }
     
     void redraw_board()
@@ -971,7 +1031,7 @@ class RegressionViewer
            clist->append(({field, value, ""}));
        }
        clist->columns_autosize();
-       data_window->set_title("Worm data for " + vertex);
+       data_window->set_title(idstring + "Worm data for " + vertex);
     }
 
     void show_dragon_data(string vertex, int part)
@@ -991,7 +1051,7 @@ class RegressionViewer
            clist->append(({field, value, ""}));
        }
        clist->columns_autosize();
-       data_window->set_title("Dragon data for " + vertex);
+       data_window->set_title(idstring + "Dragon data for " + vertex);
     }
 
     void show_move_reasons(string vertex)
@@ -1047,7 +1107,7 @@ class RegressionViewer
        }
 
        clist->columns_autosize();
-       data_window->set_title("Move reasons for " + vertex);
+       data_window->set_title(idstring + "Move reasons for " + vertex);
     }
     
     void show_eye_data(string vertex)
@@ -1079,7 +1139,7 @@ class RegressionViewer
        }
        
        clist->columns_autosize();
-       data_window->set_title(color + " eye data for " + vertex);
+       data_window->set_title(idstring + color + " eye data for " + vertex);
     }
 
    
@@ -1087,7 +1147,7 @@ class RegressionViewer
     {
 //     werror("Button: %O\n", (mapping) event);
        string vertex = goban->pixel_coord_to_vertex(event->x, event->y);
-        on_board_click_callback(vertex);
+        parent->button_pressed_on_a_board(vertex);
     }
 
     static void key_pressed_on_board(GDK.Event event)
@@ -1130,11 +1190,13 @@ class RegressionViewer
     }
 
     void do_reading(string reset_counter, string get_counter,
-                   string sgffilename,
+                   string sgffilename, string sgf_viewer_cmd,
                    string first_command, string second_command)
     {
        string result;
        send_command("clear_cache");
+       if (sizeof(parent->viewers) > 1)
+           sgffilename += "." + (string) id;
        if (sgffilename != "")
            send_command("start_sgftrace");
 
@@ -1143,7 +1205,7 @@ class RegressionViewer
        clist->append(({first_command, result,
                        "(" + send_command(get_counter) + " nodes)"}));
        
-       if (result[0..0] != "0")
+       if (result[0..0] != "0" && second_command != "")
        {
            send_command(reset_counter);
            string result = send_command(second_command);
@@ -1152,20 +1214,40 @@ class RegressionViewer
        }
        if (sgffilename != "")
            send_command("finish_sgftrace " + sgffilename);
+       if (sgf_viewer_cmd != "")
+           Process.create_process(sprintf(sgf_viewer_cmd, sgffilename)
+                                  / " ");
        clist->columns_autosize();
-       data_window->set_title("Reading result");
-     }
+       data_window->set_title(idstring + "Reading result");
+    }
+
+    void close()
+    {
+       engine->quit();
+       if (board_window)
+           board_window->destroy();
+       if (data_window)
+           data_window->destroy();
+       parent->notify_quit(this_object());
+    }
+
+    void restart()
+    {
+       werror("Sorry, unimplemented. Feel free to add it :)\n");
+    }
 }
 
 
 class Controller
 {
     array(RegressionViewer) viewers = ({});
+    static int next_engine_id = 1;
 
     string current_move_color = "";
     
     GTK.Window notebook_window;
     GTK.Notebook notebook;
+    int active_page = 0;
     
     GTK.RadioButton worm_data_button;
     GTK.RadioButton dragon_data1_button;
@@ -1202,18 +1284,19 @@ class Controller
     GTK.RadioButton white_eyes_button;
     GTK.RadioButton black_eyes_button;
     
-    GTK.RadioButton tactical_reading_button;
-    GTK.RadioButton owl_reading_button;
-    GTK.RadioButton connection_reading_button;
-    GTK.RadioButton semeai_reading_button;
-    GTK.CheckButton sgf_traces_button;
-    GTK.Entry sgf_filename_entry;
+    GTK.RadioButton tactical_reading_button, owl_reading_button,
+       owl_does_attack_button, owl_does_defend_button,
+       connection_reading_button, semeai_reading_button;
+    GTK.CheckButton sgf_traces_button, sgf_viewer_button;
+    GTK.Entry sgf_filename_entry, sgf_viewer_entry;
+    GTK.Table sgf_stuff;
     GTK.Button new_engine_button;
     GTK.Entry engine_path_entry;
+    GTK.Vbox engines_box;
     
     string delta_territory_move = "PASS";
     string move_influence_move = "PASS";
-    string first_semeai_or_connection_vertex = "";
+    string first_vertex = "";
 
     string testcase_name;
     string testcase_command;
@@ -1230,11 +1313,6 @@ class Controller
        }
        testcase_name = testcase;
 
-        viewers += ({RegressionViewer(engine_, testcase, full_testcase,
-                                        testcase_command,
-                                        button_pressed_on_a_board,
-                                        this_object())});
-
        notebook_window = GTK.Window(GTK.WindowToplevel);
        notebook = GTK.Notebook();
        notebook->set_tab_pos(GTK.POS_LEFT);
@@ -1248,7 +1326,6 @@ class Controller
        if (has_prefix(testcase_command, "reg_genmove")
            || has_prefix(testcase_command, "restricted_genmove"))
        {
-//         notebook->set_page(1);
            sscanf(testcase_command, "%*s %s", string color);
            if (lower_case(color[0..0]) == "w")
                current_move_color = "white";
@@ -1354,10 +1431,14 @@ class Controller
                                                     markup_button_pressed);
        
        
-       tactical_reading_button = GTK.RadioButton("tactical reading");
-       owl_reading_button = GTK.RadioButton("owl reading",
+       tactical_reading_button = GTK.RadioButton("attack/defend");
+       owl_reading_button = GTK.RadioButton("owl attack/defend",
                                             tactical_reading_button);
-       connection_reading_button = GTK.RadioButton("connection reading",
+       owl_does_attack_button = GTK.RadioButton("owl_does_attack",
+                                                tactical_reading_button);
+       owl_does_defend_button = GTK.RadioButton("owl_does_defend",
+                                                tactical_reading_button);
+       connection_reading_button = GTK.RadioButton("connection/disconnect",
                                                    tactical_reading_button);
        semeai_reading_button = GTK.RadioButton("semeai reading",
                                                tactical_reading_button);
@@ -1365,6 +1446,16 @@ class Controller
        sgf_filename_entry = GTK.Entry();
        sgf_filename_entry->set_text("vars.sgf");
        sgf_filename_entry->set_editable(1);
+       sgf_viewer_button = GTK.CheckButton("start sgf viewer as");
+       sgf_viewer_entry = GTK.Entry()->set_text("cgoban -edit %s")
+                          ->set_editable(1);
+       sgf_viewer_button->signal_connect("toggled", sgf_viewer_button_toggled);
+       sgf_traces_button->signal_connect("toggled", sgf_traces_button_toggled);
+       sgf_stuff = GTK.Table(2, 2, 0)
+                   ->attach_defaults(sgf_traces_button, 0, 1, 0, 1)
+                   ->attach_defaults(sgf_filename_entry, 1, 2, 0, 1)
+                   ->attach_defaults(sgf_viewer_button, 0, 1, 1, 2)
+                   ->attach_defaults(sgf_viewer_entry, 1, 2, 1, 2);
 
        engine_path_entry = GTK.Entry();
        engine_path_entry->set_text("../interface/gnugo");
@@ -1413,53 +1504,91 @@ class Controller
        notebook->append_page(GTK.Vbox(0, 0)
                              ->pack_start(tactical_reading_button, 0, 0, 0)
                              ->pack_start(owl_reading_button, 0, 0, 0)
+                             ->pack_start(owl_does_attack_button, 0, 0, 0)
+                             ->pack_start(owl_does_defend_button, 0, 0, 0)
                              ->pack_start(connection_reading_button, 0, 0, 0)
                              ->pack_start(semeai_reading_button, 0, 0, 0)
                              ->pack_start(GTK.Label(""), 0, 0, 0)
-                             ->pack_start(GTK.Hbox(0, 0)
-                                          ->pack_start(sgf_traces_button,
-                                                       0, 0, 0)
-                                          ->pack_start(sgf_filename_entry,
-                                                       0, 0, 0), 0, 0, 0),
+                             ->pack_start(sgf_stuff, 0, 0, 0),
                              GTK.Label("reading"));
-       notebook->append_page(GTK.Vbox(0, 0)
+       engines_box = GTK.Vbox(0, 0);
+       notebook->append_page(GTK.Vbox(0,0)
                              ->pack_start(engine_path_entry, 0, 0, 0)
-                             ->pack_start(new_engine_button, 0, 0, 0),
-                             GTK.Label("Engines"));
-       notebook->signal_connect_new("switch_page", add_markup);
+                             ->pack_start(new_engine_button, 0, 0, 0)
+                             ->add(GTK.Label("Running engines:"))
+                             ->pack_start(engines_box, 0, 0, 0),
+                             GTK.Label("Engines"));
+       notebook->signal_connect_new("switch_page", add_markups);
        
        notebook_window->show_all();
+
+       startViewer(engine_);
     }
 
     static void select_new_engine()
     {
        string new_engine_path = engine_path_entry->get_text();
        SimpleGtp new_engine = SimpleGtp((new_engine_path + " --quiet --mode 
gtp -w -t -d0x101840") / " ");
-       if (!new_engine)
+       if (!new_engine) {
            werror("Failed to start new engine.\n");
-       else
-           viewers += ({RegressionViewer(new_engine,
-                                         testcase_name, full_testcase,
-                                         testcase_command,
-                                         button_pressed_on_a_board,
-                                         this_object())});
+           return;
+       }
+       startViewer(new_engine);
+    }
+
+    static void startViewer(SimpleGtp new_engine)
+    {
+       RegressionViewer newViewer;
+       int id = next_engine_id++;
+       newViewer = RegressionViewer(new_engine, testcase_name, id,
+                                    full_testcase, testcase_command,
+                                    this_object());
+       viewers += ({newViewer});
+       add_engine_row(sizeof(viewers), id, newViewer);
+       notebook_window->show_all();                         
+       newViewer->start_testcase();
+    }
+
+
+    void add_engine_row(int row, int id, RegressionViewer viewer)
+    {
+       GTK.Button stop_button = GTK.Button("Stop");
+       GTK.Button restart_button = GTK.Button("Restart");
+       GTK.Hbox this_row = GTK.Hbox(0, 0)
+                           ->add(GTK.Label((string) id + ":"))
+                           ->add(stop_button)
+                           ->add(restart_button)
+                           ->show_all();
+       engines_box->add(this_row);
+       viewer->my_engines_box_entry = this_row;
+       stop_button->signal_connect("clicked", viewer->close);
+       restart_button->signal_connect("clicked", viewer->restart);
+    }
+
+    void notify_quit(RegressionViewer viewer)
+    {
+       engines_box->remove(viewer->my_engines_box_entry);
+       viewers -= ({viewer});
     }
 
     static void markup_button_pressed(mixed ... foo)
     {
-       add_markup(notebook->get_current_page());
+       add_markups(active_page);
     }
 
-    static void add_markup(int mode)
+    static void add_markups(int mode)
     {
-       viewers->add_markup(mode);
+       if (mode <= 4) {
+           active_page = mode;
+           viewers->add_markup();
+       }
     }
     
     void button_pressed_on_a_board(string vertex)
     {
        if (vertex == "")
            return;
-       if (notebook->get_current_page() == 0)
+       if (active_page == 0)
        {
            // Worms and dragons.
            if (worm_data_button->get_active())
@@ -1469,7 +1598,7 @@ class Controller
            else
                viewers->show_dragon_data(vertex, 2);
        }
-       else if (notebook->get_current_page() == 1)
+       else if (active_page == 1)
        {
            // Move generation.
            if (!delta_territory_button->get_active())
@@ -1480,12 +1609,12 @@ class Controller
                markup_button_pressed();
            }
        }
-       else if (notebook->get_current_page() == 2)
+       else if (active_page == 2)
        {
            // Eyes.
            viewers->show_eye_data(vertex);
        }
-       else if (notebook->get_current_page() == 3)
+       else if (active_page == 3)
        {
            // Influence.
            if (after_move_influence_button->get_active()
@@ -1499,18 +1628,27 @@ class Controller
                markup_button_pressed();
            }
        }
-       else if (notebook->get_current_page() == 4)
+       else if (active_page == 4)
        {
            // Reading.
            string sgffilename;
+           string sgf_viewer_cmd;
            string reset_counter, get_counter;
            
-           if (sgf_traces_button->get_active())
+           if (sgf_viewer_button->get_active()) {
                sgffilename = sgf_filename_entry->get_text();
-           else
+               sgf_viewer_cmd = sgf_viewer_entry->get_text();
+           }
+           else if (sgf_traces_button->get_active()) {
+               sgffilename = sgf_filename_entry->get_text();
+               sgf_viewer_cmd = "";
+           }
+           else {
                sgffilename = "";
+               sgf_viewer_cmd = "";
+           }
 
-           if (first_semeai_or_connection_vertex == ""
+           if (first_vertex == ""
                || tactical_reading_button->get_active()
                || owl_reading_button->get_active())
                viewers->goban->clear_markup();
@@ -1533,51 +1671,81 @@ class Controller
                    get_counter = "get_owl_node_counter";
                }
                
-               viewers->do_reading(reset_counter, get_counter, sgffilename,
+               viewers->do_reading(reset_counter, get_counter,
+                                   sgffilename, sgf_viewer_cmd,
                                    prefix + "attack " + vertex,
                                    prefix + "defend " + vertex);
            }
-           else if (connection_reading_button->get_active()
+           else if (owl_does_attack_button->get_active()
+                    || owl_does_defend_button->get_active()
+                    || connection_reading_button->get_active()
                     || semeai_reading_button->get_active())
            {
-               if (first_semeai_or_connection_vertex == "")
+               if (first_vertex == "")
                {
-                   first_semeai_or_connection_vertex = vertex;
+                   first_vertex = vertex;
                }
-               else if (first_semeai_or_connection_vertex != vertex)
+               else if (first_vertex != vertex)
                {
                    string c1, c2;
                    
-                   if (connection_reading_button->get_active())
+                   if (owl_does_attack_button->get_active()) {
+                       c1 = sprintf("owl_does_attack %s %s\n",
+                                    first_vertex, vertex);
+                       viewers->do_reading("reset_owl_node_counter",
+                                           "get_owl_node_counter",
+                                           sgffilename, sgf_viewer_cmd,
+                                           c1, "");
+                   }
+                   else if (owl_does_defend_button->get_active()) {
+                       c1 = sprintf("owl_does_defend %s %s\n",
+                                    first_vertex, vertex);
+                       viewers->do_reading("reset_owl_node_counter",
+                                           "get_owl_node_counter",
+                                           sgffilename, sgf_viewer_cmd,
+                                           c1, "");
+                   }
+                   else if (connection_reading_button->get_active())
                    {
                        c1 = sprintf("connect %s %s\n",
-                                   first_semeai_or_connection_vertex,
-                                   vertex);
+                                    first_vertex, vertex);
                        c2 = "dis" + c1;
                        viewers->do_reading("reset_connection_node_counter",
                                            "get_connection_node_counter",
-                                           sgffilename, c1, c2);
+                                           sgffilename, sgf_viewer_cmd,
+                                           c1, c2);
                    }
                    else
                    {
                        c1 = sprintf("analyze_semeai %s %s",
-                                    first_semeai_or_connection_vertex,
-                                    vertex);
+                                    first_vertex, vertex);
                        c2 = sprintf("analyze_semeai %s %s", vertex,
-                                    first_semeai_or_connection_vertex);
+                                    first_vertex);
                        // FIXME: We should use a semeai node counter rather
                        // than the owl node counter, except that it doesn't
                        // exist yet.
                        viewers->do_reading("reset_owl_node_counter",
                                            "get_owl_node_counter",
-                                           sgffilename, c1, c2);
+                                           sgffilename, sgf_viewer_cmd,
+                                           c1, c2);
                    }
-                   first_semeai_or_connection_vertex = "";
+                   first_vertex = "";
                }
            }
        }
     }
 
+    // Callback function via which the RegressionViewer tells us the
+    // engine has finished handling the testcase.
+    void notify_finished_testcase()
+    {
+       if (sizeof(viewers) == 1
+           && active_page != 1
+           && (has_prefix(testcase_command, "reg_genmove")
+               || has_prefix(testcase_command, "restricted_genmove")))
+           notebook->set_page(1);
+    }
+
     static int excerpt_testcase(string testcase)
     {
        string filename;
@@ -1629,7 +1797,18 @@ class Controller
        return 0;
     }
 
+    void sgf_traces_button_toggled()
+    {
+       if (!sgf_traces_button->get_active())
+           sgf_viewer_button->set_active(0);
+    }
     
+    void sgf_viewer_button_toggled()
+    {
+       if (sgf_viewer_button->get_active())
+           sgf_traces_button->set_active(1);
+    }
+
     void debug_callback(mixed ... args)
     {
        write("Debug callback:%O\n", args);




reply via email to

[Prev in Thread] Current Thread [Next in Thread]