summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 90d71a3)
raw | patch | inline | side by side (parent: 90d71a3)
author | mental <mental@users.sourceforge.net> | |
Thu, 15 May 2008 17:01:15 +0000 (17:01 +0000) | ||
committer | mental <mental@users.sourceforge.net> | |
Thu, 15 May 2008 17:01:15 +0000 (17:01 +0000) |
src/Makefile_insert | patch | blob | history | |
src/lifecycle.h | [new file with mode: 0644] | patch | blob |
diff --git a/src/Makefile_insert b/src/Makefile_insert
index f39ad098fd17258f1ad4b63db9d556b454c74ae8..62d6b92ce27fade88dc07c8ea0b9321060e2a1fe 100644 (file)
--- a/src/Makefile_insert
+++ b/src/Makefile_insert
gradient-chemistry.cpp gradient-chemistry.h \
ink-action.cpp \
ink-action.h \
+ lifecycle.h \
memeq.h \
round.h \
streq.h \
diff --git a/src/lifecycle.h b/src/lifecycle.h
--- /dev/null
+++ b/src/lifecycle.h
@@ -0,0 +1,134 @@
+/** \file
+ * Inkscape::Lifecycle - automatic object lifecycle management
+ *
+ * Copyright 2008 MenTaLguY <mental@rydia.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * See the file COPYING for details.
+ *
+ */
+
+#ifndef SEEN_INKSCAPE_LIFECYCLE_H
+#define SEEN_INKSCAPE_LIFECYCLE_H
+
+#include <glib/gtypes.h>
+#include <glib/gatomic.h>
+
+namespace Inkscape {
+namespace Lifecycle {
+
+class BaseManagedPtr;
+
+// Abstract base class for managed objects
+class AbstractManaged {
+public:
+ AbstractManaged() {}
+ virtual ~AbstractManaged() {}
+protected:
+ virtual void managedAddReference() const=0;
+ virtual void managedRemoveReference() const=0;
+ friend class BaseManagedPtr;
+private:
+ AbstractManaged(AbstractManaged &); // no copy
+ void operator=(AbstractManaged &); // no assign
+};
+
+// Base class for managed pointers; not intended for direct use
+class BaseManagedPtr {
+protected:
+ BaseManagedPtr() : ptr(NULL) {}
+ BaseManagedPtr(AbstractManaged const *managed) : ptr(NULL) {
+ set(managed);
+ }
+ BaseManagedPtr(BaseManagedPtr const &other) : ptr(NULL) {
+ set(other.ptr);
+ }
+
+ AbstractManaged const *get() const { return ptr; }
+ void set(AbstractManaged const *managed) {
+ if (managed) {
+ ptr->managedAddReference();
+ }
+ if (ptr) {
+ ptr->managedRemoveReference();
+ }
+ ptr = managed;
+ }
+
+private:
+ AbstractManaged const *ptr;
+};
+
+// Type-safe managed pointer
+template <typename T>
+class ManagedPtr : public BaseManagedPtr {
+public:
+ ManagedPtr() : BaseManagedPtr() {}
+ ManagedPtr(T *managed) : BaseManagedPtr(managed) {}
+ ManagedPtr(ManagedPtr const &other) : BaseManagedPtr(other) {}
+
+ operator T *() const { return get_recast(); }
+ T &operator*() const { return *get_recast(); }
+ T *operator->() const { return get_recast(); }
+ ManagedPtr &operator=(T *managed) {
+ set(managed);
+ return *this;
+ }
+ ManagedPtr &operator=(ManagedPtr const &other) {
+ set(other.get());
+ return *this;
+ }
+
+private:
+ T *get_recast() const {
+ return const_cast<T *>(static_cast<T const *>(get()));
+ }
+};
+
+// Dummy implementation of AbstractManaged to ease migration
+class DummyManaged : public virtual AbstractManaged {
+protected:
+ virtual void managedAddReference() const {}
+ virtual void managedRemoveReference() const {}
+};
+
+// Straightforward refcounting implementation of AbstractManaged
+class SimpleManaged : public virtual AbstractManaged {
+protected:
+ SimpleManaged() : refcount(0) {}
+ virtual ~SimpleManaged() {}
+
+ virtual void managedAddReference() const {
+ g_atomic_int_inc(&refcount);
+ }
+ virtual void managedRemoveReference() const {
+ if (g_atomic_int_dec_and_test(&refcount)) {
+ const_cast<SimpleManaged *>(this)->managedDispose();
+ }
+ }
+ virtual void managedDispose() {
+ delete this;
+ }
+
+private:
+ mutable volatile gint refcount;
+};
+
+}
+}
+
+#endif
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :