mirror of
https://github.com/sigmasternchen/crap-libs
synced 2025-03-15 07:38:56 +00:00
better abstraction
This commit is contained in:
parent
274d85b973
commit
c3547c47f5
3 changed files with 79 additions and 37 deletions
|
@ -7,30 +7,34 @@
|
|||
|
||||
class_t test_class;
|
||||
|
||||
__attribute__ ((constructor))
|
||||
static void add_test_class(void) {
|
||||
test_class.id = new_class("test", NO_SUPER_CLASS, true);
|
||||
}
|
||||
class(test, test_class, object_class, true) {
|
||||
extends(object_t);
|
||||
|
||||
typedef struct test {
|
||||
meta_object_t meta;
|
||||
void (*destruct)(struct test*);
|
||||
const char* string;
|
||||
|
||||
void (*print)(struct test*);
|
||||
void (*destruct)(struct test*);
|
||||
} test_t;
|
||||
|
||||
void test_method_print(test_t* this) {
|
||||
void method(test, print)(test_t* this) {
|
||||
printf("%s\n", this->string);
|
||||
}
|
||||
void test_method_destruct(test_t* this) {
|
||||
free(this);
|
||||
void method(test, destruct)(test_t* this) {
|
||||
this->super.destruct((object_t*) this);
|
||||
}
|
||||
|
||||
test_t* test_method_construct(const char* string) {
|
||||
test_t* obj = malloc(sizeof(test_t));
|
||||
void method(test, populate)(test_t* obj, const char* string) {
|
||||
populate(object)((object_t*) obj, test_class);
|
||||
|
||||
obj->string = string;
|
||||
obj->destruct = test_method_destruct;
|
||||
obj->print = test_method_print;
|
||||
|
||||
add_method(obj, test, destruct);
|
||||
add_method(obj, test, print);
|
||||
}
|
||||
|
||||
test_t* method(test, construct)(const char* string) {
|
||||
test_t* obj = malloc(sizeof(test_t));
|
||||
populate(test)(obj, string);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
|
45
oop/oop.c
45
oop/oop.c
|
@ -1,47 +1,66 @@
|
|||
#include "oop.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
class_id_t class_ids = 0;
|
||||
|
||||
meta_class_t classes[MAX_CLASSES];
|
||||
|
||||
class_id_t new_class(const char* name, class_id_t super, bool instanceable) {
|
||||
class_id_t oop_add_class(const char* name, class_t super, bool instanceable) {
|
||||
classes[class_ids] = (meta_class_t) {
|
||||
.name = name,
|
||||
.super = super,
|
||||
.super = super.id,
|
||||
.instanceable = instanceable
|
||||
};
|
||||
return class_ids++;
|
||||
}
|
||||
|
||||
bool instance_of_id(void* object, class_id_t id) {
|
||||
bool oop_instance_of_id(void* object, class_id_t id) {
|
||||
if (sizeof (object) < sizeof (object_t))
|
||||
return false; // not an object
|
||||
object_t* obj = (object_t*) object;
|
||||
return obj->meta_obj.class.id == id;
|
||||
return obj->meta_obj.type.id == id;
|
||||
}
|
||||
|
||||
bool instance_of(void* object, class_t class) {
|
||||
return instance_of_id(object, class.id);
|
||||
bool oop_instance_of(void* object, class_t type) {
|
||||
return oop_instance_of_id(object, type.id);
|
||||
}
|
||||
|
||||
const char* get_class_name_by_id(class_id_t id) {
|
||||
const char* oop_get_class_name_by_id(class_id_t id) {
|
||||
return classes[id].name;
|
||||
}
|
||||
|
||||
const char* get_class_name(class_t class) {
|
||||
return get_class_name_by_id(class.id);
|
||||
const char* oop_get_class_name(class_t type) {
|
||||
return oop_get_class_name_by_id(type.id);
|
||||
}
|
||||
|
||||
class_id_t id_from_name(const char* class_name) {
|
||||
class_id_t oop_id_from_name(const char* class_name) {
|
||||
for (int i = 0; i < class_ids; i++) {
|
||||
if (strcmp(class_name, classes[i].name) == 0)
|
||||
return i;
|
||||
}
|
||||
return NO_CLASS;
|
||||
return NO_CLASS_ID;
|
||||
}
|
||||
|
||||
bool class_exists(const char* class_name) {
|
||||
return id_from_name(class_name) != NO_CLASS;
|
||||
bool oop_class_exists(const char* class_name) {
|
||||
return oop_id_from_name(class_name) != NO_CLASS_ID;
|
||||
}
|
||||
|
||||
|
||||
class_t object_class;
|
||||
|
||||
void method(object, destruct)(object_t* obj) {
|
||||
free(obj);
|
||||
}
|
||||
|
||||
object_t* method(object, construct)() {
|
||||
object_t* obj = malloc(sizeof(object_t));
|
||||
populate(object)(obj, object_class);
|
||||
return obj;
|
||||
}
|
||||
|
||||
void method(object, populate)(object_t* obj, class_t type) {
|
||||
obj->meta_obj.type = type;
|
||||
add_method(obj, object, destruct);
|
||||
}
|
||||
|
|
39
oop/oop.h
39
oop/oop.h
|
@ -4,14 +4,25 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
#define class(name, type, superclass, instanceable) __attribute__ ((constructor)) static void add_##name##_class(void) { type.id = oop_add_class(#name, superclass, instanceable); } typedef struct name
|
||||
#define method(class, method) class ##_method_## method
|
||||
#define add_method(object, class, method) object->method = class ##_method_## method
|
||||
|
||||
#define extends(type) type super
|
||||
|
||||
#define construct(name) name ##_method_construct
|
||||
#define populate(name) name ##_method_populate
|
||||
|
||||
|
||||
#define call(obj, method) (obj)->method((obj))
|
||||
#define new
|
||||
|
||||
#define MAX_CLASSES 1024
|
||||
#define NO_SUPER_CLASS -1
|
||||
#define NO_CLASS -1
|
||||
#define NO_CLASS_ID -1
|
||||
#define NO_SUPER_CLASS (class_t){.id = NO_CLASS_ID}
|
||||
|
||||
|
||||
|
||||
typedef int class_id_t;
|
||||
|
||||
|
@ -26,19 +37,27 @@ typedef struct class {
|
|||
} class_t;
|
||||
|
||||
typedef struct meta_object {
|
||||
class_t class;
|
||||
class_t type;
|
||||
} meta_object_t;
|
||||
|
||||
typedef struct object {
|
||||
class_id_t oop_add_class(const char*, class_t, bool);
|
||||
|
||||
#define object construct(object)
|
||||
extern class_t object_class;
|
||||
|
||||
class(object, object_class, NO_SUPER_CLASS, true) {
|
||||
meta_object_t meta_obj;
|
||||
void (*destruct)(struct object*);
|
||||
} object_t;
|
||||
|
||||
class_id_t new_class(const char*, class_id_t, bool);
|
||||
bool instance_of_id(void*, class_id_t);
|
||||
bool instance_of(void*, class_t);
|
||||
const char* get_class_name(class_t);
|
||||
class_id_t id_from_name(const char*);
|
||||
bool class_exists(const char*);
|
||||
|
||||
bool oop_instance_of_id(void*, class_id_t);
|
||||
bool oop_instance_of(void*, class_t);
|
||||
const char* oop_get_class_name(class_t);
|
||||
class_id_t oop_id_from_name(const char*);
|
||||
bool oop_class_exists(const char*);
|
||||
|
||||
object_t* method(object, construct)(void);
|
||||
void method(object, populate)(object_t* obj, class_t);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue