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:
2025-10-15 10:38:18 +01:00
parent 2108277061
commit 9d2ebfce2e
11 changed files with 19 additions and 19 deletions

View 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

View 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

View 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

View 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