summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2009-07-09 21:03:16 +0000
committerTavian Barnes <tavianator@gmail.com>2009-07-09 21:03:16 +0000
commita64f9e671936451d7a3a60191dcca6e37e97e585 (patch)
treef95182c1fc24b972bd4a7dd5dae4ba6a7175de83
parent9a634a53f0d7135ef82e6888a89091db173c7f7f (diff)
downloaddimension-a64f9e671936451d7a3a60191dcca6e37e97e585.tar.xz
Implement removing/inserting in the middle of a dmnsn_array*.
-rw-r--r--libdimension/dimension/array.h28
-rw-r--r--libdimensionxx/dimensionxx/scene.hpp11
-rw-r--r--libdimensionxx/scene.cpp17
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<std::tr1::shared_ptr<Object> >::iterator Iterator;
+
public:
- Scene_Iterator(std::list<std::tr1::shared_ptr<Object> >::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<std::tr1::shared_ptr<Object> >::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*