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-09 15:24:02 +00:00
|
|
|
class_id_t oop_add_class(const char* name, class_t super, 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-09 15:24:02 +00:00
|
|
|
.super = super.id,
|
2017-03-07 22:52:11 +00:00
|
|
|
.instanceable = instanceable
|
|
|
|
};
|
|
|
|
return class_ids++;
|
|
|
|
}
|
|
|
|
|
2017-03-09 15:24:02 +00:00
|
|
|
bool oop_instance_of_id(void* object, class_id_t id) {
|
2017-03-11 01:00:02 +00:00
|
|
|
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];
|
|
|
|
if (cid == id)
|
|
|
|
return true;
|
|
|
|
// iterate through superclasses of object
|
|
|
|
for (; c.super != NO_CLASS_ID; c = classes[c.super]) {
|
|
|
|
if (c.super == id)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2017-03-11 01:00:02 +00:00
|
|
|
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
|
2017-03-11 01:00:02 +00:00
|
|
|
class_t Object_class;
|
2017-03-09 15:24:02 +00:00
|
|
|
|
2017-03-11 01:00:02 +00:00
|
|
|
void method(Object, destruct)(Object_t* obj) {
|
2017-03-09 15:24:02 +00:00
|
|
|
free(obj);
|
|
|
|
}
|
|
|
|
|
2017-03-11 01:00:02 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2017-03-11 01:00:02 +00:00
|
|
|
void method(Object, populate)(Object_t* obj, class_t type) {
|
2017-03-09 15:24:02 +00:00
|
|
|
obj->meta_obj.type = type;
|
2017-03-11 01:00:02 +00:00
|
|
|
add_method(obj, Object, destruct);
|
2017-03-07 22:52:11 +00:00
|
|
|
}
|