[Scummvm-cvs-logs] SF.net SVN: scummvm: [31287] scummvm/trunk

lordhoto at users.sourceforge.net lordhoto at users.sourceforge.net
Fri Mar 28 07:04:00 CET 2008


Revision: 31287
          http://scummvm.svn.sourceforge.net/scummvm/?rev=31287&view=rev
Author:   lordhoto
Date:     2008-03-27 23:03:59 -0700 (Thu, 27 Mar 2008)

Log Message:
-----------
Committed shared pointer implementation of patch #1895703 "COMMON: Managed List".
Unlike the patch on the tracker this commit includes documentation for SharedPtr.

Modified Paths:
--------------
    scummvm/trunk/engines/kyra/module.mk
    scummvm/trunk/engines/kyra/resource.cpp
    scummvm/trunk/engines/kyra/resource.h

Added Paths:
-----------
    scummvm/trunk/common/ptr.h
    scummvm/trunk/test/common/ptr.h

Added: scummvm/trunk/common/ptr.h
===================================================================
--- scummvm/trunk/common/ptr.h	                        (rev 0)
+++ scummvm/trunk/common/ptr.h	2008-03-28 06:03:59 UTC (rev 31287)
@@ -0,0 +1,165 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ */
+
+#ifndef COMMON_PTR_H
+#define COMMON_PTR_H
+
+#include "common/scummsys.h"
+
+namespace Common {
+
+/**
+ * A simple shared pointer implementation modelled after boost.
+ *
+ * This object keeps track of the assigned pointer and automatically
+ * frees it when no more SharedPtr references to it exist.
+ *
+ * To achieve that the object implements an internal reference counting.
+ * Thus you should try to avoid using the plain pointer after assigning
+ * it to a SharedPtr object for the first time. If you still use the
+ * plain pointer be sure you do not delete it on your own. You may also 
+ * not use the plain pointer to create a new SharedPtr object, since that
+ * would result in a double deletion of the pointer sooner or later.
+ *
+ * Example creation:
+ * Common::SharedPtr<int> pointer(new int(1));
+ * would create a pointer to int. Later on usage via *pointer is the same
+ * as for a normal pointer. If you need to access the plain pointer value
+ * itself later on use the get method. The class also supplies a operator
+ * ->, which does the same as the -> operator on a normal pointer.
+ *
+ * Be sure you are using new to initialize the pointer you want to manage.
+ * Pointers pointing to memory not allocated by new, will cause undefined
+ * behavior on deletion. That is for example the case on pointers created
+ * with malloc (or similar) and new[]. This prevents the use of SharedPtr
+ * for arrays!
+ *
+ * Note that you have to specify the type itself not the pointer type as
+ * template parameter. You also need to have a real definition of the type
+ * you want to use, a simple forward definition is not enough.
+ *
+ * The class has implicit upcast support, so if you got a class B derived
+ * from class A, you can assign a pointer to B without any problems to a
+ * SharedPtr object with template parameter A. The very same applies to 
+ * assigment of a SharedPtr<B> object to a SharedPtr<A> object.
+ *
+ * There are also operators != and == to compare two SharedPtr objects
+ * with compatible pointers.
+ */
+template<class T>
+class SharedPtr {
+	template<class T2> friend class SharedPtr;
+public:
+	typedef int RefValue;
+	typedef T ValueType;
+	typedef T *Pointer;
+
+	SharedPtr() : _refCount(0), _pointer(0) {}
+	template<class T2> explicit SharedPtr(T2 *p) : _refCount(new RefValue(1)), _pointer(p) {}
+
+	SharedPtr(const SharedPtr &r) : _refCount(r._refCount), _pointer(r._pointer) { if (_refCount) ++(*_refCount); }
+	template<class T2> SharedPtr(const SharedPtr<T2> &r) : _refCount(r._refCount), _pointer(r._pointer) { if (_refCount) ++(*_refCount); }
+
+	~SharedPtr() { decRef(); }
+
+	SharedPtr &operator =(const SharedPtr &r) {
+		if (r._refCount)
+			++(*r._refCount);
+		decRef();
+
+		_refCount = r._refCount;
+		_pointer = r._pointer;
+
+		return *this;
+	}
+
+	template<class T2>
+	SharedPtr &operator =(const SharedPtr<T2> &r) {
+		if (r._refCount)
+			++(*r._refCount);
+		decRef();
+
+		_refCount = r._refCount;
+		_pointer = r._pointer;
+
+		return *this;
+	}
+
+	ValueType &operator *() const { assert(_pointer); return *_pointer; }
+	Pointer operator ->() const { assert(_pointer); return _pointer; }
+
+	/**
+	 * Returns the plain pointer value. Be sure you know what you
+	 * do if you are continuing to use that pointer.
+	 *
+	 * @return the pointer the SharedPtr object manages
+	 */
+	Pointer get() const { return _pointer; }
+
+	operator bool() const { return _pointer != 0; }
+
+	/**
+	 * Checks if the SharedPtr object is the only object refering
+	 * to the assigned pointer. This should just be used for
+	 * debugging purposes.
+	 */
+	bool unique() const { return refCount() == 1; }
+
+	/**
+	 * Returns the number of references to the assigned pointer.
+	 * This should just be used for debugging purposes.
+	 */
+	RefValue refCount() const { return _refCount ? *_refCount : 0; }
+private:
+	void decRef() {
+		if (_refCount) {
+			--(*_refCount);
+			if (!*_refCount) {
+				delete _refCount;
+				delete _pointer;
+				_refCount = 0;
+				_pointer = 0;
+			}
+		}
+	}
+
+	RefValue *_refCount;
+	T *_pointer;
+};
+
+} // end of namespace Common
+
+template<class T1, class T2>
+bool operator ==(const Common::SharedPtr<T1> &l, const Common::SharedPtr<T2> &r) {
+	return l.get() == r.get();
+}
+
+template<class T1, class T2>
+bool operator !=(const Common::SharedPtr<T1> &l, const Common::SharedPtr<T2> &r) {
+	return l.get() != r.get();
+}
+
+
+#endif
+


Property changes on: scummvm/trunk/common/ptr.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + "Date Rev Author URL Id"
Name: svn:eol-style
   + native

Modified: scummvm/trunk/engines/kyra/module.mk
===================================================================
--- scummvm/trunk/engines/kyra/module.mk	2008-03-28 01:44:49 UTC (rev 31286)
+++ scummvm/trunk/engines/kyra/module.mk	2008-03-28 06:03:59 UTC (rev 31287)
@@ -5,6 +5,7 @@
 	animator_v2.o \
 	debugger.o \
 	detection.o \
+	gui.o \
 	gui_v1.o \
 	gui_v2.o \
 	items_v1.o \

Modified: scummvm/trunk/engines/kyra/resource.cpp
===================================================================
--- scummvm/trunk/engines/kyra/resource.cpp	2008-03-28 01:44:49 UTC (rev 31286)
+++ scummvm/trunk/engines/kyra/resource.cpp	2008-03-28 06:03:59 UTC (rev 31287)
@@ -29,7 +29,6 @@
 #include "common/file.h"
 #include "common/fs.h"
 #include "common/func.h"
-#include "common/algorithm.h"
 
 #include "gui/message.h"
 
@@ -43,8 +42,6 @@
 
 Resource::~Resource() {
 	unloadAllPakFiles();
-	for (LoaderIterator i = _loaders.begin(); i != _loaders.end(); ++i)
-		delete (*i);
 	_loaders.clear();
 }
 
@@ -666,17 +663,18 @@
 }
 
 void Resource::initializeLoaders() {
-	_loaders.push_back(new ResLoaderPak());
-	_loaders.push_back(new ResLoaderIns());
+	_loaders.push_back(LoaderList::value_type(new ResLoaderPak()));
+	_loaders.push_back(LoaderList::value_type(new ResLoaderIns()));
 }
 
 const ResArchiveLoader *Resource::getLoader(ResFileEntry::kType type) const {
 	for (CLoaderIterator i = _loaders.begin(); i != _loaders.end(); ++i) {
 		if ((*i)->getType() == type)
-			return *i;
+			return (*i).get();
 	}
 	return 0;
 }
 
 } // end of namespace Kyra
 
+

Modified: scummvm/trunk/engines/kyra/resource.h
===================================================================
--- scummvm/trunk/engines/kyra/resource.h	2008-03-28 01:44:49 UTC (rev 31286)
+++ scummvm/trunk/engines/kyra/resource.h	2008-03-28 06:03:59 UTC (rev 31287)
@@ -34,6 +34,7 @@
 #include "common/hash-str.h"
 #include "common/hashmap.h"
 #include "common/stream.h"
+#include "common/ptr.h"
 
 #include "kyra/kyra.h"
 
@@ -113,9 +114,10 @@
 
 	void initializeLoaders();
 	const ResArchiveLoader *getLoader(ResFileEntry::kType type) const;
-	typedef Common::List<ResArchiveLoader*>::iterator LoaderIterator;
-	typedef Common::List<ResArchiveLoader*>::const_iterator CLoaderIterator;
-	Common::List<ResArchiveLoader*> _loaders;
+	typedef Common::List<Common::SharedPtr<ResArchiveLoader> > LoaderList;
+	typedef LoaderList::iterator LoaderIterator;
+	typedef LoaderList::const_iterator CLoaderIterator;
+	LoaderList _loaders;
 	ResFileMap _map;
 
 	KyraEngine *_vm;
@@ -334,3 +336,4 @@
 #endif
 
 
+

Added: scummvm/trunk/test/common/ptr.h
===================================================================
--- scummvm/trunk/test/common/ptr.h	                        (rev 0)
+++ scummvm/trunk/test/common/ptr.h	2008-03-28 06:03:59 UTC (rev 31287)
@@ -0,0 +1,36 @@
+#include <cxxtest/TestSuite.h>
+
+#include "common/ptr.h"
+
+class PtrTestSuite : public CxxTest::TestSuite
+{
+	public:
+	void test_assign() {
+		Common::SharedPtr<int> p1(new int(1));
+		TS_ASSERT(p1.unique());
+		TS_ASSERT_EQUALS(*p1, 1);
+
+		{
+			Common::SharedPtr<int> p2 = p1;
+			TS_ASSERT(!p1.unique());
+			TS_ASSERT(p1.refCount() == p2.refCount());
+			TS_ASSERT(p1.refCount() == 2);
+			TS_ASSERT(p1 == p2);
+			TS_ASSERT_EQUALS(*p2, 1);
+			{
+				Common::SharedPtr<int> p3;
+				p3 = p2;
+				TS_ASSERT(p3 == p2 && p3 == p1);
+				TS_ASSERT(p1.refCount() == 3);
+				TS_ASSERT_EQUALS(*p3, 1);
+				*p3 = 0;
+				TS_ASSERT_EQUALS(*p3, 0);
+			}
+			TS_ASSERT_EQUALS(*p2, 0);
+			TS_ASSERT(p1.refCount() == 2);
+		}
+
+		TS_ASSERT_EQUALS(*p1, 0);
+		TS_ASSERT(p1.unique());
+	}
+};


Property changes on: scummvm/trunk/test/common/ptr.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + "Date Rev Author URL Id"
Name: svn:eol-style
   + native


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list