166 lines
8.2 KiB
C
166 lines
8.2 KiB
C
#ifndef BLUE_CORE_MACROS_H_
|
|
#define BLUE_CORE_MACROS_H_
|
|
|
|
#include <blue/core/class.h>
|
|
#include <blue/core/object.h>
|
|
#include <blue/core/thread.h>
|
|
#include <blue/core/type.h>
|
|
#include <stdlib.h>
|
|
|
|
#define __B_IFACE_I0(p, x) p##x
|
|
#define __B_IFACE_I1(p, x) __B_IFACE_I0(p, x)
|
|
|
|
#define B_TYPE_FWDREF(name) struct _b_object
|
|
|
|
/* Type definitions macros (for use in .c source file) */
|
|
|
|
#define B_TYPE_CLASS_DEFINITION_BEGIN(type_name) \
|
|
static void type_name##_class_init(b_class *p, void *d) \
|
|
{
|
|
#define B_TYPE_CLASS_DEFINITION_END(type_name) }
|
|
|
|
#define B_TYPE_CLASS_INTERFACE_BEGIN(interface_name, interface_id) \
|
|
interface_name##_class *__B_IFACE_I1(iface, __LINE__) \
|
|
= b_class_get_interface(p, interface_id); \
|
|
if (__B_IFACE_I1(iface, __LINE__)) { \
|
|
interface_name##_class *iface = __B_IFACE_I1(iface, __LINE__);
|
|
#define B_TYPE_CLASS_INTERFACE_END(interface_name, interface_id) }
|
|
#define B_INTERFACE_ENTRY(slot) iface->slot
|
|
|
|
#define B_TYPE_DEFINITION_BEGIN(name) \
|
|
static b_type_info name##_type_info = {0}; \
|
|
static void name##_class_init(b_class *, void *); \
|
|
static void name##_type_init(void) \
|
|
{ \
|
|
b_type_info *type_info = &name##_type_info; \
|
|
unsigned int nr_vtables = 0; \
|
|
type_info->t_name = #name; \
|
|
type_info->t_class_init = name##_class_init;
|
|
#define B_TYPE_DEFINITION_END(name) \
|
|
b_result result = b_type_register(type_info); \
|
|
if (b_result_is_error(result)) { \
|
|
b_throw_error_caused_by_error( \
|
|
B_ERRORS_BUILTIN, B_ERR_TYPE_REGISTRATION_FAILURE, \
|
|
result); \
|
|
abort(); \
|
|
} \
|
|
} \
|
|
b_type name##_get_type(void) \
|
|
{ \
|
|
static b_once static_type_init = B_ONCE_INIT; \
|
|
\
|
|
if (b_init_once(&static_type_init)) { \
|
|
name##_type_init(); \
|
|
} \
|
|
\
|
|
return &name##_type_info.t_id; \
|
|
}
|
|
|
|
#define B_TYPE_ID(a, b, c, d, e) b_type_id_init(&type_info->t_id, a, b, c, d, e)
|
|
#define B_TYPE_EXTENDS(parent_id) \
|
|
b_type_id_copy(parent_id, &type_info->t_parent_id)
|
|
#define B_TYPE_IMPLEMENTS(interface_id) \
|
|
b_type_id_copy( \
|
|
interface_id, \
|
|
&type_info->t_interfaces[type_info->t_nr_interfaces++])
|
|
#define B_TYPE_CLASS(class_struct) \
|
|
type_info->t_class_size = sizeof(class_struct)
|
|
#define B_TYPE_INSTANCE_INIT(func) type_info->t_instance_init = (func)
|
|
#define B_TYPE_INSTANCE_FINI(func) type_info->t_instance_fini = (func)
|
|
|
|
#if 0
|
|
#define B_TYPE_VTABLE_BEGIN(vtable_struct, interface_id) \
|
|
vtable_struct __B_IFACE_I1(iface, __LINE__) = {0}; \
|
|
{ \
|
|
vtable_struct *iface = &__B_IFACE_I1(iface, __LINE__); \
|
|
type_info->t_vtables[nr_vtables].v_vtable = iface; \
|
|
type_info->t_vtables[nr_vtables].v_interface_id = interface_id; \
|
|
nr_vtables++;
|
|
#define B_TYPE_VTABLE_END(vtable_struct, interface_id) }
|
|
#endif
|
|
|
|
#define B_TYPE_INSTANCE_PRIVATE(instance_struct) \
|
|
type_info->t_instance_private_size = sizeof(instance_struct)
|
|
#define B_TYPE_INSTANCE_PROTECTED(instance_struct) \
|
|
type_info->t_instance_protected_size = sizeof(instance_struct)
|
|
|
|
/* Type declaration macros (for use in .h header file) */
|
|
|
|
#define B_DECLARE_TYPE(name) \
|
|
typedef B_TYPE_FWDREF(name) name; \
|
|
typedef struct _##name##_class name##_class; \
|
|
static inline name *name##_ref(name *p) \
|
|
{ \
|
|
return b_object_ref(p); \
|
|
} \
|
|
static inline void name##_unref(name *p) \
|
|
{ \
|
|
b_object_unref(p); \
|
|
}
|
|
|
|
#define B_TYPE_CLASS_DECLARATION_BEGIN(name) struct _##name##_class {
|
|
#define B_TYPE_CLASS_DECLARATION_END(name) \
|
|
} \
|
|
;
|
|
|
|
#define B_TYPE_VIRTUAL_METHOD(return_type, method_name) \
|
|
return_type(*method_name)
|
|
|
|
#define B_TYPE_DEFAULT_CONSTRUCTOR(type_name, type_id) \
|
|
static inline type_name *type_name##_create(void) \
|
|
{ \
|
|
return b_object_create(type_id); \
|
|
}
|
|
|
|
/* Other macros */
|
|
|
|
#define B_CLASS_DISPATCH_VIRTUAL(type_name, type_id, object, func, ...) \
|
|
do { \
|
|
type_name##_class *iface \
|
|
= b_object_get_interface(object, type_id); \
|
|
if (iface && iface->func) { \
|
|
return iface->func(__VA_ARGS__); \
|
|
} \
|
|
} while (0)
|
|
#define B_CLASS_DISPATCH_VIRTUAL_V(type_name, type_id, object, func, ...) \
|
|
do { \
|
|
type_name##_class *iface \
|
|
= b_object_get_interface(object, type_id); \
|
|
if (iface && iface->func) { \
|
|
iface->func(__VA_ARGS__); \
|
|
return; \
|
|
} \
|
|
} while (0)
|
|
#define B_CLASS_DISPATCH_STATIC(type_id, func_name, obj, ...) \
|
|
do { \
|
|
void *priv = b_object_get_private(obj, type_id); \
|
|
return func_name(priv, __VA_ARGS__); \
|
|
} while (0)
|
|
#define B_CLASS_DISPATCH_STATIC_V(type_id, func_name, obj, ...) \
|
|
do { \
|
|
void *priv = b_object_get_private(obj, type_id); \
|
|
func_name(priv, __VA_ARGS__); \
|
|
} while (0)
|
|
|
|
#define B_CLASS_DISPATCH_STATIC_0(type_id, func_name, obj) \
|
|
do { \
|
|
void *priv = b_object_get_private(obj, type_id); \
|
|
return func_name(priv); \
|
|
} while (0)
|
|
|
|
#define B_CLASS_DISPATCH_STATIC_V0(type_id, func_name, obj) \
|
|
do { \
|
|
void *priv = b_object_get_private(obj, type_id); \
|
|
func_name(priv); \
|
|
} while (0)
|
|
|
|
#ifdef __cplusplus
|
|
#define B_DECLS_BEGIN extern "C" {
|
|
#define B_DECLS_END }
|
|
#else
|
|
#define B_DECLS_BEGIN
|
|
#define B_DECLS_END
|
|
#endif
|
|
|
|
#endif
|