#include #include #include "graphics.h" /* virtual table for the virtual methods of gobject */ struct gobject_vtable { void (*print)(const struct gobject *); float (*area)(const struct gobject *); void (*translate)(struct gobject *, float x, float y); void (*destroy)(struct gobject *); }; /* * class gobject */ struct gobject { struct gobject_vtable * vtable; int id; }; static int gobject_counter = 0; void gobject_virtual_print(const struct gobject * this) { this->vtable->print(this); } float gobject_virtual_area(const struct gobject * this) { return this->vtable->area(this); } void gobject_virtual_translate(struct gobject * this, float x, float y) { this->vtable->translate(this, x, y); } void gobject_print(const struct gobject * this) { printf("basic object n. %d\n", this->id); } static void gobject_init(struct gobject * this) { this->id = gobject_counter++; } /* virtual destructor */ void gobject_virtual_destroy(struct gobject * this) { this->vtable->destroy(this); } void gobject_destroy(struct gobject * this) { free(this); } /* * class point (extends gobject) */ struct point { struct gobject base; int x,y; }; static struct gobject_vtable point_vtbl = { .print = point_print, .area = point_area, .translate = point_translate, .destroy = gobject_destroy }; struct point * point_new(float x, float y) { struct point * this = malloc(sizeof(struct point)); if (this) { gobject_init(&(this->base)); this->base.vtable = &point_vtbl; this->x = x; this->y = y; } return this; } void point_print(const struct gobject * o) { const struct point * this = (const struct point *)o; printf("point (%d,%d)\n", this->x, this->y); } void point_translate(struct gobject * o, float x, float y) { struct point * this = (struct point *)o; this->x += x; this->y += y; } float point_area(const struct gobject * x) { return 0; } /* * class rectangle extends gobject */ struct rectangle { struct gobject base; struct point bl; struct point tr; }; static struct gobject_vtable rectangle_vtbl = { .print = rectangle_print, .area = rectangle_area, .translate = rectangle_translate, .destroy = gobject_destroy }; struct rectangle * rectangle_new(float x1, float y1, float x2, float y2) { struct rectangle * this = malloc(sizeof(struct rectangle)); if (this) { gobject_init(&(this->base)); this->base.vtable = &rectangle_vtbl; this->bl.x = x1; this->bl.y = y1; this->tr.x = x2; this->tr.y = y2; } return this; } void rectangle_print(const struct gobject * o) { const struct rectangle * this = (const struct rectangle *)o; printf("rectangle (%d,%d)--(%d,%d)\n", this->bl.x, this->bl.y, this->tr.x, this->tr.y); } void rectangle_translate(struct gobject * o, float x, float y) { struct rectangle * this = (struct rectangle *)o; this->bl.x += x; this->bl.y += y; this->tr.x += x; this->tr.y += y; } float rectangle_area(const struct gobject * o) { const struct rectangle * this = (const struct rectangle *)o; return (this->tr.x - this->bl.x) * (this->tr.y - this->bl.y); }