[gnumeric] Solver: rate-limit objective function value updates of the GUI.



commit c382f3ed2d79cb426086975d8ba788c73f9ef2c8
Author: Morten Welinder <terra gnome org>
Date:   Mon May 4 16:02:53 2015 -0400

    Solver: rate-limit objective function value updates of the GUI.

 src/dialogs/ChangeLog       |    5 ++
 src/dialogs/dialog-solver.c |  111 ++++++++++++++++++++++++++++---------------
 src/dialogs/solver.ui       |    5 +-
 3 files changed, 79 insertions(+), 42 deletions(-)
---
diff --git a/src/dialogs/ChangeLog b/src/dialogs/ChangeLog
index 1fd822e..f4b8c80 100644
--- a/src/dialogs/ChangeLog
+++ b/src/dialogs/ChangeLog
@@ -1,3 +1,8 @@
+2015-05-04  Morten Welinder  <terra gnome org>
+
+       * dialog-solver.c (cb_notify_result): Rate-limit actual updates to
+       10 per second.
+
 2015-05-02  Morten Welinder  <terra gnome org>
 
        * dialog-solver.c (run_solver): Move everything except the stop
diff --git a/src/dialogs/dialog-solver.c b/src/dialogs/dialog-solver.c
index 92213ba..1cfd1a9 100644
--- a/src/dialogs/dialog-solver.c
+++ b/src/dialogs/dialog-solver.c
@@ -89,6 +89,7 @@ typedef struct {
                GtkWidget   *status_widget;
                GtkWidget   *problem_status_widget;
                GtkWidget   *objective_value_widget;
+               guint       obj_val_source;
                GtkWidget   *spinner;
                guint        in_main;
        } run;
@@ -520,6 +521,62 @@ remove_timer_source (SolverState *state)
 }
 
 static void
+remove_objective_value_source (SolverState *state)
+{
+       if (state->run.obj_val_source) {
+               g_source_remove (state->run.obj_val_source);
+               state->run.obj_val_source = 0;
+       }
+}
+
+static void
+update_obj_value (SolverState *state)
+{
+       GnmSolver *sol = state->run.solver;
+       GnmSolverResult *r = sol->result;
+       char *valtxt;
+       const char *txt;
+
+       switch (r ? r->quality : GNM_SOLVER_RESULT_NONE) {
+       default:
+       case GNM_SOLVER_RESULT_NONE:
+               txt = "";
+               break;
+
+       case GNM_SOLVER_RESULT_FEASIBLE:
+               txt = _("Feasible");
+               break;
+
+       case GNM_SOLVER_RESULT_OPTIMAL:
+               txt = _("Optimal");
+               break;
+
+       case GNM_SOLVER_RESULT_INFEASIBLE:
+               txt = _("Infeasible");
+               break;
+
+       case GNM_SOLVER_RESULT_UNBOUNDED:
+               txt = _("Unbounded");
+               break;
+       }
+       gtk_label_set_text (GTK_LABEL (state->run.problem_status_widget), txt);
+
+       if (gnm_solver_has_solution (sol)) {
+               txt = valtxt = gnm_format_value (go_format_general (),
+                                                r->value);
+       } else {
+               valtxt = NULL;
+               txt = g_strdup ("");
+       }
+
+       gtk_label_set_text (GTK_LABEL (state->run.objective_value_widget),
+                           txt);
+       g_free (valtxt);
+
+       remove_objective_value_source (state);
+}
+
+static void
 cb_notify_status (SolverState *state)
 {
        GnmSolver *sol = state->run.solver;
@@ -569,6 +626,9 @@ cb_notify_status (SolverState *state)
        gtk_widget_set_sensitive (state->solve_button, finished);
        gtk_widget_set_sensitive (state->close_button, finished);
 
+       if (state->run.obj_val_source)
+               update_obj_value (state);
+
        if (finished) {
                remove_timer_source (state);
                if (state->run.in_main)
@@ -576,50 +636,22 @@ cb_notify_status (SolverState *state)
        }
 }
 
+static gboolean
+cb_obj_val_tick (SolverState *state)
+{
+       state->run.obj_val_source = 0;
+       update_obj_value (state);
+       return FALSE;
+}
+
 static void
 cb_notify_result (SolverState *state)
 {
-       GnmSolver *sol = state->run.solver;
-       GnmSolverResult *r;
-       const char *txt;
-
-       cb_notify_status (state);
-
-       r = sol->result;
-       switch (r ? r->quality : GNM_SOLVER_RESULT_NONE) {
-       default:
-       case GNM_SOLVER_RESULT_NONE:
-               txt = "";
-               break;
-
-       case GNM_SOLVER_RESULT_FEASIBLE:
-               txt = _("Feasible");
-               break;
-
-       case GNM_SOLVER_RESULT_OPTIMAL:
-               txt = _("Optimal");
-               break;
-
-       case GNM_SOLVER_RESULT_INFEASIBLE:
-               txt = _("Infeasible");
-               break;
-
-       case GNM_SOLVER_RESULT_UNBOUNDED:
-               txt = _("Unbounded");
-               break;
-       }
-       gtk_label_set_text (GTK_LABEL (state->run.problem_status_widget), txt);
-
-       if (gnm_solver_has_solution (sol)) {
-               char *valtxt = gnm_format_value (go_format_general (),
-                                                r->value);
-               gtk_label_set_text (GTK_LABEL (state->run.objective_value_widget),
-                                   valtxt);
-               g_free (valtxt);
-       }
+       if (state->run.obj_val_source == 0)
+               state->run.obj_val_source = g_timeout_add
+                       (100, (GSourceFunc)cb_obj_val_tick, state);
 }
 
-
 static gboolean
 cb_timer_tick (SolverState *state)
 {
@@ -720,6 +752,7 @@ run_solver (SolverState *state, GnmSolverParameters *param)
                ok = gnm_solver_has_solution (sol);
        }
 
+       remove_objective_value_source (state);
        remove_timer_source (state);
 
        /* ---------------------------------------- */
diff --git a/src/dialogs/solver.ui b/src/dialogs/solver.ui
index 1fedfe8..681a09f 100644
--- a/src/dialogs/solver.ui
+++ b/src/dialogs/solver.ui
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.16.0 on Mon May  4 13:32:26 2015 -->
+<!-- Generated with glade 3.16.0 on Mon May  4 15:39:51 2015 -->
 <interface>
   <!-- interface-requires gtk+ 3.8 -->
   <object class="GtkAdjustment" id="adjustment1">
@@ -962,8 +962,7 @@
                 </child>
                 <child>
                   <object class="GtkSpinner" id="run_spinner">
-                    <property name="width_request">100</property>
-                    <property name="height_request">100</property>
+                    <property name="width_request">80</property>
                     <property name="can_focus">False</property>
                     <property name="active">True</property>
                   </object>


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