/* This is -*- C -*- */
/* vim: set sw=2: */
/*
* guppi-date-series-calc-impl.c
*
* Copyright (C) 2000 EMC Capital Management, Inc.
* Copyright (C) 2001 The Free Software Foundation
*
* Developed by Jon Trowbridge <trow@gnu.org>
*
* This program 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 of the
* License, or (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
#include <config.h>
#include "guppi-date-series-calc.h"
#include <libgnome/gnome-defs.h>
#include <libgnome/gnome-config.h>
#include <libgnome/gnome-i18n.h>
#include <guppi-memory.h>
static GtkObjectClass *parent_class = NULL;
enum {
ARG_0,
ARG_USE_CACHE,
ARG_BOUNDS_FN,
ARG_VALID_FN,
ARG_GET_FN,
ARG_GET_MANY_FN,
ARG_GET_RANGE_FN,
ARG_GET_BOUNDS_FN,
ARG_USER_DATA_DESTROY_FN,
ARG_USER_DATA
};
static void
guppi_date_series_calc_get_arg (GtkObject *obj, GtkArg *arg, guint arg_id)
{
switch (arg_id) {
default:
break;
};
}
static void
guppi_date_series_calc_set_arg (GtkObject *obj, GtkArg *arg, guint arg_id)
{
GuppiDateSeriesCalc *calc = GUPPI_DATE_SERIES_CALC (obj);
gpointer ptr = GTK_VALUE_POINTER (*arg);
gboolean b;
switch (arg_id) {
case ARG_USE_CACHE:
b = GTK_VALUE_BOOL (*arg);
if (b != calc->using_cache) {
guppi_unref0 (calc->cache);
calc->hinted_cache = FALSE;
calc->using_cache = b;
}
break;
case ARG_BOUNDS_FN:
calc->bounds = (void (*) (GDate *, GDate *, gpointer)) ptr;
break;
case ARG_VALID_FN:
calc->valid = (gboolean (*) (const GDate *, gpointer)) ptr;
break;
case ARG_GET_FN:
calc->get = (double (*) (const GDate *, gpointer)) ptr;
break;
case ARG_GET_MANY_FN:
calc->get_many = (gint (*) (const GDate *, gint, double *, gpointer)) ptr;
break;
case ARG_GET_RANGE_FN:
calc->get_range =
(gint (*) (const GDate *, const GDate *, double *, double *, gint, gpointer)) ptr;
break;
case ARG_GET_BOUNDS_FN:
calc->get_bounds =
(gboolean (*) (const GDate *, const GDate *, double *, double *, gpointer)) ptr;
break;
case ARG_USER_DATA_DESTROY_FN:
calc->user_data_destroy_fn = (void (*) (gpointer)) ptr;
break;
case ARG_USER_DATA:
if (calc->user_data && calc->user_data_destroy_fn)
calc->user_data_destroy_fn (calc->user_data);
calc->user_data = ptr;
break;
default:
break;
};
}
static void
guppi_date_series_calc_finalize (GtkObject *obj)
{
GuppiDateSeriesCalc *calc = GUPPI_DATE_SERIES_CALC (obj);
if (calc->user_data && calc->user_data_destroy_fn)
calc->user_data_destroy_fn (calc->user_data);
if (calc->cache)
guppi_unref0 (calc->cache);
if (parent_class->finalize)
parent_class->finalize (obj);
}
/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
static GuppiData *
v_data_copy (GuppiData *d)
{
g_assert_not_reached ();
return NULL;
}
static gint
v_data_get_size_in_bytes (GuppiData *d)
{
return -1;
}
static void
v_di_bounds (GuppiDateIndexed *di, GDate *start, GDate *end)
{
GuppiDateSeriesCalc *calc = GUPPI_DATE_SERIES_CALC (di);
GDate sd, ed;
g_assert (calc->bounds);
calc->bounds (&sd, &ed, calc->user_data);
if (calc->using_cache && calc->cache == NULL)
calc->cache = GUPPI_DATE_SERIES (guppi_data_new ("GuppiDateSeriesCore"));
if (calc->cache && !calc->hinted_cache) {
guppi_date_indexed_bounds_hint (GUPPI_DATE_INDEXED (calc->cache),
&sd, &ed);
calc->hinted_cache = TRUE;
}
if (start) *start = sd;
if (end) *end = ed;
}
static gboolean
v_di_valid (GuppiDateIndexed *di, const GDate *dt)
{
GuppiDateSeriesCalc *calc = GUPPI_DATE_SERIES_CALC (di);
g_assert (calc->valid);
return calc->valid ((GDate *)dt, calc->user_data);
}
static double
v_ds_get (GuppiDateSeries *ser, const GDate *dt)
{
GuppiDateSeriesCalc *calc = GUPPI_DATE_SERIES_CALC (ser);
double x;
if (calc->cache
&& guppi_date_indexed_valid (GUPPI_DATE_INDEXED (calc->cache), dt))
return guppi_date_series_get (calc->cache, dt);
if (calc->using_cache && calc->cache == NULL)
calc->cache = GUPPI_DATE_SERIES (guppi_data_new ("GuppiDateSeriesCore"));
g_assert (calc->get);
x = calc->get (dt, calc->user_data);
if (calc->cache)
guppi_date_series_set (calc->cache, dt, x);
return x;
}
static gboolean
v_ds_get_many (GuppiDateSeries *ser, const GDate *dt, gint count, double *buf, gint *retval)
{
GuppiDateSeriesCalc *calc = GUPPI_DATE_SERIES_CALC (ser);
if (calc->get_many) {
gint r;
r = calc->get_many (dt, count, buf, calc->user_data);
if (retval)
*retval = r;
return TRUE;
}
return FALSE;
}
static gboolean
v_ds_get_range (GuppiDateSeries *ser, const GDate *sd, const GDate *ed,
double *tbuf, double *buf, gint bufsize, gint *retval)
{
GuppiDateSeriesCalc *calc = GUPPI_DATE_SERIES_CALC (ser);
if (calc->get_range) {
gint r;
r = calc->get_range (sd, ed, tbuf, buf, bufsize, calc->user_data);
if (retval)
*retval = r;
return TRUE;
}
return FALSE;
}
static gboolean
v_ds_get_bounds (GuppiDateSeries *ser, const GDate *sd, const GDate *ed,
double *min, double *max, gboolean *retval)
{
GuppiDateSeriesCalc *calc = GUPPI_DATE_SERIES_CALC (ser);
if (calc->get_bounds) {
gboolean r;
r = calc->get_bounds (sd, ed, min, max, calc->user_data);
if (retval)
*retval = r;
return TRUE;
}
return FALSE;
}
/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
#define add_arg(str, symb) \
gtk_object_add_arg_type("GuppiDateSeriesCalc::" str, GTK_TYPE_POINTER, GTK_ARG_WRITABLE, symb)
static void
guppi_date_series_calc_class_init (GuppiDateSeriesCalcClass *klass)
{
GtkObjectClass* object_class = (GtkObjectClass *)klass;
GuppiDataClass *data_class = GUPPI_DATA_CLASS (klass);
GuppiDateIndexedClass *di_class = GUPPI_DATE_INDEXED_CLASS (klass);
GuppiDateSeriesClass *ds_class = GUPPI_DATE_SERIES_CLASS (klass);
parent_class = gtk_type_class (GUPPI_TYPE_DATE_SERIES);
object_class->get_arg = guppi_date_series_calc_get_arg;
object_class->set_arg = guppi_date_series_calc_set_arg;
object_class->finalize = guppi_date_series_calc_finalize;
data_class->copy = v_data_copy;
data_class->get_size_in_bytes = v_data_get_size_in_bytes;
data_class->is_leaf_type = TRUE;
di_class->bounds = v_di_bounds;
di_class->valid = v_di_valid;
ds_class->get = v_ds_get;
ds_class->get_many = v_ds_get_many;
ds_class->get_range = v_ds_get_range;
ds_class->get_bounds = v_ds_get_bounds;
gtk_object_add_arg_type("GuppiDateSeriesCalc::use_cache",
GTK_TYPE_BOOL, GTK_ARG_WRITABLE, ARG_USE_CACHE);
add_arg ("bounds_fn", ARG_BOUNDS_FN);
add_arg ("valid_fn", ARG_VALID_FN);
add_arg ("get_fn", ARG_GET_FN);
add_arg ("get_many_fn", ARG_GET_MANY_FN);
add_arg ("get_range_fn", ARG_GET_RANGE_FN);
add_arg ("get_bounds_fn", ARG_GET_BOUNDS_FN);
add_arg ("user_data_destroy_fn", ARG_USER_DATA_DESTROY_FN);
add_arg ("user_data", ARG_USER_DATA);
}
static void
guppi_date_series_calc_init (GuppiDateSeriesCalc *obj)
{
}
GtkType
guppi_date_series_calc_get_type (void)
{
static GtkType guppi_date_series_calc_type = 0;
if (!guppi_date_series_calc_type) {
static const GtkTypeInfo guppi_date_series_calc_info = {
"GuppiDateSeriesCalc",
sizeof (GuppiDateSeriesCalc),
sizeof (GuppiDateSeriesCalcClass),
(GtkClassInitFunc)guppi_date_series_calc_class_init,
(GtkObjectInitFunc)guppi_date_series_calc_init,
NULL, NULL, (GtkClassInitFunc)NULL
};
guppi_date_series_calc_type = gtk_type_unique (GUPPI_TYPE_DATE_SERIES, &guppi_date_series_calc_info);
}
return guppi_date_series_calc_type;
}
syntax highlighted by Code2HTML, v. 0.9.1