## IpatchContainer

IpatchContainer — Abstract object type used for items containing other child items.

## Stability Level

Stable, unless otherwise indicated

## Synopsis

    void                (*IpatchContainerCallback)          (IpatchContainer *container,
                                                             IpatchItem *item,
                                                             gpointer user_data);
    void                (*IpatchContainerDisconnect)        (IpatchContainer *container,
                                                             IpatchItem *child,
                                                             gpointer user_data);
                        IpatchContainer;
    #define             IPATCH_CONTAINER_UNUSED_FLAG_SHIFT
    #define             IPATCH_CONTAINER_ERRMSG_INVALID_CHILD_2
    IpatchList *        ipatch_container_get_children       (IpatchContainer *container,
                                                             GType type);
    const GType *       ipatch_container_get_child_types    (IpatchContainer *container);
    const GType *       ipatch_container_get_virtual_types  (IpatchContainer *container);
    const GType *       ipatch_container_type_get_child_types
                                                            (GType container_type);
    void                ipatch_container_insert             (IpatchContainer *container,
                                                             IpatchItem *item,
                                                             int pos);
    void                ipatch_container_append             (IpatchContainer *container,
                                                             IpatchItem *item);
    #define             ipatch_container_add
    void                ipatch_container_prepend            (IpatchContainer *container,
                                                             IpatchItem *item);
    void                ipatch_container_remove             (IpatchContainer *container,
                                                             IpatchItem *item);
    void                ipatch_container_remove_all         (IpatchContainer *container);
    guint               ipatch_container_count              (IpatchContainer *container,
                                                             GType type);
    void                ipatch_container_make_unique        (IpatchContainer *container,
                                                             IpatchItem *item);
    void                ipatch_container_add_unique         (IpatchContainer *container,
                                                             IpatchItem *item);
    gboolean            ipatch_container_init_iter          (IpatchContainer *container,
                                                             IpatchIter *iter,
                                                             GType type);
    void                ipatch_container_insert_iter        (IpatchContainer *container,
                                                             IpatchItem *item,
                                                             IpatchIter *iter);
    void                ipatch_container_remove_iter        (IpatchContainer *container,
                                                             IpatchIter *iter);
    void                ipatch_container_add_notify         (IpatchContainer *container,
                                                             IpatchItem *child);
    void                ipatch_container_remove_notify      (IpatchContainer *container,
                                                             IpatchItem *child);
    guint               ipatch_container_add_connect        (IpatchContainer *container,
                                                             IpatchContainerCallback callback,
                                                             IpatchContainerDisconnect disconnect,
                                                             gpointer user_data);
    guint               ipatch_container_remove_connect     (IpatchContainer *container,
                                                             IpatchItem *child,
                                                             IpatchContainerCallback callback,
                                                             IpatchContainerDisconnect disconnect,
                                                             gpointer user_data);
    void                ipatch_container_add_disconnect     (guint handler_id);
    void                ipatch_container_add_disconnect_matched
                                                            (IpatchContainer *container,
                                                             IpatchContainerCallback callback,
                                                             gpointer user_data);
    void                ipatch_container_remove_disconnect  (guint handler_id);
    void                ipatch_container_remove_disconnect_matched
                                                            (IpatchContainer *container,
                                                             IpatchItem *child,
                                                             IpatchContainerCallback callback,
                                                             gpointer user_data);

## Object Hierarchy

      GObject
       +----IpatchItem
             +----IpatchContainer
                   +----IpatchBase
                   +----IpatchDLS2Inst
                   +----IpatchGigRegion
                   +----IpatchSF2Preset
                   +----IpatchSF2Inst
                   +----IpatchVBankInst

## Description

Objects which are derived from this abstract type can contain other items, thus forming a tree of items in an instrument file for example.

## Details

### IpatchContainerCallback ()

    void                (*IpatchContainerCallback)          (IpatchContainer *container,
                                                             IpatchItem *item,
                                                             gpointer user_data);

A function prototype callback which is called for container adds or removes (after adds, before removes).

`container` : | Container item
`item` : | Item that was added/removed to/from `container`
`user_data` : | User defined pointer assigned when callback connected

### IpatchContainerDisconnect ()

    void                (*IpatchContainerDisconnect)        (IpatchContainer *container,
                                                             IpatchItem *child,
                                                             gpointer user_data);

A function prototype which is called when a callback gets disconnected.

`container` : | Container item
`child` : | Match child item of original connect (`ipatch_container_remove_connect()` only, always NULL for `ipatch_container_add_connect()`).
`user_data` : | User defined pointer assigned when callback connected

### IpatchContainer

    typedef struct _IpatchContainer IpatchContainer;

### IPATCH_CONTAINER_UNUSED_FLAG_SHIFT

    #define IPATCH_CONTAINER_UNUSED_FLAG_SHIFT  IPATCH_ITEM_UNUSED_FLAG_SHIFT

### IPATCH_CONTAINER_ERRMSG_INVALID_CHILD_2

    #define             IPATCH_CONTAINER_ERRMSG_INVALID_CHILD_2

### ipatch_container_get_children ()

    IpatchList *        ipatch_container_get_children       (IpatchContainer *container,
                                                             GType type);

Get a list of child items from a container object. A new IpatchList is created containing all matching child items. The returned list object can be iterated over safely even in a multi-thread environment. If performance is an issue, `ipatch_container_init_iter()` can be used instead, although it requires locking of the container object.

`container` : | Container object
`type` : | GType of child items to get (will match type descendants as well)
Returns : | New object list containing all matching items (an empty list if no items matched). The caller owns a reference to the object list and removing the reference will destroy it.

### ipatch_container_get_child_types ()

    const GType *       ipatch_container_get_child_types    (IpatchContainer *container);

Get an array of child types for a container object. The number of types is the number of individual lists the container has.

`container` : | Container object
Returns : | Pointer to a zero terminated array of types. Array is static and should not be modified or freed.

### ipatch_container_get_virtual_types ()

    const GType *       ipatch_container_get_virtual_types  (IpatchContainer *container);

Get an array of virtual types for a container object. Virtual types are used to group child items in user interfaces (an example is SoundFont "Percussion Presets" which contains all presets in bank number 128). To discover what virtual container a child object is part of lookup it's "virtual-parent-type" type property (`ipatch_type_get()` or `ipatch_type_object_get()`).

`container` : | Container object
Returns : | Pointer to a zero terminated array of types or `NULL` if no virtual types for `container`. Array is static and should not be modified or freed.

### ipatch_container_type_get_child_types ()

    const GType *       ipatch_container_type_get_child_types
                                                            (GType container_type);

Get an array of child types for a container type. The number of types is the number of individual lists the container has. Like `ipatch_container_get_child_types()` but takes a container GType instead of a container object.

`container_type` : | A IpatchContainer derived type to get child types of
Returns : | Pointer to a zero terminated array of types. Array is static and should not be modified or freed.

### ipatch_container_insert ()

    void                ipatch_container_insert             (IpatchContainer *container,
                                                             IpatchItem *item,
                                                             int pos);

Inserts an item into a patch item container.

MT-NOTE: If position in list is critical the container item should be locked and `ipatch_container_insert_iter()` used instead (see other special requirements for using this function). Only inserting in the first or last position (`pos` is 0 or less than 0) is guaranteed.

`container` : | Container item to insert into
`item` : | Item to insert
`pos` : | Index position to insert `item` into (`item` type is used to determine what list to insert into). 0 = first, less than 0 = last.

### ipatch_container_append ()

    void                ipatch_container_append             (IpatchContainer *container,
                                                             IpatchItem *item);

Appends an item to a container's children.

`container` : | Container item
`item` : | Item to insert

### ipatch_container_add

    #define ipatch_container_add  ipatch_container_append

### ipatch_container_prepend ()

    void                ipatch_container_prepend            (IpatchContainer *container,
                                                             IpatchItem *item);

Prepends an item to a container's children.

`container` : | Container item
`item` : | Item to insert

### ipatch_container_remove ()

    void                ipatch_container_remove             (IpatchContainer *container,
                                                             IpatchItem *item);

Removes an `item` from `container`.

`container` : | Container item to remove from
`item` : | Item to remove from `container`

### ipatch_container_remove_all ()

    void                ipatch_container_remove_all         (IpatchContainer *container);

Removes all items from a `container` object.

`container` : | Container object

### ipatch_container_count ()

    guint               ipatch_container_count              (IpatchContainer *container,
                                                             GType type);

Counts children of a specific `type` (or derived thereof) in a `container` object.

`container` : | Container object to count children of
`type` : | Type of children to count
Returns : | Count of children of `type` in `container`.

### ipatch_container_make_unique ()

    void                ipatch_container_make_unique        (IpatchContainer *container,
                                                             IpatchItem *item);

Ensures an `item`'s duplicate sensitive properties are unique among items of the same type in `container`. The item need not be a child of `container`, but can be. The initial values of the duplicate sensitive properties are used if already unique, otherwise they are modified (name strings have numbers appended to them, unused MIDI locale is found, etc).

`container` : | Patch item container
`item` : | An item of a type that can be added to `container` (but not necessarily parented to `container`).

### ipatch_container_add_unique ()

    void                ipatch_container_add_unique         (IpatchContainer *container,
                                                             IpatchItem *item);

Adds a patch item to a container and ensures that the item's duplicate sensitive properties are unique (see `ipatch_container_make_unique()`).

`container` : | Container to add item to
`item` : | Item to add

### ipatch_container_init_iter ()

    gboolean            ipatch_container_init_iter          (IpatchContainer *container,
                                                             IpatchIter *iter,
                                                             GType type);

Initialize an iterator structure to a child list of the specified `type` in a `container` object.

MT-NOTE: The `container` must be locked, or single thread access ensured, for the duration of this call and iteration of `iter` as the `container` object's lists are used directly. The iterator related functions are meant to be used for latency critical operations, and they should try and minimize the locking duration.

`container` : | Container object
`iter` : | Iterator structure to initialize
`type` : | Container child type list to initialize `iter` to
Returns : | `TRUE` on success, `FALSE` otherwise in which case the contents of `iter` are undefined.

### ipatch_container_insert_iter ()

    void                ipatch_container_insert_iter        (IpatchContainer *container,
                                                             IpatchItem *item,
                                                             IpatchIter *iter);

This function should not normally be used. It is provided to allow for custom high performance functions involving container adds. If used, certain precautions and requirements must be followed.

Insert a patch `item` into a `container` after the position marked by `iter`. No checking is done to see if child `item` is actually a valid type in `container`, this is left up to the caller for added performance. Also left up to the caller is a call to `ipatch_container_add_notify()` to notify that the item has been added (should be called after this function and outside of `container` lock). It is not necessary to notify if hooks are not enabled for `container` or caller doesn't care.

MT-NOTE: The `container` object should be write locked, or single thread access ensured, for the duration of this call and prior iterator functions.

`container` : | Container object
`item` : | Patch item to insert
`iter` : | Iterator marking position to insert after (`NULL` position to prepend). Iterator is advanced after insert to point to new inserted item. Note that this makes appending multiple items rather fast.

### ipatch_container_remove_iter ()

    void                ipatch_container_remove_iter        (IpatchContainer *container,
                                                             IpatchIter *iter);

This function should not normally be used. It is provided to allow for custom high performance functions involving container removes. If used, certain precautions and requirements must be followed.

Removes an item from a `container` object. The item is specified by the current position in `iter`. It is left up to the caller to call `ipatch_container_remove_notify()` (should be called before this function and out of `container` lock) to notify that the item will be removed. It is not necessary to notify if hooks are not enabled for `container` or caller doesn't care.

MT-NOTE: The `container` object should be write locked, or single thread access ensured, for the duration of this call and prior iterator functions.

`container` : | Container object
`iter` : | Iterator marking item to remove

### ipatch_container_add_notify ()

    void                ipatch_container_add_notify         (IpatchContainer *container,
                                                             IpatchItem *child);

Notify that a child add has occurred to an IpatchContainer object. Should be called after the add has occurred. This function is normally not needed except when using `ipatch_container_insert_iter()`.

`container` : | Container item for which an item add occurred
`child` : | Child which was added

### ipatch_container_remove_notify ()

    void                ipatch_container_remove_notify      (IpatchContainer *container,
                                                             IpatchItem *child);

Notify that a container remove will occur to an IpatchContainer object. Should be called before the remove occurs. This function is normally not needed, except when using `ipatch_container_remove_iter()`.

`container` : | Container item for which a remove will occur
`child` : | Child which will be removed

### ipatch_container_add_connect ()

    guint               ipatch_container_add_connect        (IpatchContainer *container,
                                                             IpatchContainerCallback callback,
                                                             IpatchContainerDisconnect disconnect,
                                                             gpointer user_data);

Adds a callback which gets called when a container item add operation occurs and the container matches `container`. When `container` is `NULL`, `callback` will be called for every container add operation.

`container` : | Container to match (`NULL` for wildcard)
`callback` : | Callback function to call on match
`disconnect` : | Function to call when callback is disconnected or `NULL`
`user_data` : | User defined data pointer to pass to `callback` and `disconnect`
Returns : | Handler ID which can be used to disconnect the callback or 0 on error (only occurs on invalid function parameters).

### ipatch_container_remove_connect ()

    guint               ipatch_container_remove_connect     (IpatchContainer *container,
                                                             IpatchItem *child,
                                                             IpatchContainerCallback callback,
                                                             IpatchContainerDisconnect disconnect,
                                                             gpointer user_data);

Adds a callback which gets called when a container item remove operation occurs and the container matches `container` and child item matches `child`. The `container` and/or `child` parameters can be `NULL` in which case they are wildcard. If both are `NULL` then `callback` will be called for every container remove operation. Note that specifying only `child` or both `container` and `child` is the same, since a child belongs to only one container.

`container` : | Container to match (`NULL` for wildcard)
`child` : | Child item to match (`NULL` for wildcard)
`callback` : | Callback function to call on match
`disconnect` : | Function to call when callback is disconnected or `NULL`
`user_data` : | User defined data pointer to pass to `callback` and `disconnect`
Returns : | Handler ID which can be used to disconnect the callback or 0 on error (only occurs on invalid function parameters).

### ipatch_container_add_disconnect ()

    void                ipatch_container_add_disconnect     (guint handler_id);

Disconnects a container add callback previously connected with `ipatch_container_add_connect()` by handler ID. The `ipatch_container_add_disconnect_matched()` function can be used instead to disconnect by original callback criteria and is actually faster.

`handler_id` : | ID of callback handler

### ipatch_container_add_disconnect_matched ()

    void                ipatch_container_add_disconnect_matched
                                                            (IpatchContainer *container,
                                                             IpatchContainerCallback callback,
                                                             gpointer user_data);

Disconnects a container add callback previously connected with `ipatch_container_add_connect()` by match criteria.

`container` : | Container to match
`callback` : | Callback function to match
`user_data` : | User data to match

### ipatch_container_remove_disconnect ()

    void                ipatch_container_remove_disconnect  (guint handler_id);

Disconnects a container remove callback previously connected with `ipatch_container_remove_connect()` by handler ID. The `ipatch_container_remove_disconnect_matched()` function can be used instead to disconnect by original callback criteria and is actually faster.

`handler_id` : | ID of callback handler

### ipatch_container_remove_disconnect_matched ()

    void                ipatch_container_remove_disconnect_matched
                                                            (IpatchContainer *container,
                                                             IpatchItem *child,
                                                             IpatchContainerCallback callback,
                                                             gpointer user_data);

Disconnects a handler previously connected with `ipatch_container_remove_connect()` by match criteria.

`container` : | Container to match
`child` : | Child item to match
`callback` : | Callback function to match
`user_data` : | User data to match