[gnumeric] solver: turn GnmSolverParameters into an object.



commit 84e3e741a137ea29e6860d5101333ec0962021c2
Author: Morten Welinder <terra gnome org>
Date:   Fri Nov 13 11:27:08 2009 -0500

    solver: turn GnmSolverParameters into an object.

 src/sheet.c            |    4 +-
 src/tools/gnm-solver.c |  237 ++++++++++++++++++++++++++++++++++++------------
 src/tools/gnm-solver.h |   38 +++++---
 3 files changed, 207 insertions(+), 72 deletions(-)
---
diff --git a/src/sheet.c b/src/sheet.c
index f94b92b..e47706a 100644
--- a/src/sheet.c
+++ b/src/sheet.c
@@ -3966,7 +3966,7 @@ gnm_sheet_finalize (GObject *obj)
 
 	sheet_destroy (sheet);
 
-	gnm_solver_param_free (sheet->solver_parameters);
+	g_object_unref (sheet->solver_parameters);
 	scenarios_free (sheet->scenarios);
 
 	dependents_invalidate_sheet (sheet, TRUE);
@@ -5508,7 +5508,7 @@ sheet_dup (Sheet const *src)
 #warning selection is in view
 #warning freeze/thaw is in view
 
-	gnm_solver_param_free (dst->solver_parameters);
+	g_object_unref (dst->solver_parameters);
 	dst->solver_parameters = gnm_solver_param_dup (src->solver_parameters, dst);
 
 	dst->scenarios = scenarios_dup (src->scenarios, dst);
diff --git a/src/tools/gnm-solver.c b/src/tools/gnm-solver.c
index 2eb544b..96deb89 100644
--- a/src/tools/gnm-solver.c
+++ b/src/tools/gnm-solver.c
@@ -57,13 +57,36 @@ gnm_solver_status_get_type (void)
 			},
 			{ 0, NULL, NULL }
 		};
-		etype = g_enum_register_static ("GnmStatus", values);
+		etype = g_enum_register_static ("GnmSolverStatus", values);
+	}
+	return etype;
+}
+
+GType
+gnm_solver_problem_type_get_type (void)
+{
+	static GType etype = 0;
+	if (etype == 0) {
+		static GEnumValue const values[] = {
+			{ GNM_SOLVER_MINIMIZE,
+			  (char *)"GNM_SOLVER_MINIMIZE",
+			  (char *)"minimize"
+			},
+			{ GNM_SOLVER_MAXIMIZE,
+			  (char *)"GNM_SOLVER_MAXIMIZE",
+			  (char *)"maximize"
+			},
+			{ 0, NULL, NULL }
+		};
+		etype = g_enum_register_static ("GnmSolverProblemType", values);
 	}
 	return etype;
 }
 
 /* ------------------------------------------------------------------------- */
 
+static GObjectClass *gnm_solver_parent_class;
+
 GnmSolverConstraint *
 gnm_solver_constraint_new (Sheet *sheet)
 {
@@ -319,72 +342,54 @@ gnm_solver_constraint_as_str (GnmSolverConstraint const *c, Sheet *sheet)
 
 /* ------------------------------------------------------------------------- */
 
-GnmSolverParameters *
-gnm_solver_param_new (Sheet *sheet)
-{
-	GnmSolverParameters *res = g_new0 (GnmSolverParameters, 1);
-
-	dependent_managed_init (&res->target, sheet);
-	dependent_managed_init (&res->input, sheet);
-
-	res->options.model_type          = GNM_SOLVER_LP;
-	res->sheet                       = sheet;
-	res->options.assume_non_negative = TRUE;
-	res->options.algorithm           = NULL;
-	res->options.scenario_name       = g_strdup ("Optimal");
-	res->problem_type                = GNM_SOLVER_MAXIMIZE;
-	res->constraints                 = NULL;
-	res->constraints		 = NULL;
+enum {
+	SOLP_PROP_0,
+	SOLP_PROP_SHEET,
+	SOLP_PROP_PROBLEM_TYPE
+};
 
-	return res;
-}
+static GObjectClass *gnm_solver_param_parent_class;
 
-void
-gnm_solver_param_free (GnmSolverParameters *sp)
+GnmSolverParameters *
+gnm_solver_param_new (Sheet *sheet)
 {
-	dependent_managed_set_expr (&sp->target, NULL);
-	dependent_managed_set_expr (&sp->input, NULL);
-	go_slist_free_custom (sp->constraints,
-			      (GFreeFunc)gnm_solver_constraint_free);
-	g_free (sp->options.scenario_name);
-	g_free (sp);
+	return g_object_new (GNM_SOLVER_PARAMETERS_TYPE,
+			     "sheet", sheet,
+			     NULL);
 }
 
 GnmSolverParameters *
-gnm_solver_param_dup (const GnmSolverParameters *src_param, Sheet *new_sheet)
+gnm_solver_param_dup (GnmSolverParameters *src, Sheet *new_sheet)
 {
-	GnmSolverParameters *dst_param = gnm_solver_param_new (new_sheet);
-	GSList           *constraints;
-
-	dst_param->problem_type = src_param->problem_type;
-	dependent_managed_set_expr (&dst_param->target,
-				    src_param->target.texpr);
-	dependent_managed_set_expr (&dst_param->input,
-				    src_param->input.texpr);
-
-	g_free (dst_param->options.scenario_name);
-	dst_param->options = src_param->options;
-	dst_param->options.scenario_name = g_strdup (src_param->options.scenario_name);
+	GnmSolverParameters *dst = gnm_solver_param_new (new_sheet);
+	GSList *l;
+
+	dst->problem_type = src->problem_type;
+	dependent_managed_set_expr (&dst->target, src->target.texpr);
+	dependent_managed_set_expr (&dst->input, src->input.texpr);
+
+	g_free (dst->options.scenario_name);
+	dst->options = src->options;
+	dst->options.scenario_name = g_strdup (src->options.scenario_name);
 	/* Had there been any non-scalar options, we'd copy them here.  */
 
 	/* Copy the constraints */
-	for (constraints = src_param->constraints; constraints;
-	     constraints = constraints->next) {
-		GnmSolverConstraint *old = constraints->data;
-		GnmSolverConstraint *new = gnm_solver_constraint_dup (old, new_sheet);
+	for (l = src->constraints; l; l = l->next) {
+		GnmSolverConstraint *old = l->data;
+		GnmSolverConstraint *new =
+			gnm_solver_constraint_dup (old, new_sheet);
 
-		dst_param->constraints =
-		        g_slist_prepend (dst_param->constraints, new);
+		dst->constraints = g_slist_prepend (dst->constraints, new);
 	}
-	dst_param->constraints = g_slist_reverse (dst_param->constraints);
+	dst->constraints = g_slist_reverse (dst->constraints);
 
-	dst_param->n_constraints       = src_param->n_constraints;
-	dst_param->n_variables         = src_param->n_variables;
-	dst_param->n_int_constraints   = src_param->n_int_constraints;
-	dst_param->n_bool_constraints  = src_param->n_bool_constraints;
-	dst_param->n_total_constraints = src_param->n_total_constraints;
+	dst->n_constraints       = src->n_constraints;
+	dst->n_variables         = src->n_variables;
+	dst->n_int_constraints   = src->n_int_constraints;
+	dst->n_bool_constraints  = src->n_bool_constraints;
+	dst->n_total_constraints = src->n_total_constraints;
 
-	return dst_param;
+	return dst;
 }
 
 GnmValue const *
@@ -534,6 +539,115 @@ gnm_solver_param_valid (GnmSolverParameters const *sp, GError **err)
 	return TRUE;
 }
 
+static GObject *
+gnm_solver_param_constructor (GType type,
+			      guint n_construct_properties,
+			      GObjectConstructParam *construct_params)
+{
+	GObject *obj;
+	GnmSolverParameters *sp;
+
+	obj = gnm_solver_param_parent_class->constructor
+		(type, n_construct_properties, construct_params);
+	sp = GNM_SOLVER_PARAMETERS (obj);
+
+	dependent_managed_init (&sp->target, sp->sheet);
+	dependent_managed_init (&sp->input, sp->sheet);
+
+	sp->options.model_type          = GNM_SOLVER_LP;
+	sp->options.assume_non_negative = TRUE;
+	sp->options.scenario_name = g_strdup ("Optimal");
+
+	return obj;
+}
+
+static void
+gnm_solver_param_finalize (GObject *obj)
+{
+	GnmSolverParameters *sp = GNM_SOLVER_PARAMETERS (obj);
+
+	dependent_managed_set_expr (&sp->target, NULL);
+	dependent_managed_set_expr (&sp->input, NULL);
+	go_slist_free_custom (sp->constraints,
+			      (GFreeFunc)gnm_solver_constraint_free);
+	g_free (sp->options.scenario_name);
+
+	gnm_solver_param_parent_class->finalize (obj);
+}
+
+static void
+gnm_solver_param_get_property (GObject *object, guint property_id,
+			       GValue *value, GParamSpec *pspec)
+{
+	GnmSolverParameters *sp = (GnmSolverParameters *)object;
+
+	switch (property_id) {
+	case SOLP_PROP_SHEET:
+		g_value_set_object (value, sp->sheet);
+		break;
+
+	case SOLP_PROP_PROBLEM_TYPE:
+		g_value_set_enum (value, sp->problem_type);
+		break;
+
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+		break;
+	}
+}
+
+static void
+gnm_solver_param_set_property (GObject *object, guint property_id,
+			       GValue const *value, GParamSpec *pspec)
+{
+	GnmSolverParameters *sp = (GnmSolverParameters *)object;
+
+	switch (property_id) {
+	case SOLP_PROP_SHEET:
+		/* We hold no ref.  */
+		sp->sheet = g_value_get_object (value);
+		break;
+
+	case SOLP_PROP_PROBLEM_TYPE:
+		sp->problem_type = g_value_get_enum (value);
+		break;
+
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+		break;
+	}
+}
+
+static void
+gnm_solver_param_class_init (GObjectClass *object_class)
+{
+	gnm_solver_param_parent_class = g_type_class_peek_parent (object_class);
+
+	object_class->constructor = gnm_solver_param_constructor;
+	object_class->dispose = gnm_solver_param_finalize;
+	object_class->set_property = gnm_solver_param_set_property;
+	object_class->get_property = gnm_solver_param_get_property;
+
+	g_object_class_install_property (object_class, SOLP_PROP_SHEET,
+		 g_param_spec_object ("sheet", _("Sheet"),
+				      _("Sheet"),
+				      GNM_SHEET_TYPE,
+				      GSF_PARAM_STATIC |
+				      G_PARAM_CONSTRUCT_ONLY |
+				      G_PARAM_READWRITE));
+
+	g_object_class_install_property (object_class, SOLP_PROP_PROBLEM_TYPE,
+		 g_param_spec_enum ("problem-type", _("Problem Type"),
+				    _("Problem Type"),
+				    GNM_SOLVER_PROBLEM_TYPE_TYPE,
+				    GNM_SOLVER_MAXIMIZE,
+				    GSF_PARAM_STATIC |
+				    G_PARAM_READWRITE));
+}
+
+GSF_CLASS (GnmSolverParameters, gnm_solver_param,
+	   gnm_solver_param_class_init, NULL, G_TYPE_OBJECT)
+
 /* ------------------------------------------------------------------------- */
 
 enum {
@@ -571,6 +685,11 @@ gnm_solver_dispose (GObject *obj)
 		sol->result = NULL;
 	}
 
+	if (sol->params) {
+		g_object_unref (sol->params);
+		sol->params = NULL;
+	}
+
 	gnm_solver_parent_class->dispose (obj);
 }
 
@@ -586,7 +705,7 @@ gnm_solver_get_property (GObject *object, guint property_id,
 		break;
 
 	case SOL_PROP_PARAMS:
-		g_value_set_pointer (value, sol->params);
+		g_value_set_object (value, sol->params);
 		break;
 
 	case SOL_PROP_RESULT:
@@ -611,7 +730,8 @@ gnm_solver_set_property (GObject *object, guint property_id,
 		break;
 
 	case SOL_PROP_PARAMS:
-		sol->params = g_value_peek_pointer (value);
+		if (sol->params) g_object_unref (sol->params);
+		sol->params = g_value_dup_object (value);
 		break;
 
 	case SOL_PROP_RESULT:
@@ -810,11 +930,12 @@ gnm_solver_class_init (GObjectClass *object_class)
 				    G_PARAM_READWRITE));
 
 	g_object_class_install_property (object_class, SOL_PROP_PARAMS,
-		 g_param_spec_pointer ("params", _("Parameters"),
-				       _("Solver parameters"),
-				       GSF_PARAM_STATIC |
-				       G_PARAM_CONSTRUCT_ONLY |
-				       G_PARAM_READWRITE));
+		 g_param_spec_object ("params", _("Parameters"),
+				      _("Solver parameters"),
+				      GNM_SOLVER_PARAMETERS_TYPE,
+				      GSF_PARAM_STATIC |
+				      G_PARAM_CONSTRUCT_ONLY |
+				      G_PARAM_READWRITE));
 
 	g_object_class_install_property (object_class, SOL_PROP_RESULT,
 		 g_param_spec_object ("result", _("Result"),
diff --git a/src/tools/gnm-solver.h b/src/tools/gnm-solver.h
index 42be1d8..37de650 100644
--- a/src/tools/gnm-solver.h
+++ b/src/tools/gnm-solver.h
@@ -47,11 +47,13 @@ typedef enum {
 } GnmSolverModelType;
 
 
+GType gnm_solver_problem_type_get_type (void);
+#define GNM_SOLVER_PROBLEM_TYPE_TYPE (gnm_solver_problem_type_get_type ())
+
 typedef enum {
         GNM_SOLVER_MINIMIZE, GNM_SOLVER_MAXIMIZE
 } GnmSolverProblemType;
 
-
 /* -------------------------------------------------------------------------- */
 
 struct GnmSolverConstraint_ {
@@ -115,30 +117,42 @@ typedef struct {
 	gchar               *scenario_name;
 } GnmSolverOptions;
 
+#define GNM_SOLVER_PARAMETERS_TYPE   (gnm_solver_param_get_type ())
+#define GNM_SOLVER_PARAMETERS(o)     (G_TYPE_CHECK_INSTANCE_CAST ((o), GNM_SOLVER_PARAMETERS_TYPE, GnmSolverParameters))
+
 struct GnmSolverParameters_ {
-	GnmSolverProblemType  problem_type;
-	Sheet                *sheet;
-	GnmDependent          target;
-	GnmDependent          input;
-	GSList                *constraints;
+	GObject parent;
+
+	/* Default parsing sheet.  No ref held.  */
+	Sheet *sheet;
+
+	GnmSolverProblemType problem_type;
+	GnmDependent target;
+	GnmDependent input;
+	GSList *constraints;
+	GnmSolverOptions options;
+
+	/* These will not survive long.  */
 	int                   n_constraints;
 	int                   n_variables;
 	int                   n_int_constraints;
 	int                   n_bool_constraints;
 	int                   n_total_constraints;
-	GnmSolverOptions         options;
 };
 
+typedef struct {
+	GObjectClass parent_class;
+} GnmSolverParametersClass;
+
+GType gnm_solver_param_get_type (void);
+
 /* Creates a new GnmSolverParameters object. */
 GnmSolverParameters *gnm_solver_param_new (Sheet *sheet);
 
 /* Duplicate a GnmSolverParameters object. */
-GnmSolverParameters *gnm_solver_param_dup (GnmSolverParameters const *src_param,
+GnmSolverParameters *gnm_solver_param_dup (GnmSolverParameters *src_param,
 					   Sheet *new_sheet);
 
-/* Frees the memory resources in the solver parameter structure. */
-void gnm_solver_param_free (GnmSolverParameters *sp);
-
 GnmValue const *gnm_solver_param_get_input (GnmSolverParameters const *sp);
 void gnm_solver_param_set_input (GnmSolverParameters *sp, GnmValue *v);
 GSList *gnm_solver_param_get_input_cells (GnmSolverParameters const *sp);
@@ -171,7 +185,7 @@ typedef struct {
 	GObjectClass parent_class;
 } GnmSolverResultClass;
 
-GType gnm_solver_result_get_type  (void);
+GType gnm_solver_result_get_type (void);
 
 /* ------------------------------------------------------------------------- */
 /* Generic Solver class. */



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