## CamelObject CamelObject |

## Synopsis

    #define             CAMEL_OBJECT_TRACK_INSTANCES
    typedef             CamelType;
                        CamelObject;
    #define             CAMEL_CHECK_CAST                    (obj, ctype, ptype)
    #define             CAMEL_CHECK_CLASS_CAST              (klass, ctype, ptype)
    #define             CAMEL_CHECK_TYPE                    (obj, ctype)
    #define             CAMEL_CHECK_CLASS_TYPE              (klass, ctype)
    extern              CamelType camel_object_type;
    #define             CAMEL_OBJECT_TYPE
    #define             CAMEL_OBJECT_GET_TYPE               (o)
    typedef             CamelObjectHookID;
                        CamelObjectMeta;
    extern              CamelType camel_interface_type;
    #define             CAMEL_INTERFACE_TYPE
                        CamelInterface;
    void                (*CamelObjectClassInitFunc)         (CamelObjectClass *);
    void                (*CamelObjectClassFinalizeFunc)     (CamelObjectClass *);
    void                (*CamelObjectInitFunc)              (CamelObject *,
                                                             CamelObjectClass *);
    void                (*CamelObjectFinalizeFunc)          (CamelObject *);
    gboolean            (*CamelObjectEventPrepFunc)         (CamelObject *,
                                                             gpointer );
    void                (*CamelObjectEventHookFunc)         (CamelObject *,
                                                             gpointer ,
                                                             gpointer );
    #define             CAMEL_INVALID_TYPE
    enum                CamelObjectFlags;
    void                camel_type_init                     (void);
    CamelType           camel_type_register                 (CamelType parent,
                                                             const char *name,
                                                             size_t instance_size,
                                                             size_t classfuncs_size,
                                                             CamelObjectClassInitFunc class_init,
                                                             CamelObjectClassFinalizeFunc class_finalize,
                                                             CamelObjectInitFunc instance_init,
                                                             CamelObjectFinalizeFunc instance_finalize);
    CamelType           camel_interface_register            (CamelType parent,
                                                             const char *name,
                                                             size_t classfuncs_size,
                                                             CamelObjectClassInitFunc class_init,
                                                             CamelObjectClassFinalizeFunc class_finalize);
    #define             camel_type_get_global_classfuncs    (x)
    const char*         camel_type_to_name                  (CamelType type);
    CamelType           camel_name_to_type                  (const char *name);
    void                camel_object_class_add_event        (CamelObjectClass *klass,
                                                             const char *name,
                                                             CamelObjectEventPrepFunc prep);
    void                camel_object_class_add_interface    (CamelObjectClass *klass,
                                                             CamelType itype);
    void                camel_object_class_dump_tree        (CamelType root);
    CamelObject*        camel_object_cast                   (CamelObject *obj,
                                                             CamelType ctype);
    gboolean            camel_object_is                     (CamelObject *obj,
                                                             CamelType ctype);
    CamelObjectClass*   camel_object_class_cast             (CamelObjectClass *klass,
                                                             CamelType ctype);
    gboolean            camel_object_class_is               (CamelObjectClass *klass,
                                                             CamelType ctype);
    CamelObjectClass*   camel_interface_cast                (CamelObjectClass *klass,
                                                             CamelType ctype);
    gboolean            camel_interface_is                  (CamelObjectClass *k,
                                                             CamelType ctype);
    CamelObject*        camel_object_new                    (CamelType type);
    CamelObject*        camel_object_new_name               (const char *name);
    void                camel_object_ref                    (void *);
    void                camel_object_unref                  (void *);
    CamelObjectHookID   camel_object_hook_event             (void *obj,
                                                             const char *name,
                                                             CamelObjectEventHookFunc hook,
                                                             void *data);
    void                camel_object_remove_event           (void *obj,
                                                             CamelObjectHookID id);
    void                camel_object_unhook_event           (void *obj,
                                                             const char *name,
                                                             CamelObjectEventHookFunc hook,
                                                             void *data);
    void                camel_object_trigger_event          (void *obj,
                                                             const char *name,
                                                             void *event_data);
    void*               camel_object_get_interface          (void *vo,
                                                             CamelType itype);
    int                 camel_object_set                    (void *obj,
                                                             struct _CamelException *ex,
                                                             ...);
    int                 camel_object_setv                   (void *obj,
                                                             struct _CamelException *ex,
                                                             CamelArgV *);
    int                 camel_object_get                    (void *obj,
                                                             struct _CamelException *ex,
                                                             ...);
    int                 camel_object_getv                   (void *obj,
                                                             struct _CamelException *ex,
                                                             CamelArgGetV *);
    void*               camel_object_get_ptr                (void *vo,
                                                             CamelException *ex,
                                                             int tag);
    int                 camel_object_get_int                (void *vo,
                                                             CamelException *ex,
                                                             int tag);
    char*               camel_object_meta_get               (void *vo,
                                                             const char *name);
    gboolean            camel_object_meta_set               (void *vo,
                                                             const char *name,
                                                             const char *value);
    int                 camel_object_state_read             (void *vo);
    int                 camel_object_state_write            (void *vo);
    void                camel_object_free                   (void *vo,
                                                             guint32 tag,
                                                             void *value);
                        CamelObjectBag;
    void*               (*CamelCopyFunc)                    (const void *vo);
    CamelObjectBag*     camel_object_bag_new                (GHashFunc hash,
                                                             GEqualFunc equal,
                                                             CamelCopyFunc keycopy,
                                                             GFreeFunc keyfree);
    void*               camel_object_bag_get                (CamelObjectBag *bag,
                                                             const void *key);
    void*               camel_object_bag_peek               (CamelObjectBag *bag,
                                                             const void *key);
    void*               camel_object_bag_reserve            (CamelObjectBag *bag,
                                                             const void *key);
    void                camel_object_bag_add                (CamelObjectBag *bag,
                                                             const void *key,
                                                             void *o);
    void                camel_object_bag_abort              (CamelObjectBag *bag,
                                                             const void *key);
    void                camel_object_bag_rekey              (CamelObjectBag *bag,
                                                             void *o,
                                                             const void *newkey);
    GPtrArray*          camel_object_bag_list               (CamelObjectBag *bag);
    void                camel_object_bag_remove             (CamelObjectBag *bag,
                                                             void *o);
    void                camel_object_bag_destroy            (CamelObjectBag *bag);
    #define             CAMEL_MAKE_CLASS                    (type, tname, parent, pname)
                        CamelIteratorVTable;
                        CamelIterator;
    void*               camel_iterator_new                  (CamelIteratorVTable *klass,
                                                             size_t size);
    void                camel_iterator_free                 (void *it);
    const void*         camel_iterator_next                 (void *it,
                                                             CamelException *ex);
    void                camel_iterator_reset                (void *it);
    int                 camel_iterator_length               (void *it);

## Description

## Details

### CAMEL_OBJECT_TRACK_INSTANCES

    #define CAMEL_OBJECT_TRACK_INSTANCES

### CamelType

    typedef struct _CamelObjectClass *CamelType;

### CamelObject

    typedef struct {
    	struct _CamelObjectClass *klass;

    	guint32 magic;		/* only really needed for debugging ... */

    	/* current hooks on this object */
    	struct _CamelHookList *hooks;

    	guint32 ref_count:24;
    	guint32 flags:8;

    #ifdef CAMEL_OBJECT_TRACK_INSTANCES
    	struct _CamelObject *next, *prev;
    #endif
    } CamelObject;

### CAMEL_CHECK_CAST()

    #define             CAMEL_CHECK_CAST(obj, ctype, ptype)

`obj` : |
`ctype` : |
`ptype` : |

### CAMEL_CHECK_CLASS_CAST()

    #define             CAMEL_CHECK_CLASS_CAST(klass, ctype, ptype)

`klass` : |
`ctype` : |
`ptype` : |

### CAMEL_CHECK_TYPE()

    #define CAMEL_CHECK_TYPE(obj, ctype)                (camel_object_is ((CamelObject *)(obj), (CamelType)(ctype) ))

`obj` : |
`ctype` : |

### CAMEL_CHECK_CLASS_TYPE()

    #define CAMEL_CHECK_CLASS_TYPE(klass, ctype)        (camel_object_class_is ((CamelObjectClass *)(klass), (CamelType)(ctype)))

`klass` : |
`ctype` : |

### camel_object_type

    extern CamelType camel_object_type;

### CAMEL_OBJECT_TYPE

    #define CAMEL_OBJECT_TYPE        (camel_object_type)

### CAMEL_OBJECT_GET_TYPE()

    #define CAMEL_OBJECT_GET_TYPE(o)  ((CamelType)(CAMEL_OBJECT(o))->klass)

`o` : |

### CamelObjectHookID

    typedef unsigned int CamelObjectHookID;

### CamelObjectMeta

    typedef struct {
    	struct _CamelObjectMeta *next;

    	char *value;
    	char name[1];		/* allocated as part of structure */
    } CamelObjectMeta;

### camel_interface_type

    extern CamelType camel_interface_type;

### CAMEL_INTERFACE_TYPE

    #define CAMEL_INTERFACE_TYPE (camel_interface_type)

### CamelInterface

    typedef struct {
    	struct _CamelObjectClass type;
    } CamelInterface;

### CamelObjectClassInitFunc ()

    void                (*CamelObjectClassInitFunc)         (CamelObjectClass *);

`Param1` : |

### CamelObjectClassFinalizeFunc ()

    void                (*CamelObjectClassFinalizeFunc)     (CamelObjectClass *);

`Param1` : |

### CamelObjectInitFunc ()

    void                (*CamelObjectInitFunc)              (CamelObject *,
                                                             CamelObjectClass *);

`Param1` : |
`Param2` : |

### CamelObjectFinalizeFunc ()

    void                (*CamelObjectFinalizeFunc)          (CamelObject *);

`Param1` : |

### CamelObjectEventPrepFunc ()

    gboolean            (*CamelObjectEventPrepFunc)         (CamelObject *,
                                                             gpointer );

`Param1` : |
`Param2` : |
Returns : |

### CamelObjectEventHookFunc ()

    void                (*CamelObjectEventHookFunc)         (CamelObject *,
                                                             gpointer ,
                                                             gpointer );

`Param1` : |
`Param2` : |
`Param3` : |

### CAMEL_INVALID_TYPE

    #define CAMEL_INVALID_TYPE (NULL)

### enum CamelObjectFlags

    typedef enum _CamelObjectFlags {
    	CAMEL_OBJECT_DESTROY = (1<<0)
    } CamelObjectFlags;

### camel_type_init ()

    void                camel_type_init                     (void);

### camel_type_register ()

    CamelType           camel_type_register                 (CamelType parent,
                                                             const char *name,
                                                             size_t instance_size,
                                                             size_t classfuncs_size,
                                                             CamelObjectClassInitFunc class_init,
                                                             CamelObjectClassFinalizeFunc class_finalize,
                                                             CamelObjectInitFunc instance_init,
                                                             CamelObjectFinalizeFunc instance_finalize);

`parent` : |
`name` : |
`instance_size` : |
`classfuncs_size` : |
`class_init` : |
`class_finalize` : |
`instance_init` : |
`instance_finalize` : |
Returns : |

### camel_interface_register ()

    CamelType           camel_interface_register            (CamelType parent,
                                                             const char *name,
                                                             size_t classfuncs_size,
                                                             CamelObjectClassInitFunc class_init,
                                                             CamelObjectClassFinalizeFunc class_finalize);

`parent` : |
`name` : |
`classfuncs_size` : |
`class_init` : |
`class_finalize` : |
Returns : |

### camel_type_get_global_classfuncs()

    #define camel_type_get_global_classfuncs(x) ((CamelObjectClass *)(x))

`x` : |

### camel_type_to_name ()

    const char*         camel_type_to_name                  (CamelType type);

`type` : |
Returns : |

### camel_name_to_type ()

    CamelType           camel_name_to_type                  (const char *name);

`name` : |
Returns : |

### camel_object_class_add_event ()

    void                camel_object_class_add_event        (CamelObjectClass *klass,
                                                             const char *name,
                                                             CamelObjectEventPrepFunc prep);

`klass` : |
`name` : |
`prep` : |

### camel_object_class_add_interface ()

    void                camel_object_class_add_interface    (CamelObjectClass *klass,
                                                             CamelType itype);

`klass` : |
`itype` : |

### camel_object_class_dump_tree ()

    void                camel_object_class_dump_tree        (CamelType root);

`root` : |

### camel_object_cast ()

    CamelObject*        camel_object_cast                   (CamelObject *obj,
                                                             CamelType ctype);

`obj` : |
`ctype` : |
Returns : |

### camel_object_is ()

    gboolean            camel_object_is                     (CamelObject *obj,
                                                             CamelType ctype);

`obj` : |
`ctype` : |
Returns : |

### camel_object_class_cast ()

    CamelObjectClass*   camel_object_class_cast             (CamelObjectClass *klass,
                                                             CamelType ctype);

`klass` : |
`ctype` : |
Returns : |

### camel_object_class_is ()

    gboolean            camel_object_class_is               (CamelObjectClass *klass,
                                                             CamelType ctype);

`klass` : |
`ctype` : |
Returns : |

### camel_interface_cast ()

    CamelObjectClass*   camel_interface_cast                (CamelObjectClass *klass,
                                                             CamelType ctype);

`klass` : |
`ctype` : |
Returns : |

### camel_interface_is ()

    gboolean            camel_interface_is                  (CamelObjectClass *k,
                                                             CamelType ctype);

`k` : |
`ctype` : |
Returns : |

### camel_object_new ()

    CamelObject*        camel_object_new                    (CamelType type);

`type` : |
Returns : |

### camel_object_new_name ()

    CamelObject*        camel_object_new_name               (const char *name);

`name` : |
Returns : |

### camel_object_ref ()

    void                camel_object_ref                    (void *);

`Param1` : |

### camel_object_unref ()

    void                camel_object_unref                  (void *);

`Param1` : |

### camel_object_hook_event ()

    CamelObjectHookID   camel_object_hook_event             (void *obj,
                                                             const char *name,
                                                             CamelObjectEventHookFunc hook,
                                                             void *data);

`obj` : |
`name` : |
`hook` : |
`data` : |
Returns : |

### camel_object_remove_event ()

    void                camel_object_remove_event           (void *obj,
                                                             CamelObjectHookID id);

`obj` : |
`id` : |

### camel_object_unhook_event ()

    void                camel_object_unhook_event           (void *obj,
                                                             const char *name,
                                                             CamelObjectEventHookFunc hook,
                                                             void *data);

`obj` : |
`name` : |
`hook` : |
`data` : |

### camel_object_trigger_event ()

    void                camel_object_trigger_event          (void *obj,
                                                             const char *name,
                                                             void *event_data);

`obj` : |
`name` : |
`event_data` : |

### camel_object_get_interface ()

    void*               camel_object_get_interface          (void *vo,
                                                             CamelType itype);

`vo` : |
`itype` : |
Returns : |

### camel_object_set ()

    int                 camel_object_set                    (void *obj,
                                                             struct _CamelException *ex,
                                                             ...);

`obj` : |
`ex` : |
`...` : |
Returns : |

### camel_object_setv ()

    int                 camel_object_setv                   (void *obj,
                                                             struct _CamelException *ex,
                                                             CamelArgV *);

`obj` : |
`ex` : |
`Param3` : |
Returns : |

### camel_object_get ()

    int                 camel_object_get                    (void *obj,
                                                             struct _CamelException *ex,
                                                             ...);

`obj` : |
`ex` : |
`...` : |
Returns : |

### camel_object_getv ()

    int                 camel_object_getv                   (void *obj,
                                                             struct _CamelException *ex,
                                                             CamelArgGetV *);

`obj` : |
`ex` : |
`Param3` : |
Returns : |

### camel_object_get_ptr ()

    void*               camel_object_get_ptr                (void *vo,
                                                             CamelException *ex,
                                                             int tag);

`vo` : |
`ex` : |
`tag` : |
Returns : |

### camel_object_get_int ()

    int                 camel_object_get_int                (void *vo,
                                                             CamelException *ex,
                                                             int tag);

`vo` : |
`ex` : |
`tag` : |
Returns : |

### camel_object_meta_get ()

    char*               camel_object_meta_get               (void *vo,
                                                             const char *name);

Get a meta-data on an object.

`vo` : |
`name` : |
Returns : | NULL if the meta-data is not set.

### camel_object_meta_set ()

    gboolean            camel_object_meta_set               (void *vo,
                                                             const char *name,
                                                             const char *value);

Set a meta-data item on an object. If the object supports persistent data, then the meta-data will be persistent across sessions.

If the meta-data changes, is added, or removed, then a "meta_changed" event will be triggered with the name of the changed data.

`vo` : |
`name` : | Name of meta-data. Should be prefixed with class of setter.
`value` : | Value to set. If NULL, then the meta-data is removed.
Returns : | TRUE if the setting caused a change to the object's metadata.

### camel_object_state_read ()

    int                 camel_object_state_read             (void *vo);

Read persistent object state from object_set(CAMEL_OBJECT_STATE_FILE).

`vo` : |
Returns : | -1 on error.

### camel_object_state_write ()

    int                 camel_object_state_write            (void *vo);

Write persistent state to the file as set by object_set(CAMEL_OBJECT_STATE_FILE).

`vo` : |
Returns : | -1 on error.

### camel_object_free ()

    void                camel_object_free                   (void *vo,
                                                             guint32 tag,
                                                             void *value);

`vo` : |
`tag` : |
`value` : |

### CamelObjectBag

    typedef struct _CamelObjectBag CamelObjectBag;

### CamelCopyFunc ()

    void*               (*CamelCopyFunc)                    (const void *vo);

`vo` : |
Returns : |

### camel_object_bag_new ()

    CamelObjectBag*     camel_object_bag_new                (GHashFunc hash,
                                                             GEqualFunc equal,
                                                             CamelCopyFunc keycopy,
                                                             GFreeFunc keyfree);

Allocate a new object bag. Object bag's are key'd hash tables of camel-objects which can be updated atomically using transaction semantics.

`hash` : |
`equal` : |
`keycopy` : |
`keyfree` : |
Returns : |

### camel_object_bag_get ()

    void*               camel_object_bag_get                (CamelObjectBag *bag,
                                                             const void *key);

Lookup an object by `key`. If the key is currently reserved, then wait until the key has been committed before continuing.

`bag` : |
`key` : |
Returns : | NULL if the object corresponding to `key` is not in the bag. Otherwise a ref'd object pointer which the caller owns the ref to.

### camel_object_bag_peek ()

    void*               camel_object_bag_peek               (CamelObjectBag *bag,
                                                             const void *key);

Lookup the object `key` in `bag`, ignoring any reservations. If it isn't committed, then it isn't considered. This should only be used where reliable transactional-based state is not required.

Unlike other 'peek' operations, the object is still reffed if found.

`bag` : |
`key` : |
Returns : | A referenced object, or NULL if `key` is not present in the bag.

### camel_object_bag_reserve ()

    void*               camel_object_bag_reserve            (CamelObjectBag *bag,
                                                             const void *key);

Reserve a key in the object bag. If the key is already reserved in another thread, then wait until the reservation has been committed.

After reserving a key, you either get a reffed pointer to the object corresponding to the key, similar to object_bag_get, or you get NULL, signifying that you then MIST call either object_bag_add or object_bag_abort.

You may reserve multiple keys from the same thread, but they should always be reserved in the same order, to avoid deadlocks.

`bag` : |
`key` : |
Returns : |

### camel_object_bag_add ()

    void                camel_object_bag_add                (CamelObjectBag *bag,
                                                             const void *key,
                                                             void *o);

Add an object `vo` to the object bag `bag`. The `key` MUST have previously been reserved using `camel_object_bag_reserve()`.

`bag` : |
`key` : |
`o` : |

### camel_object_bag_abort ()

    void                camel_object_bag_abort              (CamelObjectBag *bag,
                                                             const void *key);

Abort a key reservation.

`bag` : |
`key` : |

### camel_object_bag_rekey ()

    void                camel_object_bag_rekey              (CamelObjectBag *bag,
                                                             void *o,
                                                             const void *newkey);

Re-key an object, atomically. The key for object `o` is set to `newkey`, in an atomic manner.

It is an api (fatal) error if `o` is not currently in the bag.

`bag` : |
`o` : |
`newkey` : |

### camel_object_bag_list ()

    GPtrArray*          camel_object_bag_list               (CamelObjectBag *bag);

`bag` : |
Returns : |

### camel_object_bag_remove ()

    void                camel_object_bag_remove             (CamelObjectBag *bag,
                                                             void *o);

`bag` : |
`o` : |

### camel_object_bag_destroy ()

    void                camel_object_bag_destroy            (CamelObjectBag *bag);

`bag` : |

### CAMEL_MAKE_CLASS()

    #define             CAMEL_MAKE_CLASS(type, tname, parent, pname)

`type` : |
`tname` : |
`parent` : |
`pname` : |

### CamelIteratorVTable

    typedef struct {
    	/* free fields, dont free base object */
    	void (*free)(void *it);
    	/* go to the next messageinfo */
    	const void *(*next)(void *it, CamelException *ex);
    	/* go back to the start */
    	void (*reset)(void *it);
    	/* *ESTIMATE* how many results are in the iterator */
    	int (*length)(void *it);
    } CamelIteratorVTable;

### CamelIterator

    typedef struct {
    	CamelIteratorVTable *klass;

    	/* subclasses adds new fields afterwards */
    } CamelIterator;

### camel_iterator_new ()

    void*               camel_iterator_new                  (CamelIteratorVTable *klass,
                                                             size_t size);

`klass` : |
`size` : |
Returns : |

### camel_iterator_free ()

    void                camel_iterator_free                 (void *it);

`it` : |

### camel_iterator_next ()

    const void*         camel_iterator_next                 (void *it,
                                                             CamelException *ex);

`it` : |
`ex` : |
Returns : |

### camel_iterator_reset ()

    void                camel_iterator_reset                (void *it);

`it` : |

### camel_iterator_length ()

    int                 camel_iterator_length               (void *it);

`it` : |
Returns : |