packages feed

gi-gio-hs-list-model-0.1.0.0: cbits/GiGioHsListStore.c

#include "GiGioHsListStore.h"

#define DEBUG

#ifdef DEBUG
#define WHEN_DEBUG(a) a
#else
#define WHEN_DEBUG(a)
#endif

static void     gi_gio_hs_list_store_init            (GiGioHsListStore      *store);
static void     gi_gio_hs_list_store_class_init      (GiGioHsListStoreClass *klass);
static void     gi_gio_hs_list_store_list_model_init (GListModelInterface *iface);
static void     gi_gio_hs_list_store_finalize        (GObject             *object);
static GType    gi_gio_hs_list_store_get_item_type   (GListModel          *list);
static guint    gi_gio_hs_list_store_get_n_items     (GListModel          *list);
static gpointer gi_gio_hs_list_store_get_item        (GListModel          *list,
                                                      guint               position);
static GObjectClass *parent_class = NULL;


/**
 *
 *  gi_gio_hs_list_store_get_type: here we register our new type and its
 *                                 interfaces with the type system.
 *
 **/
GType
gi_gio_hs_list_store_get_type (void)
{
  static GType gi_gio_hs_list_store_type = 0;

  if (!gi_gio_hs_list_store_type)
  {
    static const GTypeInfo gi_gio_hs_list_store_info =
    {
      sizeof (GiGioHsListStoreClass),
      NULL,              /* base_init */
      NULL,              /* base_finalize */
      (GClassInitFunc) gi_gio_hs_list_store_class_init,
      NULL,              /* class finalize */
      NULL,              /* class_data */
      sizeof (GiGioHsListStore),
      0,                 /* n_preallocs */
      (GInstanceInitFunc) gi_gio_hs_list_store_init
    };

    static const GInterfaceInfo list_model_info =
    {
      (GInterfaceInitFunc) gi_gio_hs_list_store_list_model_init,
      NULL,
      NULL
    };

    gi_gio_hs_list_store_type = g_type_register_static (G_TYPE_OBJECT, "GiGioHsListStore",
                                                        &gi_gio_hs_list_store_info,
                                                        (GTypeFlags) 0);

    g_type_add_interface_static (gi_gio_hs_list_store_type, G_TYPE_LIST_MODEL,
                                 &list_model_info);

  }

  return gi_gio_hs_list_store_type;
}


/**
 *
 *  gi_gio_hs_list_store_class_init: more boilerplate GObject/GType stuff. Init
 *                                   callback for the type system, called once
 *                                   when our new class is created.
 *
 **/
static void
gi_gio_hs_list_store_class_init (GiGioHsListStoreClass *class)
{
  WHEN_DEBUG(g_debug("calling gi_gio_hs_list_store_class_init\t\t(%p)\n", class));
  GObjectClass *object_class;

  parent_class = g_type_class_peek_parent (class);
  object_class = (GObjectClass*) class;

  object_class->finalize = gi_gio_hs_list_store_finalize;
}

/**
 *
 *  gi_gio_hs_list_store_list_model_init: init callback for the interface
 *                                        registration in
 *                                        gi_gio_hs_list_store_get_type. Here we
 *                                        override the GListModelInterface
 *                                        functions that we implement.
 *
 **/
static void
gi_gio_hs_list_store_list_model_init (GListModelInterface *iface)
{
  WHEN_DEBUG(g_debug("calling gi_gio_hs_list_store_list_model_init\t(%p)\n", iface));
  iface -> get_item_type = gi_gio_hs_list_store_get_item_type;
  iface -> get_n_items   = gi_gio_hs_list_store_get_n_items;
  iface -> get_item      = gi_gio_hs_list_store_get_item;
}

/**
 *
 *  gi_gio_hs_list_store_init: this is called everytime a new custom list object
 *                             instance is created (we do that in
 *                             gi_gio_hs_list_store_new). Initialise the list
 *                             structure's fields here.
 *
 **/
static void
gi_gio_hs_list_store_init (GiGioHsListStore *store)
{
  WHEN_DEBUG(g_debug("calling gi_gio_hs_list_store_init\t\t(%p)\n", store));

  store->stamp = g_random_int();  /* Random int to check whether an iter belongs to our model */
}


/**
 *
 *  gi_gio_hs_list_store_finalize: this is called just before a custom list is
 *                                 destroyed. Free dynamically allocated memory
 *                                 here.
 *
 **/
static void
gi_gio_hs_list_store_finalize (GObject *object)
{
  WHEN_DEBUG(g_debug("calling gi_gio_hs_list_store_finalize\t(%p)\n", object));
  GiGioHsListStore *store = (GiGioHsListStore *) object;
  g_return_if_fail(GIO_GIO_HS_IS_LIST_STORE (object));

  /* free all memory used by the store */
  hs_free_stable_ptr(store->impl);
  hs_free_stable_ptr(store->priv);

  /* must chain up - finalize parent */
  (* parent_class->finalize) (object);
}

/**
 *
 *  gi_gio_hs_list_store_get_n_items: tells the rest of the world how many items
 *                                    are in the store.
 *
 **/
static guint
gi_gio_hs_list_store_get_n_items (GListModel *list)
{
  WHEN_DEBUG(g_debug("calling gi_gio_hs_list_store_get_n_items\t(%p)\n", list));
  GiGioHsListStore *store = (GiGioHsListStore *) list;
  g_return_val_if_fail (GIO_GIO_HS_IS_LIST_STORE (list), 0);

  // TODO: Export this from haskell
  gint result = gi_gio_hs_list_store_get_n_items_impl(store->impl);
  WHEN_DEBUG(g_debug("return  gi_gio_hs_list_store_get_n_items\t=%d\n", result));
  return result;
}

/**
 *
 *  gi_gio_hs_list_store_get_item: tells the rest of the world what item exists
 *                                 at a given position in the store.
 *
 **/
static gpointer
gi_gio_hs_list_store_get_item (GListModel          *list,
                               guint               position)
{
  WHEN_DEBUG(g_debug("calling gi_gio_hs_list_store_get_item\t(%p, %d)\n", list, position));
  GiGioHsListStore *store = (GiGioHsListStore *) list;
  g_return_val_if_fail (GIO_GIO_HS_IS_LIST_STORE (list), 0);

  // TODO: Export this from haskell
  gpointer result = gi_gio_hs_list_store_get_item_impl(store->impl, position);
  WHEN_DEBUG(g_debug("return  gi_gio_hs_list_store_get_item\t=%p\n", result));
  return result;
}


/**
 *
 *  gi_gio_hs_list_store_get_item_type: tells the rest of the world which type
 *                                      of data an exported model contains
 *
 **/
static GType
gi_gio_hs_list_store_get_item_type (GListModel *list)
{
  WHEN_DEBUG(g_debug("calling gi_gio_hs_list_store_get_item_type\t(%p)\n", list));
  GiGioHsListStore *store = (GiGioHsListStore *) list;
  g_return_val_if_fail (GIO_GIO_HS_IS_LIST_STORE (list), G_TYPE_INVALID);

  // TODO: Export this from haskell
  GType result = gi_gio_hs_list_store_get_item_type_impl(store->impl);
  WHEN_DEBUG(g_debug("return  gi_gio_hs_list_store_get_item_type\t=%s\n", g_type_name(result)));
  return result;
}


/**
 *
 *  gi_gio_hs_list_store_new: Create a new custom list model which delegates to
 *                            a Haskell implementation.
 *
 **/
GiGioHsListStore *
gi_gio_hs_list_store_new (HsStablePtr impl, HsStablePtr priv)
{
  WHEN_DEBUG(g_debug("calling gi_gio_hs_list_store_new\t\t(%p)\n", impl));
  GiGioHsListStore *newstore = (GiGioHsListStore*) g_object_new (GIO_GIO_HS_TYPE_LIST_STORE, NULL);

  newstore->impl = impl;
  newstore->priv = priv;

  WHEN_DEBUG(g_debug("return  gi_gio_hs_list_store_new\t\t=%p\n", newstore));
  return newstore;
}

HsStablePtr gi_gio_hs_list_store_get_impl (GiGioHsListStore *store)
{
  g_return_val_if_fail(GIO_GIO_HS_IS_LIST_STORE(store), NULL);
  return store->impl;
}

HsStablePtr gi_gio_hs_list_store_get_priv (GiGioHsListStore *store)
{
  g_return_val_if_fail(GIO_GIO_HS_IS_LIST_STORE(store), NULL);
  return store->priv;
}

gint
gi_gio_hs_list_store_get_stamp (GiGioHsListStore *store)
{
  g_return_val_if_fail(GIO_GIO_HS_IS_LIST_STORE(store), 0);
  return store->stamp;
}

void
gi_gio_hs_list_store_increment_stamp (GiGioHsListStore *store)
{
  g_return_if_fail(GIO_GIO_HS_IS_LIST_STORE(store));
  do
    {
      store->stamp++;
    }
  while (store->stamp == 0);
}