core: move new object system to core module
this will allow a wider range of data structures (e.g. b_error, b_stream, b_stringstream) to make use of the new object system, and other modules and library users can use the object system without depending on the blue-object or blue-ds modules. blue-ds will become a simple library of data structures (string, hashmap, etc), built on top of the core object system.
This commit is contained in:
17
core/include/blue/core/class.h
Normal file
17
core/include/blue/core/class.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef BLUE_OBJECT_CLASS_H_
|
||||
#define BLUE_OBJECT_CLASS_H_
|
||||
|
||||
#include <blue/core/type.h>
|
||||
|
||||
#define B_CLASS_MAGIC 0xDEADFACEDCAFEBEDULL
|
||||
#define B_CLASS(p) ((b_class *)(p))
|
||||
|
||||
typedef struct _b_class b_class;
|
||||
|
||||
#define b_class_get_interface(class, interface_struct, interface_id) \
|
||||
((interface_struct *)z__b_class_get_interface( \
|
||||
B_CLASS(class), interface_id));
|
||||
|
||||
BLUE_API void *z__b_class_get_interface(b_class *c, b_type id);
|
||||
|
||||
#endif
|
||||
130
core/include/blue/core/macros.h
Normal file
130
core/include/blue/core/macros.h
Normal file
@@ -0,0 +1,130 @@
|
||||
#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)
|
||||
|
||||
/* 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_name##_class, 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 struct _b_object name; \
|
||||
typedef struct _##name##_class name##_class;
|
||||
|
||||
#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); \
|
||||
}
|
||||
#define B_TYPE_DEFAULT_DESTRUCTOR(type_name) \
|
||||
static inline void type_name##_release(type_name *p) \
|
||||
{ \
|
||||
b_release(p); \
|
||||
}
|
||||
|
||||
/* Other macros */
|
||||
|
||||
#define B_CLASS_DISPATCH_VIRTUAL(type_name, type_id, object, func, ...) \
|
||||
do { \
|
||||
type_name##_class *iface = b_object_get_interface( \
|
||||
object, type_name##_class, 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_name##_class, type_id); \
|
||||
if (iface && iface->func) { \
|
||||
iface->func(__VA_ARGS__); \
|
||||
return; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
41
core/include/blue/core/object.h
Normal file
41
core/include/blue/core/object.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef BLUE_CORE_OBJECT_H_
|
||||
#define BLUE_CORE_OBJECT_H_
|
||||
|
||||
#include <blue/core/misc.h>
|
||||
#include <blue/core/stringstream.h>
|
||||
#include <blue/core/type.h>
|
||||
|
||||
#define B_OBJECT_MAGIC 0xDECAFC0C0ABEEF13ULL
|
||||
|
||||
#define B_OBJECT(p) ((b_object *)(p))
|
||||
#define B_TYPE_OBJECT (b_object_get_type())
|
||||
|
||||
struct b_stream;
|
||||
|
||||
typedef struct _b_object b_object;
|
||||
|
||||
typedef struct _b_object_class {
|
||||
void (*to_string)(b_object *, struct b_stream *);
|
||||
} b_object_class;
|
||||
|
||||
#define b_object_get_private(object, private_struct, type_id) \
|
||||
((private_struct *)z__b_object_get_private(B_OBJECT(object), type_id));
|
||||
#define b_object_get_protected(object, protected_struct, type_id) \
|
||||
((protected_struct *)z__b_object_get_protected(B_OBJECT(object), type_id));
|
||||
#define b_object_get_interface(object, interface_struct, interface_id) \
|
||||
((interface_struct *)z__b_object_get_interface( \
|
||||
B_OBJECT(object), interface_id));
|
||||
|
||||
BLUE_API b_type b_object_get_type(void);
|
||||
|
||||
BLUE_API void *z__b_object_get_private(b_object *object, b_type type);
|
||||
BLUE_API void *z__b_object_get_protected(b_object *object, b_type type);
|
||||
BLUE_API void *z__b_object_get_interface(b_object *object, b_type type);
|
||||
|
||||
b_object *b_retain(b_object *p);
|
||||
BLUE_API void b_release(b_object *p);
|
||||
|
||||
BLUE_API b_object *b_object_create(b_type type);
|
||||
BLUE_API void b_object_to_string(b_object *p, struct b_stream *out);
|
||||
|
||||
#endif
|
||||
61
core/include/blue/core/type.h
Normal file
61
core/include/blue/core/type.h
Normal file
@@ -0,0 +1,61 @@
|
||||
#ifndef BLUE_CORE_TYPE_H_
|
||||
#define BLUE_CORE_TYPE_H_
|
||||
|
||||
#include <blue/core/error.h>
|
||||
#include <blue/core/misc.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#define B_TYPE_MAX_INTERFACES 64
|
||||
|
||||
struct _b_class;
|
||||
struct _b_object;
|
||||
|
||||
typedef void (*b_class_init_function)(struct _b_class *, void *);
|
||||
typedef void (*b_instance_init_function)(struct _b_object *, void *);
|
||||
typedef void (*b_instance_fini_function)(struct _b_object *, void *);
|
||||
|
||||
typedef const union b_type {
|
||||
struct {
|
||||
uint64_t p00, p01;
|
||||
} a;
|
||||
|
||||
unsigned char b[16];
|
||||
} *b_type;
|
||||
|
||||
typedef struct b_type_info {
|
||||
union b_type t_id;
|
||||
union b_type t_parent_id;
|
||||
const char *t_name;
|
||||
union b_type t_interfaces[B_TYPE_MAX_INTERFACES];
|
||||
size_t t_nr_interfaces;
|
||||
size_t t_class_size;
|
||||
b_class_init_function t_class_init;
|
||||
size_t t_instance_private_size;
|
||||
size_t t_instance_protected_size;
|
||||
b_instance_init_function t_instance_init;
|
||||
b_instance_fini_function t_instance_fini;
|
||||
} b_type_info;
|
||||
|
||||
BLUE_API void b_type_id_init(
|
||||
union b_type *out, uint32_t a, uint16_t b, uint16_t c, uint16_t d,
|
||||
uint64_t e);
|
||||
static inline void b_type_id_copy(b_type src, union b_type *dest)
|
||||
{
|
||||
dest->a.p00 = src->a.p00;
|
||||
dest->a.p01 = src->a.p01;
|
||||
}
|
||||
|
||||
static inline int b_type_id_compare(b_type a, b_type b)
|
||||
{
|
||||
if (a == b) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return memcmp(a, b, sizeof(union b_type));
|
||||
}
|
||||
|
||||
BLUE_API b_result b_type_register(b_type_info *info);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user