## GwyInventory

GwyInventory — Ordered item inventory, indexed by both name and position.

## Synopsis

    #include <libgwyddion/gwyddion.h>

                        GwyInventoryItemType;
                        GwyInventory;
                        GwyInventoryClass;
    GwyInventory*       gwy_inventory_new                   (const GwyInventoryItemType *itype);
    GwyInventory*       gwy_inventory_new_filled            (const GwyInventoryItemType *itype,
                                                             guint nitems,
                                                             gpointer *items);
    GwyInventory*       gwy_inventory_new_from_array        (const GwyInventoryItemType *itype,
                                                             guint item_size,
                                                             guint nitems,
                                                             gconstpointer items);
    guint               gwy_inventory_get_n_items           (GwyInventory *inventory);
    gboolean            gwy_inventory_can_make_copies       (GwyInventory *inventory);
    gboolean            gwy_inventory_is_const              (GwyInventory *inventory);
    const GwyInventoryItemType* gwy_inventory_get_item_type (GwyInventory *inventory);
    gpointer            gwy_inventory_get_item              (GwyInventory *inventory,
                                                             const gchar *name);
    gpointer            gwy_inventory_get_item_or_default   (GwyInventory *inventory,
                                                             const gchar *name);
    gpointer            gwy_inventory_get_nth_item          (GwyInventory *inventory,
                                                             guint n);
    guint               gwy_inventory_get_item_position     (GwyInventory *inventory,
                                                             const gchar *name);
    void                gwy_inventory_foreach               (GwyInventory *inventory,
                                                             GHFunc function,
                                                             gpointer user_data);
    gpointer            gwy_inventory_find                  (GwyInventory *inventory,
                                                             GHRFunc predicate,
                                                             gpointer user_data);
    void                gwy_inventory_set_default_item_name (GwyInventory *inventory,
                                                             const gchar *name);
    const gchar*        gwy_inventory_get_default_item_name (GwyInventory *inventory);
    gpointer            gwy_inventory_get_default_item      (GwyInventory *inventory);
    void                gwy_inventory_item_updated          (GwyInventory *inventory,
                                                             const gchar *name);
    void                gwy_inventory_nth_item_updated      (GwyInventory *inventory,
                                                             guint n);
    void                gwy_inventory_restore_order         (GwyInventory *inventory);
    void                gwy_inventory_forget_order          (GwyInventory *inventory);
    gpointer            gwy_inventory_insert_item           (GwyInventory *inventory,
                                                             gpointer item);
    gpointer            gwy_inventory_insert_nth_item       (GwyInventory *inventory,
                                                             gpointer item,
                                                             guint n);
    gboolean            gwy_inventory_delete_item           (GwyInventory *inventory,
                                                             const gchar *name);
    gboolean            gwy_inventory_delete_nth_item       (GwyInventory *inventory,
                                                             guint n);
    gpointer            gwy_inventory_rename_item           (GwyInventory *inventory,
                                                             const gchar *name,
                                                             const gchar *newname);
    gpointer            gwy_inventory_new_item              (GwyInventory *inventory,
                                                             const gchar *name,
                                                             const gchar *newname);

## Object Hierarchy

      GObject
       +----GwyInventory

## Signals

      "default-changed"                                : Run First / No Recursion
      "item-deleted"                                   : Run First / No Recursion
      "item-inserted"                                  : Run First / No Recursion
      "item-updated"                                   : Run First / No Recursion
      "items-reordered"                                : Run First / No Recursion

## Description

GwyInventory is a uniform container that offers both hash table and array (sorted or unsorted) interfaces. Both types of read access are fast, operations that modify it may be slower. Inventory can also maintain a notion of default item.

GwyInventory can be used both as an actual container for some data, or just wrap a static array with a the same interface so the actual storage is opaque to inventory user. The former kind of inventories can be created with `gwy_inventory_new()` or `gwy_inventory_new_filled()`; constant inventory is created with `gwy_inventory_new_from_array()`. Contantess of an inventory can be tested with `gwy_inventory_is_const()`.

Possible operations with data items stored in an inventory are specified upon inventory creation with GwyInventoryItemType structure. Not all fields are mandatory, with items allowing more operations the inventory is more capable too. For example, if items offer a method to make copies, `gwy_inventory_new_item()` can be used to directly create new items in the inventory (this capability can be tested with `gwy_inventory_can_make_copies()`).

Item can have `traits', that is data that can be obtained generically. They are similar to GObject properties. Actually, if items are objects, they should simply map object properties to traits. But it is possible to define traits for simple structures too.

## Details

### GwyInventoryItemType

    typedef struct {
        GType         type;
        const gchar  *watchable_signal;
        gboolean     (*is_fixed)       (gconstpointer item);
        const gchar* (*get_name)       (gpointer item);
        gint         (*compare)        (gconstpointer item1,
                                        gconstpointer item2);
        void         (*rename)         (gpointer item,
                                        const gchar *newname);
        void         (*dismantle)      (gpointer item);
        gpointer     (*copy)           (gpointer item);
        const GType* (*get_traits)     (gint *ntraits);
        const gchar* (*get_trait_name) (gint i);
        void         (*get_trait_value)(gpointer item,
                                        gint i,
                                        GValue *value);
    } GwyInventoryItemType;

Infromation about a GwyInventory item type.

Note only one of the fields must be always defined: `get_name`. All the others give inventory (and thus inventory users) some additional powers over items. They may be set to `NULL` or 0 if particular item type does not (want to) support this operation.

The three trait methods are not used by GwyInventory itself, but allows GwyInventoryStore to generically map item properties to virtual columns of a GtkTreeModel. If items are objects, you will usually want to directly map some or all GObject properties to item traits. If they are plain C structs or something else, you can easily export their data members as virtual GtkTreeModel columns by defining traits for them.

GType `type`; | Object type, if item is object or other type with registered GType. May be zero to indicate an unregistered item type. If items are objects, inventory takes a reference on them.
const gchar *`watchable_signal`; | Item signal name to watch, used only for objects. When item emits this signal, inventory emits "item-updated" signal for it. May be `NULL` to indicate no signal should be watched, you can still emit "item-updated" with `gwy_inventory_item_updated()` or `gwy_inventory_nth_item_updated()`.
`is_fixed` () | If not `NULL` and returns `TRUE` for some item, such an item cannot be removed from inventory, fixed items can be only added. This is checked each time an attempt is made to remove an item.
`get_name` () | Returns item name (the string is owned by item and it is assumed to exist until item ceases to exist or is renamed). This function is obligatory.
`compare` () | Item comparation function for sorting. If `NULL`, inventory never attempts to keep any item order and `gwy_inventory_restore_order()` does nothing. Otherwise inventory is sorted unless sorting is (temporarily) disabled with `gwy_inventory_forget_order()` or it was created with `gwy_inventory_new_filled()` and the initial array was not sorted according to `compare`.
`rename` () | Function to rename an item. If not `NULL`, calls to `gwy_inventory_rename_item()` are possible. Note items must not be renamed by any other means than this method, because when an item is renamed and inventory does not know it, very bad things will happen and you will lose all your good karma.
`dismantle` () | Called on item before it's removed from inventory. May be `NULL`.
`copy` () | Method to create a copy of an item. If this function and `rename` are defined, calls to `gwy_inventory_new_item()` are possible. Inventory sets the copy's name immediately after creation, so it normally does not matter which name `copy` gives it.
`get_traits` () | Function to get item traits. It returns array of item trait GTypes (keeping its ownership) and if `nitems` is not `NULL`, it stores the length of returned array there.
`get_trait_name` () | Returns name of `i`-th trait (keeping ownership of the returned string). It is not obligatory, but advisable to give traits names.
`get_trait_value` () | Sets `value` to value of `i`-th trait of item.

### GwyInventory

    typedef struct _GwyInventory GwyInventory;

The GwyInventory struct contains private data only and should be accessed using the functions below.

### GwyInventoryClass

    typedef struct {
        GObjectClass parent_class;

        /* Signals */
        void (*item_inserted)(GwyInventory *inventory,
                              guint position);
        void (*item_deleted)(GwyInventory *inventory,
                             guint position);
        void (*item_updated)(GwyInventory *inventory,
                             guint position);
        void (*items_reordered)(GwyInventory *inventory,
                                const gint *new_order);
        void (*default_changed)(GwyInventory *inventory);

        void (*reserved1)(void);
        void (*reserved2)(void);
    } GwyInventoryClass;

### gwy_inventory_new ()

    GwyInventory*       gwy_inventory_new                   (const GwyInventoryItemType *itype);

Creates a new inventory.

`itype` : | Type of items the inventory will contain.
Returns : | The newly created inventory.

### gwy_inventory_new_filled ()

    GwyInventory*       gwy_inventory_new_filled            (const GwyInventoryItemType *itype,
                                                             guint nitems,
                                                             gpointer *items);

Creates a new inventory and fills it with items.

`itype` : | Type of items the inventory will contain.
`nitems` : | The number of pointers in `items`.
`items` : | Item pointers to fill the newly created inventory with.
Returns : | The newly created inventory.

### gwy_inventory_new_from_array ()

    GwyInventory*       gwy_inventory_new_from_array        (const GwyInventoryItemType *itype,
                                                             guint item_size,
                                                             guint nitems,
                                                             gconstpointer items);

Creates a new inventory from static item array.

The inventory is neither modifiable nor sortable, it simply serves as an adaptor for the array `items`.

`itype` : | Type of items the inventory will contain. Inventory keeps a copy of it, so it can be an automatic variable.
`item_size` : | Item size in bytes.
`nitems` : | The number of items in `items`.
`items` : | An array with items. It will be directly used as thus must exist through the whole lifetime of inventory.
Returns : | The newly created inventory.

### gwy_inventory_get_n_items ()

    guint               gwy_inventory_get_n_items           (GwyInventory *inventory);

Returns the number of items in an inventory.

`inventory` : | An inventory.
Returns : | The number of items.

### gwy_inventory_can_make_copies ()

    gboolean            gwy_inventory_can_make_copies       (GwyInventory *inventory);

Returns whether an inventory can create new items itself.

The prerequistie is that item type is a serializable object. It enables functions like `gwy_inventory_new_item()`.

`inventory` : | An inventory.
Returns : | `TRUE` if inventory can create new items itself.

### gwy_inventory_is_const ()

    gboolean            gwy_inventory_is_const              (GwyInventory *inventory);

Returns whether an inventory is an constant inventory.

Not only you cannot modify a constant inventory, but functions like `gwy_inventory_get_item()` may return pointers to constant memory.

`inventory` : | An inventory.
Returns : | `TRUE` if inventory is constant.

### gwy_inventory_get_item_type ()

    const GwyInventoryItemType* gwy_inventory_get_item_type (GwyInventory *inventory);

Returns the type of item an inventory holds.

`inventory` : | An inventory.
Returns : | The item type. It is owned by inventory and must not be modified or freed.

### gwy_inventory_get_item ()

    gpointer            gwy_inventory_get_item              (GwyInventory *inventory,
                                                             const gchar *name);

Looks up an item in an inventory.

`inventory` : | An inventory.
`name` : | Item name.
Returns : | Item called `name`, or `NULL` if there is no such item.

### gwy_inventory_get_item_or_default ()

    gpointer            gwy_inventory_get_item_or_default   (GwyInventory *inventory,
                                                             const gchar *name);

Looks up an item in an inventory, eventually falling back to default.

The lookup order is: item of requested name, default item (if set), any inventory item, `NULL` (can happen only when inventory is empty).

`inventory` : | An inventory.
`name` : | Item name.
Returns : | Item called `name`, or default item.

### gwy_inventory_get_nth_item ()

    gpointer            gwy_inventory_get_nth_item          (GwyInventory *inventory,
                                                             guint n);

Returns item on given position in an inventory.

`inventory` : | An inventory.
`n` : | Item position. It must be between zero and the number of items in inventory, inclusive. If it is equal to the number of items, `NULL` is returned. In other words, inventory behaves like a `NULL`-terminated array, you can simply iterate over it until `gwy_inventory_get_nth_item()` returns `NULL`.
Returns : | Item at given position.

### gwy_inventory_get_item_position ()

    guint               gwy_inventory_get_item_position     (GwyInventory *inventory,
                                                             const gchar *name);

Finds position of an item in an inventory.

`inventory` : | An inventory.
`name` : | Item name.
Returns : | Item position, or -1 if there is no such item.

### gwy_inventory_foreach ()

    void                gwy_inventory_foreach               (GwyInventory *inventory,
                                                             GHFunc function,
                                                             gpointer user_data);

Calls a function on each item of an inventory, in order.

`function`'s first argument is item position (transformed with `GUINT_TO_POINTER()`), second is item pointer, and the last is `user_data`.

`inventory` : | An inventory.
`function` : | A function to call on each item. It must not modify `inventory`.
`user_data` : | Data passed to `function`.

### gwy_inventory_find ()

    gpointer            gwy_inventory_find                  (GwyInventory *inventory,
                                                             GHRFunc predicate,
                                                             gpointer user_data);

Finds an inventory item using user-specified predicate function.

`predicate` is called for each item in `inventory` (in order) until it returns `TRUE`. Its arguments are the same as in `gwy_inventory_foreach()`.

`inventory` : | An inventory.
`predicate` : | A function testing some item property. It must not modify `inventory`.
`user_data` : | Data passed to `predicate`.
Returns : | The item for which `predicate` returned `TRUE`. If there is no such item in the inventory, `NULL` is returned.

### gwy_inventory_set_default_item_name ()

    void                gwy_inventory_set_default_item_name (GwyInventory *inventory,
                                                             const gchar *name);

Sets the default of an inventory.

Item `name` must already exist in the inventory.

`inventory` : | An inventory.
`name` : | Item name, pass `NULL` to unset default item.

### gwy_inventory_get_default_item_name ()

    const gchar*        gwy_inventory_get_default_item_name (GwyInventory *inventory);

Returns the name of the default item of an inventory.

`inventory` : | An inventory.
Returns : | The default item name, `NULL` if no default name is set. Item of this name may or may not exist in the inventory.

### gwy_inventory_get_default_item ()

    gpointer            gwy_inventory_get_default_item      (GwyInventory *inventory);

Returns the default item of an inventory.

`inventory` : | An inventory.
Returns : | The default item. If there is no default item, `NULL` is returned.

### gwy_inventory_item_updated ()

    void                gwy_inventory_item_updated          (GwyInventory *inventory,
                                                             const gchar *name);

Notifies inventory an item was updated.

This function makes sense primarily for non-object items, as object items can notify inventory via signals.

`inventory` : | An inventory.
`name` : | Item name.

### gwy_inventory_nth_item_updated ()

    void                gwy_inventory_nth_item_updated      (GwyInventory *inventory,
                                                             guint n);

Notifies inventory item on given position was updated.

This function makes sense primarily for non-object items, as object items can implement GwyWatchable interface.

`inventory` : | An inventory.
`n` : | Item position.

### gwy_inventory_restore_order ()

    void                gwy_inventory_restore_order         (GwyInventory *inventory);

Assures an inventory is sorted.

`inventory` : | An inventory.

### gwy_inventory_forget_order ()

    void                gwy_inventory_forget_order          (GwyInventory *inventory);

Forces an inventory to be unsorted.

Item positions don't change, but future `gwy_inventory_insert_item()` won't try to insert items in order.

`inventory` : | An inventory.

### gwy_inventory_insert_item ()

    gpointer            gwy_inventory_insert_item           (GwyInventory *inventory,
                                                             gpointer item);

Inserts an item into an inventory.

Item of the same name must not exist yet.

If the inventory is sorted, item is inserted to keep order. If the inventory is unsorted, item is simply added to the end.

`inventory` : | An inventory.
`item` : | An item to insert.
Returns : | `item`, for convenience.

### gwy_inventory_insert_nth_item ()

    gpointer            gwy_inventory_insert_nth_item       (GwyInventory *inventory,
                                                             gpointer item,
                                                             guint n);

Inserts an item to an explicit position in an inventory.

Item of the same name must not exist yet.

`inventory` : | An inventory.
`item` : | An item to insert.
`n` : | Position to insert `item` to.
Returns : | `item`, for convenience.

### gwy_inventory_delete_item ()

    gboolean            gwy_inventory_delete_item           (GwyInventory *inventory,
                                                             const gchar *name);

Deletes an item from an inventory.

`inventory` : | An inventory.
`name` : | Name of item to delete.
Returns : | `TRUE` if item was deleted.

### gwy_inventory_delete_nth_item ()

    gboolean            gwy_inventory_delete_nth_item       (GwyInventory *inventory,
                                                             guint n);

Deletes an item on given position from an inventory.

`inventory` : | An inventory.
`n` : | Position of `item` to delete.
Returns : | `TRUE` if item was deleted.

### gwy_inventory_rename_item ()

    gpointer            gwy_inventory_rename_item           (GwyInventory *inventory,
                                                             const gchar *name,
                                                             const gchar *newname);

Renames an inventory item.

If an item of name `newname` is already present in `inventory`, the rename will fail.

`inventory` : | An inventory.
`name` : | Name of item to rename.
`newname` : | New name of item.
Returns : | The item, for convenience.

### gwy_inventory_new_item ()

    gpointer            gwy_inventory_new_item              (GwyInventory *inventory,
                                                             const gchar *name,
                                                             const gchar *newname);

Creates a new item as a copy of existing one and inserts it to inventory.

The newly created item can be called differently than `newname` if that already exists.

`inventory` : | An inventory.
`name` : | Name of item to duplicate, may be `NULL` to use default item (the same happens when `name` does not exist).
`newname` : | Name of new item, it must not exist yet. It may be `NULL`, the new name is based on `name` then.
Returns : | The newly added item.

## Signal Details

### The `"default-changed"` signal

    void                user_function                      (GwyInventory *gwyinventory,
                                                            gpointer      user_data)         : Run First / No Recursion

The ::default-changed signal is emitted when either default inventory item name changes or the presence of such an item in the inventory changes.

`gwyinventory` : | The GwyInventory which received the signal.
`user_data` : | user data set when the signal handler was connected.

### The `"item-deleted"` signal

    void                user_function                      (GwyInventory *gwyinventory,
                                                            guint         arg1,
                                                            gpointer      user_data)         : Run First / No Recursion

The ::item-deleted signal is emitted when an item is deleted from an inventory.

`gwyinventory` : | The GwyInventory which received the signal.
`arg1` : | Position an item was deleted from.
`user_data` : | user data set when the signal handler was connected.

### The `"item-inserted"` signal

    void                user_function                      (GwyInventory *gwyinventory,
                                                            guint         arg1,
                                                            gpointer      user_data)         : Run First / No Recursion

The ::item-inserted signal is emitted when an item is inserted into an inventory.

`gwyinventory` : | The GwyInventory which received the signal.
`arg1` : | Position an item was inserted at.
`user_data` : | user data set when the signal handler was connected.

### The `"item-updated"` signal

    void                user_function                      (GwyInventory *gwyinventory,
                                                            guint         arg1,
                                                            gpointer      user_data)         : Run First / No Recursion

The ::item-updated signal is emitted when an item in an inventory is updated.

`gwyinventory` : | The GwyInventory which received the signal.
`arg1` : | Position of updated item.
`user_data` : | user data set when the signal handler was connected.

### The `"items-reordered"` signal

    void                user_function                      (GwyInventory *gwyinventory,
                                                            gpointer      arg1,
                                                            gpointer      user_data)         : Run First / No Recursion

The ::items-reordered signal is emitted when item in an inventory are reordered.

`gwyinventory` : | The GwyInventory which received the signal.
`arg1` : | New item order map as in GtkTreeModel, `arg1`[new_position] = old_position.
`user_data` : | user data set when the signal handler was connected.

## See Also

GwyContainer