/* 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 * * 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 #include "guppi-date-series-calc.h" #include #include #include #include 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; }