aboutsummaryrefslogtreecommitdiff
path: root/src/server/shared/Dynamic/CountedReference
diff options
context:
space:
mode:
authorXTZGZoReX <none@none>2010-06-06 23:44:21 +0200
committerXTZGZoReX <none@none>2010-06-06 23:44:21 +0200
commit22950963e908017eefaccf0592feed29238f943b (patch)
treec94cfcb4e07f5b0212101e3b3c25487ef4202369 /src/server/shared/Dynamic/CountedReference
parent1170c67a70dbda204cafb72ed80402f18af3b9a6 (diff)
* Get rid of framework and move the files to game and shared.
--HG-- branch : trunk
Diffstat (limited to 'src/server/shared/Dynamic/CountedReference')
-rw-r--r--src/server/shared/Dynamic/CountedReference/Reference.h100
-rw-r--r--src/server/shared/Dynamic/CountedReference/ReferenceHolder.h42
-rw-r--r--src/server/shared/Dynamic/CountedReference/ReferenceImpl.h133
3 files changed, 275 insertions, 0 deletions
diff --git a/src/server/shared/Dynamic/CountedReference/Reference.h b/src/server/shared/Dynamic/CountedReference/Reference.h
new file mode 100644
index 00000000000..d3cfe55ffc0
--- /dev/null
+++ b/src/server/shared/Dynamic/CountedReference/Reference.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef TRINITY_REFERENCE_H
+#define TRINITY_REFERENCE_H
+
+/**
+ * Referencer<T>
+ * Referencer is an object that holds a reference holder that hold a reference
+ * counted object. When an object's reference count drop to zero, it removes
+ * the object. This is a non intrusive mechanism and any object at any point
+ * in time can be referenced. When and object is reference counted, do not
+ * pass the object directly to other methods but rather, pass its
+ * reference around. Objects can be reference counted in both single threaded
+ * model and multi-threaded model
+ */
+
+#include <stdexcept>
+#include "Platform/Define.h"
+#include "Policies/ThreadingModel.h"
+#include "ReferenceHolder.h"
+
+template
+<
+typename T,
+class THREADING_MODEL = Trinity::SingleThreaded<T>
+>
+class Referencer
+{
+ typedef typename THREADING_MODEL::Lock Lock;
+ typedef ReferenceHolder<T, THREADING_MODEL> ReferenceeHolder;
+ public:
+
+ /// Constructs a referencer.
+ Referencer(T *ref = NULL);
+
+ /// Copy constructor
+ Referencer(const Referencer &obj) : i_holder(NULL) { *this = obj; }
+
+ /// Destructor
+ ~Referencer();
+
+ /// Referencee accessor
+ T* referencee(void) { return (i_holder == NULL ? NULL : i_holder->i_referencee); }
+ const T* referencee(void) const { return (i_holder == NULL ? NULL : i_holder->i_referencee); }
+
+ //T& referencee(void){ return _referencee(); }
+ //const T& referencee(void) const { return const_cast<Referencer *>(this)->_referencee(); }
+ operator T&(void) { return _referencee(); }
+ operator const T&(void) const { return *const_cast<Referencer *>(this)->_referencee(); }
+
+ /// cast operators
+ T* operator*() { return (i_holder == NULL ? NULL : i_holder->i_referencee); }
+ T const * operator*() const { return (i_holder == NULL ? NULL : i_holder->i_referencee); }
+
+ /// overload operators
+ T* operator->() { return (i_holder == NULL ? NULL : i_holder->i_referencee); }
+ const T * operator->() const { return (i_holder == NULL ? NULL : i_holder->i_referencee); }
+
+ /// operator =
+ Referencer& operator=(const Referencer &obj);
+ Referencer& operator=(T *);
+
+ /// returns true if i_referencee is null
+ bool isNull(void) const { return i_holder == NULL; }
+
+ private:
+
+ T& _referencee(void)
+ {
+ if( i_holder == NULL )
+ throw std::runtime_error("Invalid access to null pointer");
+ return *i_holder->i_referencee;
+ }
+
+ void deReference(ReferenceeHolder *);
+ void addReference(ReferenceeHolder *);
+
+ // private data
+ ReferenceeHolder *i_holder;
+};
+#endif
+
diff --git a/src/server/shared/Dynamic/CountedReference/ReferenceHolder.h b/src/server/shared/Dynamic/CountedReference/ReferenceHolder.h
new file mode 100644
index 00000000000..597e9854be0
--- /dev/null
+++ b/src/server/shared/Dynamic/CountedReference/ReferenceHolder.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef TRINITY_REFERENCEHOLDER_H
+#define TRINITY_REFERENCEHOLDER_H
+
+/** ReferenceHolder holds the actualy referenced obejct as well the refence
+ count. The ReferenecHolder implements as a policy base object and
+ will decided by the Reference class to be consnsitent.
+ */
+
+template
+<
+typename T,
+class THREADING_MODEL
+>
+struct ReferenceHolder : public THREADING_MODEL
+{
+ explicit ReferenceHolder(T *ref) : i_referencee(ref), i_referenceCount(0) {}
+ T *i_referencee;
+ unsigned int i_referenceCount;
+ typedef typename THREADING_MODEL::Lock Lock;
+};
+#endif
+
diff --git a/src/server/shared/Dynamic/CountedReference/ReferenceImpl.h b/src/server/shared/Dynamic/CountedReference/ReferenceImpl.h
new file mode 100644
index 00000000000..cde330179e3
--- /dev/null
+++ b/src/server/shared/Dynamic/CountedReference/ReferenceImpl.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef TRINITY_REFERENCEIMPL_H
+#define TRINITY_REFERENCEIMPL_H
+
+#include "Reference.h"
+
+template
+<
+typename T,
+class THREADING_MODEL
+>
+Referencer<T, THREADING_MODEL>::Referencer(T *ref)
+: i_holder(NULL)
+{
+ if( ref != NULL )
+ {
+ i_holder = new ReferenceeHolder(ref);
+ ++i_holder->i_referenceCount;
+ }
+}
+
+template
+<
+typename T,
+class THREADING_MODEL
+>
+Referencer<T, THREADING_MODEL>::~Referencer()
+{
+ if( i_holder != NULL )
+ deReference(i_holder);
+ i_holder = NULL;
+}
+
+template
+<
+typename T,
+class THREADING_MODEL
+>
+Referencer<T, THREADING_MODEL>&
+Referencer<T, THREADING_MODEL>::operator=(const Referencer<T, THREADING_MODEL> &obj)
+{
+ if( i_holder != NULL )
+ deReference(i_holder);
+ if( obj.i_holder != NULL )
+ addReference(obj.i_holder);
+ i_holder = obj.i_holder;
+ return *this;
+}
+
+template
+<
+typename T,
+class THREADING_MODEL
+>
+Referencer<T, THREADING_MODEL>&
+Referencer<T, THREADING_MODEL>::operator=(T *ref)
+{
+ if( i_holder != NULL )
+ deReference(i_holder);
+ i_holder = NULL;
+ if( ref != NULL )
+ {
+ i_holder = new ReferenceeHolder(ref);
+ ++i_holder->i_referenceCount;
+ }
+
+ return *this;
+}
+
+template
+<
+typename T,
+class THREADING_MODEL
+>
+void
+Referencer<T, THREADING_MODEL>::deReference(ReferenceHolder<T, THREADING_MODEL> *holder)
+{
+ assert( holder != NULL && holder->i_referenceCount > 0);
+ bool delete_object = false;
+
+ {
+ // The guard is within the scope due to the guard
+ // must release earlier than expected.
+ Lock guard(*holder);
+ Guard(&guard);
+
+ --holder->i_referenceCount;
+ if( holder->i_referenceCount == 0 )
+ delete_object = true;
+ }
+
+ if( delete_object )
+ {
+ delete holder->i_referencee;
+ delete holder;
+ }
+}
+
+template
+<
+typename T,
+class THREADING_MODEL
+>
+void
+Referencer<T, THREADING_MODEL>::addReference(ReferenceHolder<T, THREADING_MODEL> *holder)
+{
+ assert( i_holder != NULL );
+ Lock guard(*holder);
+ Guard(&guard);
+
+ ++holder->i_referenceCount;
+}
+#endif
+