From 8f01c5394dcce8f5d4e7102dacfcdea9d1f7b021 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Thu, 16 Jul 2009 01:16:09 +0000 Subject: Add destructor callbacks for polymorphic C types, and use their base dmnsn_delete_*() function. --- libdimension/camera.c | 13 +++++++++++-- libdimension/cameras.c | 15 +++------------ libdimension/canvas.c | 1 + libdimension/dimension.h | 3 +++ libdimension/dimension/camera.h | 13 ++++--------- libdimension/dimension/cameras.h | 1 - libdimension/dimension/canvas.h | 6 ++++-- libdimension/dimension/object.h | 5 +++++ libdimension/dimension/objects.h | 2 -- libdimension/dimension/pigments.h | 1 - libdimension/dimension/texture.h | 4 ++++ libdimension/object.c | 10 ++++++++-- libdimension/objects.c | 14 -------------- libdimension/pigments.c | 9 --------- libdimension/texture.c | 12 ++++++++++-- libdimensionxx/camera.cpp | 8 ++++++-- libdimensionxx/cameras.cpp | 8 -------- libdimensionxx/dimensionxx/camera.hpp | 2 +- libdimensionxx/dimensionxx/cameras.hpp | 2 +- libdimensionxx/dimensionxx/object.hpp | 2 +- libdimensionxx/dimensionxx/objects.hpp | 4 ++-- libdimensionxx/object.cpp | 8 ++++++-- libdimensionxx/objects.cpp | 16 ---------------- tests/tests.c | 12 ++++++------ 24 files changed, 76 insertions(+), 95 deletions(-) diff --git a/libdimension/camera.c b/libdimension/camera.c index 5a321ef..dfa14e6 100644 --- a/libdimension/camera.c +++ b/libdimension/camera.c @@ -25,12 +25,21 @@ dmnsn_camera * dmnsn_new_camera() { - return malloc(sizeof(dmnsn_camera)); + dmnsn_camera *camera = malloc(sizeof(dmnsn_camera)); + if (camera) { + camera->free_fn = NULL; + } + return camera; } /* Free a dummy camera */ void dmnsn_delete_camera(dmnsn_camera *camera) { - free(camera); + if (camera) { + if (camera->free_fn) { + (*camera->free_fn)(camera->ptr); + } + free(camera); + } } diff --git a/libdimension/cameras.c b/libdimension/cameras.c index 1ab1360..dfe4708 100644 --- a/libdimension/cameras.c +++ b/libdimension/cameras.c @@ -39,8 +39,6 @@ dmnsn_new_perspective_camera(dmnsn_matrix trans) dmnsn_matrix *ptr; dmnsn_camera *camera = dmnsn_new_camera(); if (camera) { - camera->ray_fn = &dmnsn_perspective_camera_ray_fn; - /* Allocate room for the transformation matrix */ ptr = malloc(sizeof(dmnsn_matrix)); if (!ptr) { @@ -49,18 +47,11 @@ dmnsn_new_perspective_camera(dmnsn_matrix trans) } *ptr = trans; camera->ptr = ptr; - } - return camera; -} -/* Delete a perspective camera */ -void -dmnsn_delete_perspective_camera(dmnsn_camera *camera) -{ - if (camera) { - free(camera->ptr); - dmnsn_delete_camera(camera); + camera->ray_fn = &dmnsn_perspective_camera_ray_fn; + camera->free_fn = &free; } + return camera; } /* Get the transformation matrix */ diff --git a/libdimension/canvas.c b/libdimension/canvas.c index 2933259..9329a07 100644 --- a/libdimension/canvas.c +++ b/libdimension/canvas.c @@ -64,6 +64,7 @@ dmnsn_delete_canvas(dmnsn_canvas *canvas) (*optimizer.free_fn)(optimizer.ptr); } } + dmnsn_delete_array(canvas->optimizers); /* Free the pixels and canvas */ free(canvas->pixels); diff --git a/libdimension/dimension.h b/libdimension/dimension.h index 0c6ae26..4cc29ab 100644 --- a/libdimension/dimension.h +++ b/libdimension/dimension.h @@ -56,6 +56,9 @@ extern "C" { #endif +/* Common types */ +typedef void dmnsn_free_fn(void *ptr); + /* Include all the libdimension headers */ #include #include diff --git a/libdimension/dimension/camera.h b/libdimension/dimension/camera.h index 13c03b0..3e6da4f 100644 --- a/libdimension/dimension/camera.h +++ b/libdimension/dimension/camera.h @@ -34,20 +34,15 @@ typedef dmnsn_line dmnsn_camera_ray_fn(const dmnsn_camera *camera, unsigned int x, unsigned int y); struct dmnsn_camera { + /* Callback functions */ + dmnsn_camera_ray_fn *ray_fn; + dmnsn_free_fn *free_fn; + /* Generic pointer for camera info */ void *ptr; - - /* Callback function */ - dmnsn_camera_ray_fn *ray_fn; }; dmnsn_camera *dmnsn_new_camera(); void dmnsn_delete_camera(dmnsn_camera *camera); -/* A perspective camera, at the origin, looking at (0, 0, 1). The feild of view - is the section of the plane z = 1 from (-0.5, -0.5) to (0.5, 0.5). Rays are - transformed by the transformation matrix `trans'. */ -dmnsn_camera *dmnsn_new_perspective_camera(dmnsn_matrix trans); -void dmnsn_delete_perspective_camera(dmnsn_camera *camera); - #endif /* DIMENSION_CAMERA_H */ diff --git a/libdimension/dimension/cameras.h b/libdimension/dimension/cameras.h index 1793bbd..b135693 100644 --- a/libdimension/dimension/cameras.h +++ b/libdimension/dimension/cameras.h @@ -29,7 +29,6 @@ is the section of the plane z = 1 from (-0.5, -0.5) to (0.5, 0.5). Rays are transformed by the transformation matrix `trans'. */ dmnsn_camera *dmnsn_new_perspective_camera(dmnsn_matrix trans); -void dmnsn_delete_perspective_camera(dmnsn_camera *camera); /* Get or set the transformation matrix */ dmnsn_matrix dmnsn_get_perspective_camera_trans(const dmnsn_camera *camera); diff --git a/libdimension/dimension/canvas.h b/libdimension/dimension/canvas.h index 05a9a62..0d37acf 100644 --- a/libdimension/dimension/canvas.h +++ b/libdimension/dimension/canvas.h @@ -47,12 +47,14 @@ typedef struct dmnsn_canvas_optimizer dmnsn_canvas_optimizer; typedef void dmnsn_canvas_optimizer_fn(dmnsn_canvas *canvas, dmnsn_canvas_optimizer optimizer, unsigned int x, unsigned int y); -typedef void dmnsn_canvas_optimizer_free_fn(void *ptr); /* Canvas optimizer */ struct dmnsn_canvas_optimizer { + /* Callback types */ dmnsn_canvas_optimizer_fn *optimizer_fn; - dmnsn_canvas_optimizer_free_fn *free_fn; + dmnsn_free_fn *free_fn; + + /* Generic pointer */ void *ptr; }; diff --git a/libdimension/dimension/object.h b/libdimension/dimension/object.h index 2da3ac7..901b366 100644 --- a/libdimension/dimension/object.h +++ b/libdimension/dimension/object.h @@ -34,7 +34,9 @@ typedef dmnsn_array *dmnsn_object_intersections_fn(const dmnsn_object *object, typedef int dmnsn_object_inside_fn(const dmnsn_object *object, dmnsn_vector point); +/* dmnsn_object definition */ struct dmnsn_object { + /* Surface properties */ dmnsn_texture *texture; /* Transformation matrix */ @@ -43,6 +45,7 @@ struct dmnsn_object { /* Callback functions */ dmnsn_object_intersections_fn *intersections_fn; dmnsn_object_inside_fn *inside_fn; + dmnsn_free_fn *free_fn; /* Generic pointer for object info */ void *ptr; @@ -50,6 +53,8 @@ struct dmnsn_object { /* Allocate a dummy object */ dmnsn_object *dmnsn_new_object(); + +/* Free an object */ void dmnsn_delete_object(dmnsn_object *object); #endif /* DIMENSION_OBJECT_H */ diff --git a/libdimension/dimension/objects.h b/libdimension/dimension/objects.h index d8c4144..4a24ca7 100644 --- a/libdimension/dimension/objects.h +++ b/libdimension/dimension/objects.h @@ -27,10 +27,8 @@ /* A sphere object, of radius 1, centered at the origin. */ dmnsn_object *dmnsn_new_sphere(); -void dmnsn_delete_sphere(dmnsn_object *sphere); /* A cube, axis-aligned, from (-1, -1, -1) to (1, 1, 1) */ dmnsn_object *dmnsn_new_cube(); -void dmnsn_delete_cube(dmnsn_object *cube); #endif /* DIMENSION_OBJECTS_H */ diff --git a/libdimension/dimension/pigments.h b/libdimension/dimension/pigments.h index ed0c3b2..61d50d8 100644 --- a/libdimension/dimension/pigments.h +++ b/libdimension/dimension/pigments.h @@ -27,6 +27,5 @@ /* A solid color */ dmnsn_pigment *dmnsn_new_solid_pigment(dmnsn_color color); -void dmnsn_delete_solid_pigment(dmnsn_pigment *pigment); #endif /* DIMENSION_PIGMENTS_H */ diff --git a/libdimension/dimension/texture.h b/libdimension/dimension/texture.h index 2eabe84..c26e840 100644 --- a/libdimension/dimension/texture.h +++ b/libdimension/dimension/texture.h @@ -38,7 +38,11 @@ typedef dmnsn_color dmnsn_pigment_fn(const dmnsn_pigment *pigment, /* dmnsn_pigment definition */ struct dmnsn_pigment { + /* Callbacks */ dmnsn_pigment_fn *pigment_fn; + dmnsn_free_fn *free_fn; + + /* Generic pointer */ void *ptr; }; diff --git a/libdimension/object.c b/libdimension/object.c index 0556921..6b248ff 100644 --- a/libdimension/object.c +++ b/libdimension/object.c @@ -28,7 +28,8 @@ dmnsn_new_object() dmnsn_object *object = malloc(sizeof(dmnsn_object)); if (object) { object->texture = NULL; - object->trans = dmnsn_identity_matrix(); + object->trans = dmnsn_identity_matrix(); + object->free_fn = NULL; } return object; } @@ -37,5 +38,10 @@ dmnsn_new_object() void dmnsn_delete_object(dmnsn_object *object) { - free(object); + if (object) { + if (object->free_fn) { + (*object->free_fn)(object->ptr); + } + free(object); + } } diff --git a/libdimension/objects.c b/libdimension/objects.c index 8f45c0e..32d3fdd 100644 --- a/libdimension/objects.c +++ b/libdimension/objects.c @@ -44,13 +44,6 @@ dmnsn_new_sphere() return sphere; } -/* Free a sphere */ -void -dmnsn_delete_sphere(dmnsn_object *sphere) -{ - dmnsn_delete_object(sphere); -} - /* Return a list of insersections of `line' with a sphere */ static dmnsn_array * dmnsn_sphere_intersections_fn(const dmnsn_object *sphere, dmnsn_line line) @@ -103,13 +96,6 @@ dmnsn_new_cube() return cube; } -/* Delete a cube */ -void -dmnsn_delete_cube(dmnsn_object *cube) -{ - dmnsn_delete_object(cube); -} - /* Intersections callback for a cube */ static dmnsn_array * dmnsn_cube_intersections_fn(const dmnsn_object *cube, dmnsn_line line) diff --git a/libdimension/pigments.c b/libdimension/pigments.c index 3b417f6..22f75e8 100644 --- a/libdimension/pigments.c +++ b/libdimension/pigments.c @@ -46,15 +46,6 @@ dmnsn_new_solid_pigment(dmnsn_color color) return pigment; } -/* Destroy a solid color */ -void dmnsn_delete_solid_pigment(dmnsn_pigment *pigment) -{ - if (pigment) { - free(pigment->ptr); - dmnsn_delete_pigment(pigment); - } -} - /* Solid color callback */ static dmnsn_color dmnsn_solid_pigment_fn(const dmnsn_pigment *pigment, dmnsn_vector v) diff --git a/libdimension/texture.c b/libdimension/texture.c index 511c6b0..f232cbc 100644 --- a/libdimension/texture.c +++ b/libdimension/texture.c @@ -25,7 +25,11 @@ dmnsn_pigment * dmnsn_new_pigment() { - return malloc(sizeof(dmnsn_pigment)); + dmnsn_pigment *pigment = malloc(sizeof(dmnsn_pigment)); + if (pigment) { + pigment->free_fn = NULL; + } + return pigment; } /* Free a dummy pigment */ @@ -39,7 +43,11 @@ dmnsn_delete_pigment(dmnsn_pigment *pigment) dmnsn_texture * dmnsn_new_texture() { - return malloc(sizeof(dmnsn_texture)); + dmnsn_texture *texture = malloc(sizeof(dmnsn_texture)); + if (texture) { + texture->pigment = NULL; + } + return texture; } /* Free a dummy texture */ diff --git a/libdimensionxx/camera.cpp b/libdimensionxx/camera.cpp index b44173c..5786055 100644 --- a/libdimensionxx/camera.cpp +++ b/libdimensionxx/camera.cpp @@ -22,9 +22,13 @@ namespace Dimension { - // Virtual no-op destructor + // Virtual destructor Camera::~Camera() - { } + { + if (unique()) { + dmnsn_delete_camera(dmnsn()); + } + } // Return the result of the dmnsn_camera*'s ray callback Line diff --git a/libdimensionxx/cameras.cpp b/libdimensionxx/cameras.cpp index ca571be..5d84c4f 100644 --- a/libdimensionxx/cameras.cpp +++ b/libdimensionxx/cameras.cpp @@ -31,14 +31,6 @@ namespace Dimension } } - // Delete a perspective camera, if we're the last reference - Perspective_Camera::~Perspective_Camera() - { - if (unique()) { - dmnsn_delete_perspective_camera(dmnsn()); - } - } - // Get the transformation matrix Matrix Perspective_Camera::trans() diff --git a/libdimensionxx/dimensionxx/camera.hpp b/libdimensionxx/dimensionxx/camera.hpp index d8743ce..fa13a7e 100644 --- a/libdimensionxx/dimensionxx/camera.hpp +++ b/libdimensionxx/dimensionxx/camera.hpp @@ -29,7 +29,7 @@ namespace Dimension class Camera { public: - // No-op + // Delete the camera virtual ~Camera(); // Camera callback diff --git a/libdimensionxx/dimensionxx/cameras.hpp b/libdimensionxx/dimensionxx/cameras.hpp index 1764ac5..364ea4c 100644 --- a/libdimensionxx/dimensionxx/cameras.hpp +++ b/libdimensionxx/dimensionxx/cameras.hpp @@ -30,7 +30,7 @@ namespace Dimension { public: Perspective_Camera(const Matrix& trans); - ~Perspective_Camera(); + // ~Perspective_Camera(); // Get/set the transformation matrix Matrix trans(); diff --git a/libdimensionxx/dimensionxx/object.hpp b/libdimensionxx/dimensionxx/object.hpp index 30dadf8..6505162 100644 --- a/libdimensionxx/dimensionxx/object.hpp +++ b/libdimensionxx/dimensionxx/object.hpp @@ -29,7 +29,7 @@ namespace Dimension class Object { public: - // No-op + // Delete the object virtual ~Object(); // Get/set the transformation matrix diff --git a/libdimensionxx/dimensionxx/objects.hpp b/libdimensionxx/dimensionxx/objects.hpp index f86b2b3..15c072b 100644 --- a/libdimensionxx/dimensionxx/objects.hpp +++ b/libdimensionxx/dimensionxx/objects.hpp @@ -30,7 +30,7 @@ namespace Dimension { public: Sphere(); - ~Sphere(); + // ~Sphere(); // Shallow-copy the sphere Object* copy(); @@ -46,7 +46,7 @@ namespace Dimension { public: Cube(); - ~Cube(); + // ~Cube(); // Shallow-copy the cube Object* copy(); diff --git a/libdimensionxx/object.cpp b/libdimensionxx/object.cpp index e5384db..9c28e22 100644 --- a/libdimensionxx/object.cpp +++ b/libdimensionxx/object.cpp @@ -22,9 +22,13 @@ namespace Dimension { - // Virtual no-op destructor + // Virtual destructor Object::~Object() - { } + { + if (unique()) { + dmnsn_delete_object(dmnsn()); + } + } // Get the transformation matrix Matrix diff --git a/libdimensionxx/objects.cpp b/libdimensionxx/objects.cpp index 2272586..7bedd92 100644 --- a/libdimensionxx/objects.cpp +++ b/libdimensionxx/objects.cpp @@ -31,14 +31,6 @@ namespace Dimension } } - // Delete a sphere - Sphere::~Sphere() - { - if (unique()) { - dmnsn_delete_sphere(dmnsn()); - } - } - // Shallow copy a sphere Object* Sphere::copy() @@ -60,14 +52,6 @@ namespace Dimension } } - // Delete a sphere - Cube::~Cube() - { - if (unique()) { - dmnsn_delete_cube(dmnsn()); - } - } - // Shallow copy a cube Object* Cube::copy() diff --git a/tests/tests.c b/tests/tests.c index 8743119..218fcfd 100644 --- a/tests/tests.c +++ b/tests/tests.c @@ -76,7 +76,7 @@ dmnsn_new_default_scene() sphere = dmnsn_new_sphere(); if (!sphere) { - dmnsn_delete_perspective_camera(scene->camera); + dmnsn_delete_camera(scene->camera); dmnsn_delete_canvas(scene->canvas); dmnsn_delete_scene(scene); return NULL; @@ -89,8 +89,8 @@ dmnsn_new_default_scene() cube = dmnsn_new_cube(); if (!cube) { - dmnsn_delete_sphere(sphere); - dmnsn_delete_perspective_camera(scene->camera); + dmnsn_delete_object(sphere); + dmnsn_delete_camera(scene->camera); dmnsn_delete_canvas(scene->canvas); dmnsn_delete_scene(scene); return NULL; @@ -113,9 +113,9 @@ dmnsn_delete_default_scene(dmnsn_scene *scene) dmnsn_array_get(scene->objects, 0, &sphere); dmnsn_array_get(scene->objects, 1, &cube); - dmnsn_delete_cube(cube); - dmnsn_delete_sphere(sphere); - dmnsn_delete_perspective_camera(scene->camera); + dmnsn_delete_object(cube); + dmnsn_delete_object(sphere); + dmnsn_delete_camera(scene->camera); dmnsn_delete_canvas(scene->canvas); dmnsn_delete_scene(scene); } -- cgit v1.2.3