From 81df0f1c8c7f6053aa0708753426a8fa604fc8a3 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Fri, 20 May 2022 10:36:53 +0200 Subject: Changed example shape.c --- examples/shape.c | 82 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 37 deletions(-) diff --git a/examples/shape.c b/examples/shape.c index 69c8ca70..db42adf3 100644 --- a/examples/shape.c +++ b/examples/shape.c @@ -4,13 +4,13 @@ #include #include -#define c_self(s, T, api) \ - T* self = (T *)s; \ - assert(*s == &T##_##api) +#define c_self(s, T) \ + T* self = c_container_of(s, T, base); \ + assert(s->api == &T##_api) -#define c_vtable(Interface, T, api) \ - c_static_assert(offsetof(T, api) == 0); \ - static Interface T##_##api +#define c_vtable(Api, T) \ + c_static_assert(offsetof(T, base) == 0); \ + static Api T##_api // Shape definition @@ -18,19 +18,27 @@ typedef struct { float x, y; } Point; -typedef struct Shape { - void (*drop)(struct Shape**); - void (*draw)(struct Shape**); +typedef struct { + struct ShapeAPI* api; + uint32_t color; + uint16_t style; + uint8_t thickness; + uint8_t hardness; } Shape; -void Shape_drop(Shape** shape) +struct ShapeAPI { + void (*drop)(Shape*); + void (*draw)(const Shape*); +}; + +void Shape_drop(Shape* shape) { } -void Shape_delete(Shape** shape) +void Shape_delete(Shape* shape) { if (shape) { - (*shape)->drop(shape); + shape->api->drop(shape); c_free(shape); } } @@ -39,31 +47,31 @@ void Shape_delete(Shape** shape) // ============================================================ typedef struct { - Shape* api; + Shape base; Point p[3]; } Triangle; -c_vtable(Shape, Triangle, api); +c_vtable(struct ShapeAPI, Triangle); -static void Triangle_draw(Shape** shape) +static void Triangle_draw(const Shape* shape) { - const c_self(shape, Triangle, api); + const c_self(shape, Triangle); printf("Triangle: (%g,%g), (%g,%g), (%g,%g)\n", self->p[0].x, self->p[0].y, self->p[1].x, self->p[1].y, self->p[2].x, self->p[2].y); } -static Shape Triangle_api = { +static struct ShapeAPI Triangle_api = { .drop = Shape_drop, .draw = Triangle_draw, }; -Shape** Triangle_new(Point a, Point b, Point c) +Shape* Triangle_new(Point a, Point b, Point c) { - Triangle* s = c_new(Triangle, {&Triangle_api, .p={a, b, c}}); - return &s->api; + Triangle* s = c_new(Triangle, {{.api=&Triangle_api}, .p={a, b, c}}); + return &s->base; } // Polygon implementation @@ -74,43 +82,43 @@ Shape** Triangle_new(Point a, Point b, Point c) #include typedef struct { - Shape* api; + Shape base; PVec points; } Polygon; -c_vtable(Shape, Polygon, api); +c_vtable(struct ShapeAPI, Polygon); -static void Polygon_drop(Shape** shape) +static void Polygon_drop(Shape* shape) { - c_self(shape, Polygon, api); + c_self(shape, Polygon); puts("drop poly"); PVec_drop(&self->points); } -static void Polygon_draw(Shape** shape) +static void Polygon_draw(const Shape* shape) { - const c_self(shape, Polygon, api); + const c_self(shape, Polygon); printf("Polygon:"); c_foreach (i, PVec, self->points) printf(" (%g,%g)", i.ref->x, i.ref->y); puts(""); } -static Shape Polygon_api = { +static struct ShapeAPI Polygon_api = { .drop = Polygon_drop, .draw = Polygon_draw, }; -Shape** Polygon_new(void) +Shape* Polygon_new(void) { - Polygon* s = c_new(Polygon, {&Polygon_api, .points=PVec_init()}); - return &s->api; + Polygon* s = c_new(Polygon, {{.api=&Polygon_api}, .points=PVec_init()}); + return &s->base; } -void Polygon_addPoint(Shape** shape, Point p) +void Polygon_addPoint(Shape* shape, Point p) { - c_self(shape, Polygon, api); + c_self(shape, Polygon); PVec_push(&self->points, p); } @@ -118,13 +126,13 @@ void Polygon_addPoint(Shape** shape, Point p) // Test // ============================================================ -void testShape(Shape** shape) +void testShape(Shape* shape) { - (*shape)->draw(shape); + shape->api->draw(shape); } #define i_type Shapes -#define i_val Shape** +#define i_val Shape* #define i_opt c_no_clone #define i_valdrop(x) Shape_delete(*x) #include @@ -133,8 +141,8 @@ int main(void) { c_auto (Shapes, shapes) { - Shape** tria = Triangle_new((Point){5, 7}, (Point){12, 7}, (Point){12, 20}); - Shape** poly = Polygon_new(); + Shape* tria = Triangle_new((Point){5, 7}, (Point){12, 7}, (Point){12, 20}); + Shape* poly = Polygon_new(); c_apply(p, Polygon_addPoint(poly, p), Point, { {5, 7}, {12, 7}, {12, 20}, {82, 33}, {17, 56}, -- cgit v1.2.3