2003-12-22 19:29:21 +03:00
|
|
|
/*
|
2004-01-07 21:39:35 +03:00
|
|
|
* $HEADER$
|
2003-12-22 19:29:21 +03:00
|
|
|
*/
|
2004-01-07 10:57:00 +03:00
|
|
|
|
|
|
|
#ifndef LAM_OBJECT_H
|
|
|
|
#define LAM_OBJECT_H
|
2003-12-22 19:29:21 +03:00
|
|
|
|
|
|
|
#include <stdlib.h>
|
2004-01-10 01:09:51 +03:00
|
|
|
#include "lam/types.h"
|
|
|
|
#include "lam/atomic.h"
|
2004-01-16 03:32:41 +03:00
|
|
|
#include "lam/mem/malloc.h"
|
2003-12-22 19:29:21 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Base data structures
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2004-01-07 20:50:41 +03:00
|
|
|
struct lam_object;
|
2003-12-22 19:29:21 +03:00
|
|
|
|
2004-01-07 20:50:41 +03:00
|
|
|
typedef void (*class_init_t)(struct lam_object *);
|
|
|
|
typedef void (*class_destroy_t)(struct lam_object *);
|
2003-12-22 19:29:21 +03:00
|
|
|
|
|
|
|
typedef struct lam_class_info
|
|
|
|
{
|
|
|
|
const char *cls_name;
|
|
|
|
struct lam_class_info *cls_parent;
|
|
|
|
class_init_t cls_init;
|
|
|
|
class_destroy_t cls_destroy;
|
|
|
|
} lam_class_info_t;
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Available Classes
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2004-01-07 20:50:41 +03:00
|
|
|
extern lam_class_info_t lam_object_cls;
|
2003-12-22 19:29:21 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Helpful macros
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define SUPER(obj) (&((obj)->super))
|
|
|
|
|
|
|
|
/* Use STATIC_INIT to initialize objects that are not
|
|
|
|
dynamically allocated. */
|
|
|
|
#define STATIC_INIT(obj, cls_ptr) \
|
|
|
|
do { \
|
2003-12-22 22:28:08 +03:00
|
|
|
OBJECT(&(obj))->obj_class = cls_ptr; \
|
|
|
|
OBJECT(&(obj))->obj_class->cls_init(OBJECT(&(obj))); \
|
2003-12-22 19:29:21 +03:00
|
|
|
} while (0)
|
|
|
|
|
|
|
|
/* super_cls should be the pointer to the obj's parent
|
|
|
|
class info struct. */
|
|
|
|
#define SUPER_INIT(obj, super_cls) \
|
|
|
|
do { \
|
|
|
|
(super_cls)->cls_init(OBJECT(obj)); \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define SUPER_DESTROY(obj, super_cls) (super_cls)->cls_destroy(OBJECT(obj))
|
2004-01-16 03:32:41 +03:00
|
|
|
#define OBJECT(obj) ((lam_object_t *)(obj))
|
2003-12-22 19:29:21 +03:00
|
|
|
#define OBJ_RETAIN(obj) if ( obj ) lam_obj_retain(OBJECT(obj))
|
|
|
|
#define OBJ_RELEASE(obj) if ( obj ) lam_obj_release(OBJECT(obj))
|
|
|
|
|
2004-01-07 20:50:41 +03:00
|
|
|
typedef struct lam_object
|
2003-12-22 19:29:21 +03:00
|
|
|
{
|
|
|
|
lam_class_info_t *obj_class;
|
|
|
|
int obj_refcnt;
|
|
|
|
} lam_object_t;
|
|
|
|
|
|
|
|
void lam_obj_init(lam_object_t *obj);
|
|
|
|
void lam_obj_destroy(lam_object_t *obj);
|
|
|
|
|
2004-01-16 03:32:41 +03:00
|
|
|
|
|
|
|
static inline lam_object_t* lam_create_object(size_t size, lam_class_info_t* class_info)
|
|
|
|
{
|
|
|
|
lam_object_t *obj = (lam_object_t*)LAM_MALLOC(size);
|
|
|
|
if ( NULL != obj ) {
|
|
|
|
obj->obj_class = class_info;
|
|
|
|
obj->obj_class->cls_init(obj);
|
|
|
|
}
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define NEW(obj_type, class_info) \
|
|
|
|
((obj_type*)lam_create_object(sizeof(obj_type), class_info))
|
|
|
|
#define CREATE_OBJECT(obj, obj_type, class_info) \
|
|
|
|
(obj = (obj_type*)lam_create_object(sizeof(obj_type, class_info)))
|
|
|
|
|
2004-01-10 01:09:51 +03:00
|
|
|
/*
|
|
|
|
* This function is used by inline functions later in this file, and
|
|
|
|
* it must be defined by other header files later (eg., one of the
|
|
|
|
* atomic.h's).
|
|
|
|
*/
|
|
|
|
static inline int fetchNadd(volatile int *addr, int inc);
|
|
|
|
|
2003-12-22 19:29:21 +03:00
|
|
|
/*
|
|
|
|
returns 1 if object's class is derived from cls, otherwise 0.
|
|
|
|
*/
|
|
|
|
int lam_obj_is_kind_of(lam_object_t *obj, lam_class_info_t *cls);
|
|
|
|
|
|
|
|
static inline int lam_obj_get_ref_count(lam_object_t *obj)
|
|
|
|
{
|
|
|
|
return obj->obj_refcnt;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void lam_obj_retain(lam_object_t *obj)
|
|
|
|
{
|
|
|
|
fetchNadd(&obj->obj_refcnt, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void lam_obj_release(lam_object_t *obj)
|
|
|
|
{
|
|
|
|
if ( fetchNadd(&obj->obj_refcnt, -1) == 1 )
|
|
|
|
{
|
|
|
|
obj->obj_class->cls_destroy(obj);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-01-07 10:57:00 +03:00
|
|
|
#endif /* LAM_OBJECT_H */
|
2003-12-22 19:29:21 +03:00
|
|
|
|