From a64f9e671936451d7a3a60191dcca6e37e97e585 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Thu, 9 Jul 2009 21:03:16 +0000 Subject: Implement removing/inserting in the middle of a dmnsn_array*. --- libdimension/dimension/array.h | 28 ++++++++++++++++++++++++++++ libdimensionxx/dimensionxx/scene.hpp | 11 ++++++++--- libdimensionxx/scene.cpp | 17 +++++++++++++++++ 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/libdimension/dimension/array.h b/libdimension/dimension/array.h index c12ff9f..d835d60 100644 --- a/libdimension/dimension/array.h +++ b/libdimension/dimension/array.h @@ -139,4 +139,32 @@ dmnsn_array_pop(dmnsn_array *array, void *obj) dmnsn_array_resize(array, size - 1); /* Shrink the array */ } +/* Insert an item into the middle of the array */ +DMNSN_INLINE void +dmnsn_array_insert(dmnsn_array *array, size_t i, const void *obj) +{ + size_t size = dmnsn_array_size(array); + /* Increase the size by 1 */ + dmnsn_array_resize(array, size + 1); + /* Move the elements at and after `i' 1 to the right */ + memmove((char *)array->ptr + array->obj_size*(i + 1), + (char *)array->ptr + array->obj_size*i, + array->obj_size*(size - i)); + /* Insert `obj' at `i' */ + memcpy((char *)array->ptr + array->obj_size*i, obj, array->obj_size); +} + +/* Remove an item from the middle of the array */ +DMNSN_INLINE void +dmnsn_array_remove(dmnsn_array *array, size_t i) +{ + size_t size = dmnsn_array_size(array); + /* Move the array elements after `i' 1 to the left */ + memmove((char *)array->ptr + array->obj_size*i, + (char *)array->ptr + array->obj_size*(i + 1), + array->obj_size*(size - i)); + /* Decrease the size by 1 */ + dmnsn_array_resize(array, size - 1); +} + #endif /* DIMENSION_ARRAY_H */ diff --git a/libdimensionxx/dimensionxx/scene.hpp b/libdimensionxx/dimensionxx/scene.hpp index 73cbc2e..acb2cb1 100644 --- a/libdimensionxx/dimensionxx/scene.hpp +++ b/libdimensionxx/dimensionxx/scene.hpp @@ -25,7 +25,7 @@ namespace Dimension { - // Iterator class for scene objects + // Iterator class for scene objects - never invalidated unless removed class Scene_Iterator; // Base scene class. Wraps a dmnsn_scene*. @@ -55,6 +55,7 @@ namespace Dimension Iterator end(); void push_object(Object& object); + void remove_object(Iterator i); // Access the wrapped C object. dmnsn_scene* dmnsn(); @@ -72,8 +73,10 @@ namespace Dimension class Scene_Iterator { + typedef std::list >::iterator Iterator; + public: - Scene_Iterator(std::list >::iterator i) + Scene_Iterator(Iterator i) : m_i(i) { } // Scene_Iterator(const Scene_Iterator& i); // ~Scene_Iterator(); @@ -91,8 +94,10 @@ namespace Dimension Scene_Iterator& operator--() { --m_i; return *this; } Scene_Iterator operator--(int) { return Scene_Iterator(m_i--); } + Iterator iterator() const { return m_i; } + private: - std::list >::iterator m_i; + Iterator m_i; }; } diff --git a/libdimensionxx/scene.cpp b/libdimensionxx/scene.cpp index 4ff19e1..1bff351 100644 --- a/libdimensionxx/scene.cpp +++ b/libdimensionxx/scene.cpp @@ -99,6 +99,23 @@ namespace Dimension dmnsn_array_push(dmnsn()->objects, &cobject); } + // Remove an object + void + Scene::remove_object(Iterator i) + { + // Find it in the dmnsn_array* of objects and remove it + for (unsigned int j = 0; j < dmnsn_array_size(dmnsn()->objects); ++j) { + dmnsn_object* cobject; + dmnsn_array_get(dmnsn()->objects, j, &cobject); + if (cobject == i->dmnsn()) { + dmnsn_array_remove(dmnsn()->objects, j); + break; + } + } + // Remove it from the std::list + m_objects.erase(i.iterator()); + } + // Access the wrapped C object. dmnsn_scene* -- cgit v1.2.3