diff options
author | Neo2003 <none@none> | 2008-10-02 16:23:55 -0500 |
---|---|---|
committer | Neo2003 <none@none> | 2008-10-02 16:23:55 -0500 |
commit | 9b1c0e006f20091f28f3f468cfcab1feb51286bd (patch) | |
tree | b5d1ba94a656e6679f8737f9ea6bed1239b73b14 /src/framework/Utilities |
[svn] * Proper SVN structureinit
--HG--
branch : trunk
Diffstat (limited to 'src/framework/Utilities')
-rw-r--r-- | src/framework/Utilities/ByteConverter.h | 57 | ||||
-rw-r--r-- | src/framework/Utilities/Callback.h | 382 | ||||
-rw-r--r-- | src/framework/Utilities/CountedReference/Reference.h | 97 | ||||
-rw-r--r-- | src/framework/Utilities/CountedReference/ReferenceHolder.h | 39 | ||||
-rw-r--r-- | src/framework/Utilities/CountedReference/ReferenceImpl.h | 130 | ||||
-rw-r--r-- | src/framework/Utilities/EventProcessor.cpp | 88 | ||||
-rw-r--r-- | src/framework/Utilities/EventProcessor.h | 68 | ||||
-rw-r--r-- | src/framework/Utilities/HashMap.h | 63 | ||||
-rw-r--r-- | src/framework/Utilities/LinkedList.h | 216 | ||||
-rw-r--r-- | src/framework/Utilities/LinkedReference/RefManager.h | 53 | ||||
-rw-r--r-- | src/framework/Utilities/LinkedReference/Reference.h | 84 | ||||
-rw-r--r-- | src/framework/Utilities/TypeList.h | 43 |
12 files changed, 1320 insertions, 0 deletions
diff --git a/src/framework/Utilities/ByteConverter.h b/src/framework/Utilities/ByteConverter.h new file mode 100644 index 00000000000..fade287ed0a --- /dev/null +++ b/src/framework/Utilities/ByteConverter.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.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 MANGOS_BYTECONVERTER_H +#define MANGOS_BYTECONVERTER_H + +/** ByteConverter reverse your byte order. This is use + for cross platform where they have different endians. + */ + +#include<Platform/Define.h> +#include<algorithm> + +namespace ByteConverter +{ + template<size_t T> + inline void convert(char *val) + { + std::swap(*val, *(val + T - 1)); + convert<T - 2>(val + 1); + } + + template<> inline void convert<0>(char *) {} + template<> inline void convert<1>(char *) {} // ignore central byte + + template<typename T> inline void apply(T *val) + { + convert<sizeof(T)>((char *)(val)); + } +} + +#if MANGOS_ENDIAN == MANGOS_BIGENDIAN +template<typename T> inline void EndianConvert(T& val) { ByteConverter::apply<T>(&val); } +#else +template<typename T> inline void EndianConvert(T&) { } +#endif + +template<typename T> inline void EndianConvert(T*) { } +inline void EndianConvert(uint8&) { } +inline void EndianConvert( int8&) { } + +#endif diff --git a/src/framework/Utilities/Callback.h b/src/framework/Utilities/Callback.h new file mode 100644 index 00000000000..d794821a892 --- /dev/null +++ b/src/framework/Utilities/Callback.h @@ -0,0 +1,382 @@ +/* + * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.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 MANGOS_CALLBACK_H +#define MANGOS_CALLBACK_H + +/// ------------ BASE CLASSES ------------ + +namespace MaNGOS +{ + template < class Class, typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void, typename ParamType4 = void > + class _Callback + { + protected: + typedef void (Class::*Method)(ParamType1, ParamType2, ParamType3, ParamType4); + Class *m_object; + Method m_method; + ParamType1 m_param1; + ParamType2 m_param2; + ParamType3 m_param3; + ParamType4 m_param4; + void _Execute() { (m_object->*m_method)(m_param1, m_param2, m_param3, m_param4); } + public: + _Callback(Class *object, Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3, ParamType4 param4) + : m_object(object), m_method(method), m_param1(param1), m_param2(param2), m_param3(param3), m_param4(param4) {} + _Callback(_Callback < Class, ParamType1, ParamType2, ParamType3, ParamType4> const& cb) + : m_object(cb.object), m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2), m_param3(cb.m_param3), m_param4(cb.m_param4) {} + }; + + template < class Class, typename ParamType1, typename ParamType2, typename ParamType3 > + class _Callback < Class, ParamType1, ParamType2, ParamType3 > + { + protected: + typedef void (Class::*Method)(ParamType1, ParamType2, ParamType3); + Class *m_object; + Method m_method; + ParamType1 m_param1; + ParamType2 m_param2; + ParamType3 m_param3; + void _Execute() { (m_object->*m_method)(m_param1, m_param2, m_param3); } + public: + _Callback(Class *object, Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3) + : m_object(object), m_method(method), m_param1(param1), m_param2(param2) {} + _Callback(_Callback < Class, ParamType1, ParamType2, ParamType3 > const& cb) + : m_object(cb.object), m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2), m_param3(cb.m_param3) {} + }; + + template < class Class, typename ParamType1, typename ParamType2 > + class _Callback < Class, ParamType1, ParamType2 > + { + protected: + typedef void (Class::*Method)(ParamType1, ParamType2); + Class *m_object; + Method m_method; + ParamType1 m_param1; + ParamType2 m_param2; + void _Execute() { (m_object->*m_method)(m_param1, m_param2); } + public: + _Callback(Class *object, Method method, ParamType1 param1, ParamType2 param2) + : m_object(object), m_method(method), m_param1(param1), m_param2(param2) {} + _Callback(_Callback < Class, ParamType1, ParamType2 > const& cb) + : m_object(cb.m_object), m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2) {} + }; + + template < class Class, typename ParamType1 > + class _Callback < Class, ParamType1 > + { + protected: + typedef void (Class::*Method)(ParamType1); + Class *m_object; + Method m_method; + ParamType1 m_param1; + void _Execute() { (m_object->*m_method)(m_param1); } + public: + _Callback(Class *object, Method method, ParamType1 param1) + : m_object(object), m_method(method), m_param1(param1) {} + _Callback(_Callback < Class, ParamType1 > const& cb) + : m_object(cb.m_object), m_method(cb.m_method), m_param1(cb.m_param1) {} + }; + + template < class Class > + class _Callback < Class > + { + protected: + typedef void (Class::*Method)(); + Class *m_object; + Method m_method; + void _Execute() { (m_object->*m_method)(); } + public: + _Callback(Class *object, Method method) + : m_object(object), m_method(method) {} + _Callback(_Callback < Class > const& cb) + : m_object(cb.m_object), m_method(cb.m_method) {} + }; + + /// ---- Statics ---- + + template < typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void, typename ParamType4 = void > + class _SCallback + { + protected: + typedef void (*Method)(ParamType1, ParamType2, ParamType3, ParamType4); + Method m_method; + ParamType1 m_param1; + ParamType2 m_param2; + ParamType3 m_param3; + ParamType4 m_param4; + void _Execute() { (*m_method)(m_param1, m_param2, m_param3, m_param4); } + public: + _SCallback(Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3, ParamType4 param4) + : m_method(method), m_param1(param1), m_param2(param2), m_param3(param3), m_param4(param4) {} + _SCallback(_SCallback < ParamType1, ParamType2, ParamType3, ParamType4> const& cb) + : m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2), m_param3(cb.m_param3), m_param4(cb.m_param4) {} + }; + + template < typename ParamType1, typename ParamType2, typename ParamType3 > + class _SCallback < ParamType1, ParamType2, ParamType3 > + { + protected: + typedef void (*Method)(ParamType1, ParamType2, ParamType3); + Method m_method; + ParamType1 m_param1; + ParamType2 m_param2; + ParamType3 m_param3; + void _Execute() { (*m_method)(m_param1, m_param2, m_param3); } + public: + _SCallback(Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3) + : m_method(method), m_param1(param1), m_param2(param2) {} + _SCallback(_SCallback < ParamType1, ParamType2, ParamType3 > const& cb) + : m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2), m_param3(cb.m_param3) {} + }; + + template < typename ParamType1, typename ParamType2 > + class _SCallback < ParamType1, ParamType2 > + { + protected: + typedef void (*Method)(ParamType1, ParamType2); + Method m_method; + ParamType1 m_param1; + ParamType2 m_param2; + void _Execute() { (*m_method)(m_param1, m_param2); } + public: + _SCallback(Method method, ParamType1 param1, ParamType2 param2) + : m_method(method), m_param1(param1), m_param2(param2) {} + _SCallback(_SCallback < ParamType1, ParamType2 > const& cb) + : m_method(cb.m_method), m_param1(cb.m_param1), m_param2(cb.m_param2) {} + }; + + template < typename ParamType1 > + class _SCallback < ParamType1 > + { + protected: + typedef void (*Method)(ParamType1); + Method m_method; + ParamType1 m_param1; + void _Execute() { (*m_method)(m_param1); } + public: + _SCallback(Method method, ParamType1 param1) + : m_method(method), m_param1(param1) {} + _SCallback(_SCallback < ParamType1 > const& cb) + : m_method(cb.m_method), m_param1(cb.m_param1) {} + }; + + template < > + class _SCallback < > + { + protected: + typedef void (*Method)(); + Method m_method; + void _Execute() { (*m_method)(); } + public: + _SCallback(Method method) + : m_method(method) {} + _SCallback(_SCallback <> const& cb) + : m_method(cb.m_method) {} + }; +} + +/// --------- GENERIC CALLBACKS ---------- + +namespace MaNGOS +{ + class ICallback + { + public: + virtual void Execute() = 0; + virtual ~ICallback() {} + }; + + template < class CB > + class _ICallback : public CB, public ICallback + { + public: + _ICallback(CB const& cb) : CB(cb) {} + void Execute() { CB::_Execute(); } + }; + + template < class Class, typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void, typename ParamType4 = void > + class Callback : + public _ICallback< _Callback < Class, ParamType1, ParamType2, ParamType3, ParamType4 > > + { + private: + typedef _Callback < Class, ParamType1, ParamType2, ParamType3, ParamType4 > C4; + public: + Callback(Class *object, typename C4::Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3, ParamType4 param4) + : _ICallback< C4 >(C4(object, method, param1, param2, param3, param4)) {} + }; + + template < class Class, typename ParamType1, typename ParamType2, typename ParamType3 > + class Callback < Class, ParamType1, ParamType2, ParamType3 > : + public _ICallback< _Callback < Class, ParamType1, ParamType2, ParamType3 > > + { + private: + typedef _Callback < Class, ParamType1, ParamType2, ParamType3 > C3; + public: + Callback(Class *object, typename C3::Method method, ParamType1 param1, ParamType2 param2, ParamType3 param3) + : _ICallback< C3 >(C3(object, method, param1, param2, param3)) {} + }; + + template < class Class, typename ParamType1, typename ParamType2 > + class Callback < Class, ParamType1, ParamType2 > : + public _ICallback< _Callback < Class, ParamType1, ParamType2 > > + { + private: + typedef _Callback < Class, ParamType1, ParamType2 > C2; + public: + Callback(Class *object, typename C2::Method method, ParamType1 param1, ParamType2 param2) + : _ICallback< C2 >(C2(object, method, param1, param2)) {} + }; + + template < class Class, typename ParamType1 > + class Callback < Class, ParamType1 > : + public _ICallback< _Callback < Class, ParamType1 > > + { + private: + typedef _Callback < Class, ParamType1 > C1; + public: + Callback(Class *object, typename C1::Method method, ParamType1 param1) + : _ICallback< C1 >(C1(object, method, param1)) {} + }; + + template < class Class > + class Callback < Class > : public _ICallback< _Callback < Class > > + { + private: + typedef _Callback < Class > C0; + public: + Callback(Class *object, typename C0::Method method) + : _ICallback< C0 >(C0(object, method)) {} + }; +} + +/// ---------- QUERY CALLBACKS ----------- + +class QueryResult; + +namespace MaNGOS +{ + class IQueryCallback + { + public: + virtual void Execute() = 0; + virtual ~IQueryCallback() {} + virtual void SetResult(QueryResult* result) = 0; + virtual QueryResult* GetResult() = 0; + }; + + template < class CB > + class _IQueryCallback : public CB, public IQueryCallback + { + public: + _IQueryCallback(CB const& cb) : CB(cb) {} + void Execute() { CB::_Execute(); } + void SetResult(QueryResult* result) { CB::m_param1 = result; } + QueryResult* GetResult() { return CB::m_param1; } + }; + + template < class Class, typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void > + class QueryCallback : + public _IQueryCallback< _Callback < Class, QueryResult*, ParamType1, ParamType2, ParamType3 > > + { + private: + typedef _Callback < Class, QueryResult*, ParamType1, ParamType2, ParamType3 > QC3; + public: + QueryCallback(Class *object, typename QC3::Method method, QueryResult* result, ParamType1 param1, ParamType2 param2, ParamType3 param3) + : _IQueryCallback< QC3 >(QC3(object, method, result, param1, param2, param3)) {} + }; + + template < class Class, typename ParamType1, typename ParamType2 > + class QueryCallback < Class, ParamType1, ParamType2 > : + public _IQueryCallback< _Callback < Class, QueryResult*, ParamType1, ParamType2 > > + { + private: + typedef _Callback < Class, QueryResult*, ParamType1, ParamType2 > QC2; + public: + QueryCallback(Class *object, typename QC2::Method method, QueryResult* result, ParamType1 param1, ParamType2 param2) + : _IQueryCallback< QC2 >(QC2(object, method, result, param1, param2)) {} + }; + + template < class Class, typename ParamType1 > + class QueryCallback < Class, ParamType1 > : + public _IQueryCallback< _Callback < Class, QueryResult*, ParamType1 > > + { + private: + typedef _Callback < Class, QueryResult*, ParamType1 > QC1; + public: + QueryCallback(Class *object, typename QC1::Method method, QueryResult* result, ParamType1 param1) + : _IQueryCallback< QC1 >(QC1(object, method, result, param1)) {} + }; + + template < class Class > + class QueryCallback < Class > : public _IQueryCallback< _Callback < Class, QueryResult* > > + { + private: + typedef _Callback < Class, QueryResult* > QC0; + public: + QueryCallback(Class *object, typename QC0::Method method, QueryResult* result) + : _IQueryCallback< QC0 >(QC0(object, method, result)) {} + }; + + /// ---- Statics ---- + + template < typename ParamType1 = void, typename ParamType2 = void, typename ParamType3 = void > + class SQueryCallback : + public _IQueryCallback< _SCallback < QueryResult*, ParamType1, ParamType2, ParamType3 > > + { + private: + typedef _SCallback < QueryResult*, ParamType1, ParamType2, ParamType3 > QC3; + public: + SQueryCallback(typename QC3::Method method, QueryResult* result, ParamType1 param1, ParamType2 param2, ParamType3 param3) + : _IQueryCallback< QC3 >(QC3(method, result, param1, param2, param3)) {} + }; + + template < typename ParamType1, typename ParamType2 > + class SQueryCallback < ParamType1, ParamType2 > : + public _IQueryCallback< _SCallback < QueryResult*, ParamType1, ParamType2 > > + { + private: + typedef _SCallback < QueryResult*, ParamType1, ParamType2 > QC2; + public: + SQueryCallback(typename QC2::Method method, QueryResult* result, ParamType1 param1, ParamType2 param2) + : _IQueryCallback< QC2 >(QC2(method, result, param1, param2)) {} + }; + + template < typename ParamType1 > + class SQueryCallback < ParamType1 > : + public _IQueryCallback< _SCallback < QueryResult*, ParamType1 > > + { + private: + typedef _SCallback < QueryResult*, ParamType1 > QC1; + public: + SQueryCallback(typename QC1::Method method, QueryResult* result, ParamType1 param1) + : _IQueryCallback< QC1 >(QC1(method, result, param1)) {} + }; + + template < > + class SQueryCallback < > : public _IQueryCallback< _SCallback < QueryResult* > > + { + private: + typedef _SCallback < QueryResult* > QC0; + public: + SQueryCallback(QC0::Method method, QueryResult* result) + : _IQueryCallback< QC0 >(QC0(method, result)) {} + }; +} + +#endif diff --git a/src/framework/Utilities/CountedReference/Reference.h b/src/framework/Utilities/CountedReference/Reference.h new file mode 100644 index 00000000000..581c6399a1b --- /dev/null +++ b/src/framework/Utilities/CountedReference/Reference.h @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.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 MANGOS_REFERENCE_H +#define MANGOS_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 = MaNGOS::SingleThreaded<T> +> +class MANGOS_DLL_DECL 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/framework/Utilities/CountedReference/ReferenceHolder.h b/src/framework/Utilities/CountedReference/ReferenceHolder.h new file mode 100644 index 00000000000..5387b14107a --- /dev/null +++ b/src/framework/Utilities/CountedReference/ReferenceHolder.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.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 MANGOS_REFERENCEHOLDER_H +#define MANGOS_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/framework/Utilities/CountedReference/ReferenceImpl.h b/src/framework/Utilities/CountedReference/ReferenceImpl.h new file mode 100644 index 00000000000..dffd05c52c4 --- /dev/null +++ b/src/framework/Utilities/CountedReference/ReferenceImpl.h @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.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 MANGOS_REFERENCEIMPL_H +#define MANGOS_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 diff --git a/src/framework/Utilities/EventProcessor.cpp b/src/framework/Utilities/EventProcessor.cpp new file mode 100644 index 00000000000..55581ff7f8c --- /dev/null +++ b/src/framework/Utilities/EventProcessor.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.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 + */ + +#include "EventProcessor.h" + +EventProcessor::EventProcessor() +{ + m_time = 0; + m_aborting = false; +} + +EventProcessor::~EventProcessor() +{ + KillAllEvents(); +} + +void EventProcessor::Update(uint32 p_time) +{ + // update time + m_time += p_time; + + // main event loop + EventList::iterator i; + while (((i = m_events.begin()) != m_events.end()) && i->first <= m_time) + { + // get and remove event from queue + BasicEvent* Event = i->second; + m_events.erase(i); + + if (!Event->to_Abort) + { + if (Event->Execute(m_time, p_time)) + { + // completely destroy event if it is not re-added + delete Event; + } + } + else + { + Event->Abort(m_time); + delete Event; + } + } +} + +void EventProcessor::KillAllEvents() +{ + // prevent event insertions + m_aborting = true; + + // first, abort all existing events + for (EventList::iterator i = m_events.begin(); i != m_events.end(); ++i) + { + i->second->to_Abort = true; + i->second->Abort(m_time); + delete i->second; + } + + // clear event list + m_events.clear(); +} + +void EventProcessor::AddEvent(BasicEvent* Event, uint64 e_time, bool set_addtime) +{ + if (set_addtime) Event->m_addTime = m_time; + Event->m_execTime = e_time; + m_events.insert(std::pair<uint64, BasicEvent*>(e_time, Event)); +} + +uint64 EventProcessor::CalculateTime(uint64 t_offset) +{ + return(m_time + t_offset); +} diff --git a/src/framework/Utilities/EventProcessor.h b/src/framework/Utilities/EventProcessor.h new file mode 100644 index 00000000000..d0a94ce08ae --- /dev/null +++ b/src/framework/Utilities/EventProcessor.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.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 __EVENTPROCESSOR_H +#define __EVENTPROCESSOR_H + +#include "Platform/Define.h" + +#include<map> + +// Note. All times are in milliseconds here. + +class BasicEvent +{ + public: + BasicEvent() { to_Abort = false; } + virtual ~BasicEvent() // override destructor to perform some actions on event removal + { + }; + + // this method executes when the event is triggered + // return false if event does not want to be deleted + // e_time is execution time, p_time is update interval + virtual bool Execute(uint64 /*e_time*/, uint32 /*p_time*/) { return true; } + + virtual void Abort(uint64 /*e_time*/) {} // this method executes when the event is aborted + + bool to_Abort; // set by externals when the event is aborted, aborted events don't execute + // and get Abort call when deleted + + // these can be used for time offset control + uint64 m_addTime; // time when the event was added to queue, filled by event handler + uint64 m_execTime; // planned time of next execution, filled by event handler +}; + +typedef std::multimap<uint64, BasicEvent*> EventList; + +class EventProcessor +{ + public: + EventProcessor(); + ~EventProcessor(); + + void Update(uint32 p_time); + void KillAllEvents(); + void AddEvent(BasicEvent* Event, uint64 e_time, bool set_addtime = true); + uint64 CalculateTime(uint64 t_offset); + protected: + uint64 m_time; + EventList m_events; + bool m_aborting; +}; +#endif diff --git a/src/framework/Utilities/HashMap.h b/src/framework/Utilities/HashMap.h new file mode 100644 index 00000000000..2f887bd1943 --- /dev/null +++ b/src/framework/Utilities/HashMap.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.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 MANGOS_HASHMAP_H +#define MANGOS_HASHMAP_H + +#include "Platform/CompilerDefs.h" +#include "Platform/Define.h" + +#if COMPILER == COMPILER_INTEL +#include <ext/hash_map> +#elif COMPILER == COMPILER_GNU && __GNUC__ >= 3 +#include <ext/hash_map> +#else +#include <hash_map> +#endif + +#ifdef _STLPORT_VERSION +#define HM_NAMESPACE std +using std::hash_map; +#elif COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1300 +#define HM_NAMESPACE stdext +using stdext::hash_map; +#elif COMPILER == COMPILER_INTEL +#define HM_NAMESPACE std +using std::hash_map; +#elif COMPILER == COMPILER_GNU && __GNUC__ >= 3 +#define HM_NAMESPACE __gnu_cxx +using __gnu_cxx::hash_map; + +namespace __gnu_cxx +{ + template<> struct hash<unsigned long long> + { + size_t operator()(const unsigned long long &__x) const { return (size_t)__x; } + }; + template<typename T> struct hash<T *> + { + size_t operator()(T * const &__x) const { return (size_t)__x; } + }; + +}; + +#else +#define HM_NAMESPACE std +using std::hash_map; +#endif +#endif diff --git a/src/framework/Utilities/LinkedList.h b/src/framework/Utilities/LinkedList.h new file mode 100644 index 00000000000..3686c12c34c --- /dev/null +++ b/src/framework/Utilities/LinkedList.h @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.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 _LINKEDLIST +#define _LINKEDLIST + +#include "Common.h" + +//============================================ +class LinkedListHead; + +class LinkedListElement +{ + private: + friend class LinkedListHead; + + LinkedListElement* iNext; + LinkedListElement* iPrev; + public: + LinkedListElement() { iNext = NULL; iPrev = NULL; } + ~LinkedListElement() { delink(); } + + bool hasNext() const { return(iNext->iNext != NULL); } + bool hasPrev() const { return(iPrev->iPrev != NULL); } + bool isInList() const { return(iNext != NULL && iPrev != NULL); } + + LinkedListElement * next() { return hasNext() ? iNext : NULL; } + LinkedListElement const* next() const { return hasNext() ? iNext : NULL; } + LinkedListElement * prev() { return hasPrev() ? iPrev : NULL; } + LinkedListElement const* prev() const { return hasPrev() ? iPrev : NULL; } + + void delink() + { + if(isInList()) + { + iNext->iPrev = iPrev; iPrev->iNext = iNext; iNext = NULL; iPrev = NULL; + } + } + + void insertBefore(LinkedListElement* pElem) + { + pElem->iNext = this; + pElem->iPrev = iPrev; + iPrev->iNext = pElem; + iPrev = pElem; + } + + void insertAfter(LinkedListElement* pElem) + { + pElem->iPrev = this; + pElem->iNext = iNext; + iNext->iPrev = pElem; + iNext = pElem; + } +}; + +//============================================ + +class LinkedListHead +{ + private: + LinkedListElement iFirst; + LinkedListElement iLast; + uint32 iSize; + public: + LinkedListHead() + { + // create empty list + + iFirst.iNext = &iLast; + iLast.iPrev = &iFirst; + iSize = 0; + } + + bool isEmpty() const { return(!iFirst.iNext->isInList()); } + + LinkedListElement * getFirst() { return(isEmpty() ? NULL : iFirst.iNext); } + LinkedListElement const* getFirst() const { return(isEmpty() ? NULL : iFirst.iNext); } + + LinkedListElement * getLast() { return(isEmpty() ? NULL : iLast.iPrev); } + LinkedListElement const* getLast() const { return(isEmpty() ? NULL : iLast.iPrev); } + + void insertFirst(LinkedListElement* pElem) + { + iFirst.insertAfter(pElem); + } + + void insertLast(LinkedListElement* pElem) + { + iLast.insertBefore(pElem); + } + + uint32 getSize() const + { + if(!iSize) + { + uint32 result = 0; + LinkedListElement const* e = getFirst(); + while(e) + { + ++result; + e = e->next(); + } + return result; + } + else + return iSize; + } + + void incSize() { ++iSize; } + void decSize() { --iSize; } + + template<class _Ty> + class Iterator + { + public: + typedef std::bidirectional_iterator_tag iterator_category; + typedef _Ty value_type; + typedef ptrdiff_t difference_type; + typedef ptrdiff_t distance_type; + typedef _Ty* pointer; + typedef _Ty& reference; + + Iterator() : _Ptr(0) + { // construct with null node pointer + } + + Iterator(pointer _Pnode) : _Ptr(_Pnode) + { // construct with node pointer _Pnode + } + + reference operator*() + { // return designated value + return *_Ptr; + } + + pointer operator->() + { // return pointer to class object + return _Ptr; + } + + Iterator& operator++() + { // preincrement + _Ptr = _Ptr->next(); + return (*this); + } + + Iterator operator++(int) + { // postincrement + iterator _Tmp = *this; + ++*this; + return (_Tmp); + } + + Iterator& operator--() + { // predecrement + _Ptr = _Ptr->prev(); + return (*this); + } + + Iterator operator--(int) + { // postdecrement + iterator _Tmp = *this; + --*this; + return (_Tmp); + } + + bool operator==(Iterator const &_Right) const + { // test for iterator equality + return (_Ptr == _Right._Ptr); + } + + bool operator!=(Iterator const &_Right) const + { // test for iterator inequality + return (!(*this == _Right)); + } + + bool operator==(pointer const &_Right) const + { // test for pointer equality + return (_Ptr != _Right); + } + + bool operator!=(pointer const &_Right) const + { // test for pointer equality + return (!(*this == _Right)); + } + + pointer _Mynode() + { // return node pointer + return (_Ptr); + } + + protected: + pointer _Ptr; // pointer to node + }; + + typedef Iterator<LinkedListElement> iterator; +}; + +//============================================ +#endif diff --git a/src/framework/Utilities/LinkedReference/RefManager.h b/src/framework/Utilities/LinkedReference/RefManager.h new file mode 100644 index 00000000000..4e71ec7f2ed --- /dev/null +++ b/src/framework/Utilities/LinkedReference/RefManager.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.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 _REFMANAGER_H +#define _REFMANAGER_H +//===================================================== + +#include "Utilities/LinkedList.h" +#include "Utilities/LinkedReference/Reference.h" + +template <class TO, class FROM> class RefManager : public LinkedListHead +{ + public: + typedef LinkedListHead::Iterator< Reference<TO, FROM> > iterator; + RefManager() { } + virtual ~RefManager() { clearReferences(); } + + Reference<TO, FROM>* getFirst() { return ((Reference<TO, FROM>*) LinkedListHead::getFirst()); } + Reference<TO, FROM>* getLast() { return ((Reference<TO, FROM>*) LinkedListHead::getLast()); } + + iterator begin() { return iterator(getFirst()); } + iterator end() { return iterator(NULL); } + iterator rbegin() { return iterator(getLast()); } + iterator rend() { return iterator(NULL); } + + void clearReferences() + { + LinkedListElement* ref; + while((ref = getFirst()) != NULL) + { + ((Reference<TO, FROM>*) ref)->invalidate(); + ref->delink(); // the delink might be already done by invalidate(), but doing it here again does not hurt and insures an empty list + } + } +}; + +//===================================================== +#endif diff --git a/src/framework/Utilities/LinkedReference/Reference.h b/src/framework/Utilities/LinkedReference/Reference.h new file mode 100644 index 00000000000..682bfd82162 --- /dev/null +++ b/src/framework/Utilities/LinkedReference/Reference.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.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 _REFERENCE_H +#define _REFERENCE_H + +#include "Utilities/LinkedList.h" + +//===================================================== + +template <class TO, class FROM> class Reference : public LinkedListElement +{ + private: + TO* iRefTo; + FROM* iRefFrom; + protected: + // Tell our refTo (target) object that we have a link + virtual void targetObjectBuildLink() = 0; + + // Tell our refTo (taget) object, that the link is cut + virtual void targetObjectDestroyLink() = 0; + + // Tell our refFrom (source) object, that the link is cut (Target destroyed) + virtual void sourceObjectDestroyLink() = 0; + public: + Reference() { iRefTo = NULL; iRefFrom = NULL; } + virtual ~Reference() {} + + // Create new link + inline void link(TO* toObj, FROM* fromObj) + { + assert(fromObj); // fromObj MUST not be NULL + if(isValid()) + unlink(); + if(toObj != NULL) + { + iRefTo = toObj; + iRefFrom = fromObj; + targetObjectBuildLink(); + } + } + + // We don't need the reference anymore. Call comes from the refFrom object + // Tell our refTo object, that the link is cut + inline void unlink() { targetObjectDestroyLink(); delink(); iRefTo = NULL; iRefFrom = NULL; } + + // Link is invalid due to destruction of referenced target object. Call comes from the refTo object + // Tell our refFrom object, that the link is cut + inline void invalidate() // the iRefFrom MUST remain!! + { + sourceObjectDestroyLink(); delink(); iRefTo = NULL; + } + + inline bool isValid() const // Only check the iRefTo + { + return iRefTo != NULL; + } + + Reference<TO,FROM>* next() { return((Reference<TO,FROM>*)LinkedListElement::next()); } + Reference<TO,FROM>* prev() { return((Reference<TO,FROM>*)LinkedListElement::prev()); } + + inline TO* operator ->() const { return iRefTo; } + inline TO* getTarget() const { return iRefTo; } + + inline FROM* getSource() const { return iRefFrom; } +}; + +//===================================================== +#endif diff --git a/src/framework/Utilities/TypeList.h b/src/framework/Utilities/TypeList.h new file mode 100644 index 00000000000..074f5eb2483 --- /dev/null +++ b/src/framework/Utilities/TypeList.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.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 MANGOS_TYPELIST_H +#define MANGOS_TYPELIST_H + +/* + @struct TypeList + TypeList is the most simple but yet the most powerfull class of all. It holds + at compile time the different type of objects in a linked list. + */ + +class TypeNull; + +template<typename HEAD, typename TAIL> +struct TypeList +{ + typedef HEAD Head; + typedef TAIL Tail; +}; + +// enough for now.. can be expand at any point in time as needed +#define TYPELIST_1(T1) TypeList<T1,TypeNull> +#define TYPELIST_2(T1, T2) TypeList<T1, TYPELIST_1(T2) > +#define TYPELIST_3(T1, T2, T3) TypeList<T1, TYPELIST_2(T2, T3) > +#define TYPELIST_4(T1, T2, T3, T4) TypeList<T1, TYPELIST_3(T2, T3, T4) > +#define TYPELIST_5(T1, T2, T3, T4, T5) TypeList<T1, TYPELIST_4(T2, T3, T4, T5) > +#endif |