crap-libs/oop/oop.c

112 lines
2.4 KiB
C
Raw Normal View History

2017-03-07 22:52:11 +00:00
#include "oop.h"
#include <string.h>
2017-03-09 15:24:02 +00:00
#include <stdlib.h>
2017-03-09 17:02:18 +00:00
#include <stdio.h>
2017-03-07 22:52:11 +00:00
class_id_t class_ids = 0;
meta_class_t classes[MAX_CLASSES];
2017-03-11 02:36:07 +00:00
class_id_t oop_add_class(const char* name, bool interface, class_t super, iflist_t iflist, bool instanceable) {
2017-03-09 17:02:18 +00:00
if (oop_class_exists(name))
return oop_id_from_name(name);
2017-03-07 22:52:11 +00:00
classes[class_ids] = (meta_class_t) {
.name = name,
2017-03-11 02:36:07 +00:00
.interface = interface,
2017-03-09 15:24:02 +00:00
.super = super.id,
2017-03-11 02:36:07 +00:00
.nrinterfaces = iflist.nr,
2017-03-07 22:52:11 +00:00
.instanceable = instanceable
};
2017-03-11 02:36:07 +00:00
for(int i = 0; i < iflist.nr; i++) {
classes[class_ids].interfaces[i] = iflist.interfaces[i].id;
}
2017-03-07 22:52:11 +00:00
return class_ids++;
}
2017-03-09 15:24:02 +00:00
bool oop_instance_of_id(void* object, class_id_t id) {
class_id_t cid = ((Object_t*) object)->meta_obj.type.id;
2017-03-09 17:02:18 +00:00
meta_class_t c = classes[cid];
2017-03-11 02:36:07 +00:00
2017-03-09 17:02:18 +00:00
if (cid == id)
return true;
2017-03-11 02:36:07 +00:00
for (int i = 0; i < c.nrinterfaces; i++) {
if (c.interfaces[i] == id)
return true;
}
2017-03-09 17:02:18 +00:00
// iterate through superclasses of object
2017-03-11 02:36:07 +00:00
while (c.super != NO_CLASS_ID) {
2017-03-09 17:02:18 +00:00
if (c.super == id)
return true;
2017-03-11 02:36:07 +00:00
c = classes[c.super];
for (int i = 0; i < c.nrinterfaces; i++) {
if (c.interfaces[i] == id)
return true;
}
2017-03-09 17:02:18 +00:00
}
return false;
2017-03-07 22:52:11 +00:00
}
2017-03-09 15:24:02 +00:00
bool oop_instance_of(void* object, class_t type) {
2017-03-09 17:02:18 +00:00
return oop_instance_of_id(object, type.id);
2017-03-07 22:52:11 +00:00
}
2017-03-09 15:24:02 +00:00
const char* oop_get_class_name_by_id(class_id_t id) {
2017-03-07 22:52:11 +00:00
return classes[id].name;
}
2017-03-09 15:24:02 +00:00
const char* oop_get_class_name(class_t type) {
return oop_get_class_name_by_id(type.id);
2017-03-07 22:52:11 +00:00
}
2017-03-09 15:24:02 +00:00
class_id_t oop_id_from_name(const char* class_name) {
2017-03-07 22:52:11 +00:00
for (int i = 0; i < class_ids; i++) {
if (strcmp(class_name, classes[i].name) == 0)
return i;
}
2017-03-09 15:24:02 +00:00
return NO_CLASS_ID;
2017-03-07 22:52:11 +00:00
}
2017-03-09 15:24:02 +00:00
bool oop_class_exists(const char* class_name) {
return oop_id_from_name(class_name) != NO_CLASS_ID;
}
2017-03-09 17:02:18 +00:00
class_t oop_class_from_id(class_id_t id) {
return (class_t) {.id = id};
}
class_t oop_get_super_class(class_t type) {
return oop_class_from_id(classes[type.id].super);
}
class_t oop_get_class_from_obj(Object_t* obj) {
return oop_class_from_id(((Object_t*) obj)->meta_obj.type.id);
2017-03-09 17:02:18 +00:00
}
2017-03-09 15:24:02 +00:00
2017-03-10 22:30:48 +00:00
// defined by class macro in h-file
class_t Object_class;
2017-03-09 15:24:02 +00:00
2017-03-11 02:36:07 +00:00
// defined by interface macro in h-file
class_t Cloneable_class;
void method(Object, destruct)(Object_t* obj) {
2017-03-09 15:24:02 +00:00
free(obj);
}
Object_t* method(Object, construct)() {
Object_t* obj = malloc(sizeof(Object_t));
populate(Object)(obj, Object_class);
2017-03-09 15:24:02 +00:00
return obj;
}
void method(Object, populate)(Object_t* obj, class_t type) {
2017-03-09 15:24:02 +00:00
obj->meta_obj.type = type;
add_method(obj, Object, destruct);
2017-03-07 22:52:11 +00:00
}