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 |
[svn] * Proper SVN structureinit
--HG--
branch : trunk
Diffstat (limited to 'src/framework')
33 files changed, 3397 insertions, 0 deletions
diff --git a/src/framework/Dynamic/FactoryHolder.h b/src/framework/Dynamic/FactoryHolder.h new file mode 100644 index 00000000000..7041c4ecbfa --- /dev/null +++ b/src/framework/Dynamic/FactoryHolder.h @@ -0,0 +1,60 @@ +/* + * 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_FACTORY_HOLDER +#define MANGOS_FACTORY_HOLDER + +#include "Platform/Define.h" +#include "Utilities/TypeList.h" +#include "ObjectRegistry.h" +#include "Policies/SingletonImp.h" + +/** FactoryHolder holds a factory object of a specific type + */ +template<class T, class Key = std::string> +class MANGOS_DLL_DECL FactoryHolder +{ + public: + typedef ObjectRegistry<FactoryHolder<T, Key >, Key > FactoryHolderRegistry; + typedef MaNGOS::Singleton<FactoryHolderRegistry > FactoryHolderRepository; + + FactoryHolder(Key k) : i_key(k) {} + virtual ~FactoryHolder() {} + inline Key key() const { return i_key; } + + void RegisterSelf(void) { FactoryHolderRepository::Instance().InsertItem(this, i_key); } + void DeregisterSelf(void) { FactoryHolderRepository::Instance().RemoveItem(this, false); } + + /// Abstract Factory create method + virtual T* Create(void *data = NULL) const = 0; + private: + Key i_key; +}; + +/** Permissible is a classic way of letting the object decide + * whether how good they handle things. This is not retricted + * to factory selectors. + */ +template<class T> +class Permissible +{ + public: + virtual ~Permissible() {} + virtual int Permit(const T *) const = 0; +}; +#endif diff --git a/src/framework/Dynamic/ObjectRegistry.h b/src/framework/Dynamic/ObjectRegistry.h new file mode 100644 index 00000000000..e0d885d2b9b --- /dev/null +++ b/src/framework/Dynamic/ObjectRegistry.h @@ -0,0 +1,107 @@ +/* + * 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_OBJECTREGISTRY_H +#define MANGOS_OBJECTREGISTRY_H + +#include "Platform/Define.h" +#include "Utilities/HashMap.h" +#include "Policies/Singleton.h" + +#include <string> +#include <map> + +/** ObjectRegistry holds all registry item of the same type + */ +template<class T, class Key = std::string> +class MANGOS_DLL_DECL ObjectRegistry +{ + public: + typedef std::map<Key, T *> RegistryMapType; + + /// Returns a registry item + const T* GetRegistryItem(Key key) const + { + typename RegistryMapType::const_iterator iter = i_registeredObjects.find(key); + return( iter == i_registeredObjects.end() ? NULL : iter->second ); + } + + /// Inserts a registry item + bool InsertItem(T *obj, Key key, bool override = false) + { + typename RegistryMapType::iterator iter = i_registeredObjects.find(key); + if( iter != i_registeredObjects.end() ) + { + if( !override ) + return false; + delete iter->second; + i_registeredObjects.erase(iter); + } + + i_registeredObjects[key] = obj; + return true; + } + + /// Removes a registry item + void RemoveItem(Key key, bool delete_object = true) + { + typename RegistryMapType::iterator iter = i_registeredObjects.find(key); + if( iter != i_registeredObjects.end() ) + { + if( delete_object ) + delete iter->second; + i_registeredObjects.erase(iter); + } + } + + /// Returns true if registry contains an item + bool HasItem(Key key) const + { + return (i_registeredObjects.find(key) != i_registeredObjects.end()); + } + + /// Inefficiently return a vector of registered items + unsigned int GetRegisteredItems(std::vector<Key> &l) const + { + unsigned int sz = l.size(); + l.resize(sz + i_registeredObjects.size()); + for(typename RegistryMapType::const_iterator iter = i_registeredObjects.begin(); iter != i_registeredObjects.end(); ++iter) + l[sz++] = iter->first; + return i_registeredObjects.size(); + } + + /// Return the map of registered items + RegistryMapType const &GetRegisteredItems() const + { + return i_registeredObjects; + } + + private: + RegistryMapType i_registeredObjects; + friend class MaNGOS::OperatorNew<ObjectRegistry<T, Key> >; + + // protected for friend use since it should be a singleton + ObjectRegistry() {} + ~ObjectRegistry() + { + for(typename RegistryMapType::iterator iter=i_registeredObjects.begin(); iter != i_registeredObjects.end(); ++iter) + delete iter->second; + i_registeredObjects.clear(); + } +}; +#endif diff --git a/src/framework/GameSystem/Grid.h b/src/framework/GameSystem/Grid.h new file mode 100644 index 00000000000..f4a274a51a6 --- /dev/null +++ b/src/framework/GameSystem/Grid.h @@ -0,0 +1,129 @@ +/* + * 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_GRID_H +#define MANGOS_GRID_H + +/* + @class Grid + Grid is a logical segment of the game world represented inside MaNGOS. + Grid is bind at compile time to a particular type of object which + we call it the object of interested. There are many types of loader, + specially, dynamic loader, static loader, or on-demand loader. There's + a subtle difference between dynamic loader and on-demand loader but + this is implementation specific to the loader class. From the + Grid's perspective, the loader meets its API requirement is suffice. +*/ + +#include "Platform/Define.h" +#include "Policies/ThreadingModel.h" +#include "TypeContainer.h" +#include "TypeContainerVisitor.h" + +// forward declaration +template<class A, class T, class O> class GridLoader; + +template +< +class ACTIVE_OBJECT, +class WORLD_OBJECT_TYPES, +class GRID_OBJECT_TYPES, +class ThreadModel = MaNGOS::SingleThreaded<ACTIVE_OBJECT> +> +class MANGOS_DLL_DECL Grid +{ + // allows the GridLoader to access its internals + template<class A, class T, class O> friend class GridLoader; + public: + + /** destructor to clean up its resources. This includes unloading the + grid if it has not been unload. + */ + ~Grid() {} + + /** an object of interested enters the grid + */ + template<class SPECIFIC_OBJECT> bool AddWorldObject(SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl) + { + return i_objects.template insert<SPECIFIC_OBJECT>(hdl, obj); + } + + /** an object of interested exits the grid + */ + template<class SPECIFIC_OBJECT> bool RemoveWorldObject(SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl) + { + return i_objects.template remove<SPECIFIC_OBJECT>(obj, hdl); + } + + /** Accessors: Returns a specific type of object in the WORDL_OBJECT_TYPES + */ + template<class SPECIFIC_OBJECT> const SPECIFIC_OBJECT* GetWorldObject(OBJECT_HANDLE hdl, SPECIFIC_OBJECT* fake) const { return i_objects.template find<SPECIFIC_OBJECT>(hdl); } + template<class SPECIFIC_OBJECT> SPECIFIC_OBJECT* GetWorldObject(OBJECT_HANDLE hdl, SPECIFIC_OBJECT *fake) { return i_objects.template find<SPECIFIC_OBJECT>(hdl, fake); } + + /** Refreshes/update the grid. This required for remote grids. + */ + void RefreshGrid(void) { /* TBI */} + + /** Locks a grid. Any object enters must wait until the grid is unlock. + */ + void LockGrid(void) { /* TBI */ } + + /** Unlocks the grid. + */ + void UnlockGrid(void) { /* TBI */ } + + /** Grid visitor for grid objects + */ + template<class T> void Visit(TypeContainerVisitor<T, TypeMapContainer<GRID_OBJECT_TYPES> > &visitor) + { + visitor.Visit(i_container); + } + + /** Grid visitor for world objects + */ + template<class T> void Visit(TypeContainerVisitor<T, TypeMapContainer<WORLD_OBJECT_TYPES> > &visitor) + { + visitor.Visit(i_objects); + } + + /** Returns the number of object within the grid. + */ + unsigned int ActiveObjectsInGrid(void) const { return i_objects.template Count<ACTIVE_OBJECT>(); } + + /** Accessors: Returns a specific type of object in the GRID_OBJECT_TYPES + */ + template<class SPECIFIC_OBJECT> const SPECIFIC_OBJECT* GetGridObject(OBJECT_HANDLE hdl, SPECIFIC_OBJECT *fake) const { return i_container.template find<SPECIFIC_OBJECT>(hdl, fake); } + template<class SPECIFIC_OBJECT> SPECIFIC_OBJECT* GetGridObject(OBJECT_HANDLE hdl, SPECIFIC_OBJECT *fake) { return i_container.template find<SPECIFIC_OBJECT>(hdl, fake); } + + /** Inserts a container type object into the grid. + */ + template<class SPECIFIC_OBJECT> bool AddGridObject(SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl) { return i_container.template insert<SPECIFIC_OBJECT>(hdl, obj); } + + /** Removes a containter type object from the grid + */ + template<class SPECIFIC_OBJECT> bool RemoveGridObject(SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl) { return i_container.template remove<SPECIFIC_OBJECT>(obj, hdl); } + + private: + + typedef typename ThreadModel::Lock Guard; + typedef typename ThreadModel::VolatileType VolatileType; + + TypeMapContainer<GRID_OBJECT_TYPES> i_container; + TypeMapContainer<WORLD_OBJECT_TYPES> i_objects; +}; +#endif diff --git a/src/framework/GameSystem/GridLoader.h b/src/framework/GameSystem/GridLoader.h new file mode 100644 index 00000000000..07982a613f5 --- /dev/null +++ b/src/framework/GameSystem/GridLoader.h @@ -0,0 +1,76 @@ +/* + * 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_GRIDLOADER_H +#define MANGOS_GRIDLOADER_H + +/** + @class GridLoader + The GridLoader is working in conjuction with the Grid and responsible + for loading and unloading object-types (one or more) when objects + enters a grid. Unloading is scheduled and might be canceled if + an interested object re-enters. GridLoader does not do the actuall + loading and unloading but implements as a template pattern that + delicate its loading and unloading for the actualy loader and unloader. + GridLoader manages the grid (both local and remote). + */ + +#include "Platform/Define.h" +#include "Grid.h" +#include "TypeContainerVisitor.h" + +template +< +class ACTIVE_OBJECT, +class WORLD_OBJECT_TYPES, +class GRID_OBJECT_TYPES +> +class MANGOS_DLL_DECL GridLoader +{ + public: + + /** Loads the grid + */ + template<class LOADER> + void Load(Grid<ACTIVE_OBJECT,WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES> &grid, LOADER &loader) + { + grid.LockGrid(); + loader.Load(grid); + grid.UnlockGrid(); + } + + /** Stop the grid + */ + template<class STOPER> + void Stop(Grid<ACTIVE_OBJECT,WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES> &grid, STOPER &stoper) + { + grid.LockGrid(); + stoper.Stop(grid); + grid.UnlockGrid(); + } + /** Unloads the grid + */ + template<class UNLOADER> + void Unload(Grid<ACTIVE_OBJECT,WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES> &grid, UNLOADER &unloader) + { + grid.LockGrid(); + unloader.Unload(grid); + grid.UnlockGrid(); + } +}; +#endif diff --git a/src/framework/GameSystem/GridRefManager.h b/src/framework/GameSystem/GridRefManager.h new file mode 100644 index 00000000000..fb402a1c6d3 --- /dev/null +++ b/src/framework/GameSystem/GridRefManager.h @@ -0,0 +1,41 @@ +/* + * 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 _GRIDREFMANAGER +#define _GRIDREFMANAGER + +#include "Utilities/LinkedReference/RefManager.h" + +template<class OBJECT> +class GridReference; + +template<class OBJECT> +class GridRefManager : public RefManager<GridRefManager<OBJECT>, OBJECT> +{ + public: + typedef LinkedListHead::Iterator< GridReference<OBJECT> > iterator; + + GridReference<OBJECT>* getFirst() { return (GridReference<OBJECT>*)RefManager<GridRefManager<OBJECT>, OBJECT>::getFirst(); } + GridReference<OBJECT>* getLast() { return (GridReference<OBJECT>*)RefManager<GridRefManager<OBJECT>, OBJECT>::getLast(); } + + iterator begin() { return iterator(getFirst()); } + iterator end() { return iterator(NULL); } + iterator rbegin() { return iterator(getLast()); } + iterator rend() { return iterator(NULL); } +}; +#endif diff --git a/src/framework/GameSystem/GridReference.h b/src/framework/GameSystem/GridReference.h new file mode 100644 index 00000000000..92d30e54ae1 --- /dev/null +++ b/src/framework/GameSystem/GridReference.h @@ -0,0 +1,52 @@ +/* + * 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 _GRIDREFERENCE_H +#define _GRIDREFERENCE_H + +#include "Utilities/LinkedReference/Reference.h" + +template<class OBJECT> +class GridRefManager; + +template<class OBJECT> +class MANGOS_DLL_SPEC GridReference : public Reference<GridRefManager<OBJECT>, OBJECT> +{ + protected: + void targetObjectBuildLink() + { + // called from link() + this->getTarget()->insertFirst(this); + this->getTarget()->incSize(); + } + void targetObjectDestroyLink() + { + // called from unlink() + if(this->isValid()) this->getTarget()->decSize(); + } + void sourceObjectDestroyLink() + { + // called from invalidate() + this->getTarget()->decSize(); + } + public: + GridReference() : Reference<GridRefManager<OBJECT>, OBJECT>() {} + ~GridReference() { this->unlink(); } + GridReference *next() { return (GridReference*)Reference<GridRefManager<OBJECT>, OBJECT>::next(); } +}; +#endif diff --git a/src/framework/GameSystem/NGrid.h b/src/framework/GameSystem/NGrid.h new file mode 100644 index 00000000000..941a90282e2 --- /dev/null +++ b/src/framework/GameSystem/NGrid.h @@ -0,0 +1,160 @@ +/* + * 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_NGRID_H +#define MANGOS_NGRID_H + +/** NGrid is nothing more than a wrapper of the Grid with an NxN cells + */ + +#include "GameSystem/Grid.h" +#include "GameSystem/GridReference.h" +#include "Timer.h" + +class GridInfo +{ +public: + GridInfo() : i_timer(0) {} + GridInfo(time_t expiry, bool unload = true ) : i_timer(expiry), i_unloadflag(unload) {} + const TimeTracker& getTimeTracker() const { return i_timer; } + bool getUnloadFlag() const { return i_unloadflag; } + void setUnloadFlag( bool pFlag) { i_unloadflag = pFlag; } + void setTimer(const TimeTracker& pTimer) { i_timer = pTimer; } + void ResetTimeTracker(time_t interval) { i_timer.Reset(interval); } + void UpdateTimeTracker(time_t diff) { i_timer.Update(diff); } + +private: + TimeTracker i_timer; + bool i_unloadflag; +}; + +typedef enum +{ + GRID_STATE_INVALID = 0, + GRID_STATE_ACTIVE = 1, + GRID_STATE_IDLE = 2, + GRID_STATE_REMOVAL= 3, + MAX_GRID_STATE = 4 +} grid_state_t; + +template +< +unsigned int N, +class ACTIVE_OBJECT, +class WORLD_OBJECT_TYPES, +class GRID_OBJECT_TYPES, +class ThreadModel = MaNGOS::SingleThreaded<ACTIVE_OBJECT> +> +class MANGOS_DLL_DECL NGrid +{ + public: + + typedef Grid<ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES, ThreadModel> GridType; + NGrid(uint32 id, int32 x, int32 y, time_t expiry, bool unload = true) : + i_gridId(id), i_cellstate(GRID_STATE_INVALID), i_x(x), i_y(y), i_GridObjectDataLoaded(false) + { + i_GridInfo = GridInfo(expiry, unload); + } + + const GridType& operator()(unsigned short x, unsigned short y) const { return i_cells[x][y]; } + GridType& operator()(unsigned short x, unsigned short y) { return i_cells[x][y]; } + + inline const uint32& GetGridId(void) const { return i_gridId; } + inline void SetGridId(const uint32 id) const { i_gridId = id; } + inline grid_state_t GetGridState(void) const { return i_cellstate; } + inline void SetGridState(grid_state_t s) { i_cellstate = s; } + inline int32 getX() const { return i_x; } + inline int32 getY() const { return i_y; } + + void link(GridRefManager<NGrid<N, ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES, ThreadModel> >* pTo) + { + i_Reference.link(pTo, this); + } + bool isGridObjectDataLoaded() const { return i_GridObjectDataLoaded; } + void setGridObjectDataLoaded(bool pLoaded) { i_GridObjectDataLoaded = pLoaded; } + + GridInfo* getGridInfoRef() { return &i_GridInfo; } + const TimeTracker& getTimeTracker() const { return i_GridInfo.getTimeTracker(); } + bool getUnloadFlag() const { return i_GridInfo.getUnloadFlag(); } + void setUnloadFlag( bool pFlag) { i_GridInfo.setUnloadFlag(pFlag); } + void ResetTimeTracker(time_t interval) { i_GridInfo.ResetTimeTracker(interval); } + void UpdateTimeTracker(time_t diff) { i_GridInfo.UpdateTimeTracker(diff); } + + template<class SPECIFIC_OBJECT> void AddWorldObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl) + { + i_cells[x][y].AddWorldObject(obj, hdl); + } + + template<class SPECIFIC_OBJECT> void RemoveWorldObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl) + { + i_cells[x][y].RemoveWorldObject(obj, hdl); + } + + template<class T, class TT> void Visit(TypeContainerVisitor<T, TypeMapContainer<TT> > &visitor) + { + for(unsigned int x=0; x < N; ++x) + for(unsigned int y=0; y < N; ++y) + i_cells[x][y].Visit(visitor); + } + + template<class T, class TT> void Visit(const uint32 &x, const uint32 &y, TypeContainerVisitor<T, TypeMapContainer<TT> > &visitor) + { + i_cells[x][y].Visit(visitor); + } + + unsigned int ActiveObjectsInGrid(void) const + { + unsigned int count=0; + for(unsigned int x=0; x < N; ++x) + for(unsigned int y=0; y < N; ++y) + count += i_cells[x][y].ActiveObjectsInGrid(); + return count; + } + + template<class SPECIFIC_OBJECT> const SPECIFIC_OBJECT* GetGridObject(const uint32 x, const uint32 y, OBJECT_HANDLE hdl) const + { + return i_cells[x][y].template GetGridObject<SPECIFIC_OBJECT>(hdl); + } + + template<class SPECIFIC_OBJECT> SPECIFIC_OBJECT* GetGridObject(const uint32 x, const uint32 y, OBJECT_HANDLE hdl) + { + return i_cells[x][y].template GetGridObject<SPECIFIC_OBJECT>(hdl); + } + + template<class SPECIFIC_OBJECT> bool AddGridObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl) + { + return i_cells[x][y].AddGridObject(hdl, obj); + } + + template<class SPECIFIC_OBJECT> bool RemoveGridObject(const uint32 x, const uint32 y, SPECIFIC_OBJECT *obj, OBJECT_HANDLE hdl) + { + return i_cells[x][y].RemoveGridObject(obj, hdl); + } + + private: + + uint32 i_gridId; + GridInfo i_GridInfo; + GridReference<NGrid<N, ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES, ThreadModel> > i_Reference; + int32 i_x; + int32 i_y; + grid_state_t i_cellstate; + GridType i_cells[N][N]; + bool i_GridObjectDataLoaded; +}; +#endif diff --git a/src/framework/GameSystem/TypeContainer.h b/src/framework/GameSystem/TypeContainer.h new file mode 100644 index 00000000000..c07d8229a99 --- /dev/null +++ b/src/framework/GameSystem/TypeContainer.h @@ -0,0 +1,128 @@ +/* + * 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_TYPECONTAINER_H +#define MANGOS_TYPECONTAINER_H + +/* + * Here, you'll find a series of containers that allow you to hold multiple + * types of object at the same time. + */ + +#include <map> +#include <vector> +#include "Platform/Define.h" +#include "Utilities/TypeList.h" +#include "GameSystem/GridRefManager.h" + +/* + * @class ContainerMapList is a mulit-type container for map elements + * By itself its meaningless but collaborate along with TypeContainers, + * it become the most powerfully container in the whole system. + */ +template<class OBJECT> struct ContainerMapList +{ + //std::map<OBJECT_HANDLE, OBJECT *> _element; + GridRefManager<OBJECT> _element; +}; + +template<> struct ContainerMapList<TypeNull> /* nothing is in type null */ +{ +}; +template<class H, class T> struct ContainerMapList<TypeList<H, T> > +{ + ContainerMapList<H> _elements; + ContainerMapList<T> _TailElements; +}; + +/* + * @class ContaierArrayList is a multi-type container for + * array of elements. + */ +template<class OBJECT> struct ContainerArrayList +{ + std::vector<OBJECT> _element; +}; + +// termination condition +template<> struct ContainerArrayList<TypeNull> {}; +// recursion +template<class H, class T> struct ContainerArrayList<TypeList<H, T> > +{ + ContainerArrayList<H> _elements; + ContainerArrayList<T> _TailElements; +}; + +/* + * @class ContainerList is a simple list of different types of elements + * + */ +template<class OBJECT> struct ContainerList +{ + OBJECT _element; +}; + +/* TypeNull is underfined */ +template<> struct ContainerList<TypeNull> {}; +template<class H, class T> struct ContainerList<TypeList<H, T> > +{ + ContainerList<H> _elements; + ContainerMapList<T> _TailElements; +}; + +#include "TypeContainerFunctions.h" + +/* + * @class TypeMapContainer contains a fixed number of types and is + * determined at compile time. This is probably the most complicated + * class and do its simplest thing, that is, holds objects + * of different types. + */ + +template<class OBJECT_TYPES> +class MANGOS_DLL_DECL TypeMapContainer +{ + public: + template<class SPECIFIC_TYPE> size_t Count() const { return MaNGOS::Count(i_elements, (SPECIFIC_TYPE*)NULL); } + + template<class SPECIFIC_TYPE> SPECIFIC_TYPE* find(OBJECT_HANDLE hdl, SPECIFIC_TYPE *fake) { return MaNGOS::Find(i_elements, hdl,fake); } + + /// find a specific type of object in the container + template<class SPECIFIC_TYPE> const SPECIFIC_TYPE* find(OBJECT_HANDLE hdl, SPECIFIC_TYPE *fake) const { return MaNGOS::Find(i_elements, hdl,fake); } + + /// inserts a specific object into the container + template<class SPECIFIC_TYPE> bool insert(OBJECT_HANDLE hdl, SPECIFIC_TYPE *obj) + { + SPECIFIC_TYPE* t = MaNGOS::Insert(i_elements, obj, hdl); + return (t != NULL); + } + + /// Removes the object from the container, and returns the removed object + template<class SPECIFIC_TYPE> bool remove(SPECIFIC_TYPE* obj, OBJECT_HANDLE hdl) + { + SPECIFIC_TYPE* t = MaNGOS::Remove(i_elements, obj, hdl); + return (t != NULL); + } + + ContainerMapList<OBJECT_TYPES> & GetElements(void) { return i_elements; } + const ContainerMapList<OBJECT_TYPES> & GetElements(void) const { return i_elements;} + + private: + ContainerMapList<OBJECT_TYPES> i_elements; +}; +#endif diff --git a/src/framework/GameSystem/TypeContainerFunctions.h b/src/framework/GameSystem/TypeContainerFunctions.h new file mode 100644 index 00000000000..81a6a5f876b --- /dev/null +++ b/src/framework/GameSystem/TypeContainerFunctions.h @@ -0,0 +1,172 @@ +/* + * 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 TYPECONTAINER_FUNCTIONS_H +#define TYPECONTAINER_FUNCTIONS_H + +/* + * Here you'll find a list of helper functions to make + * the TypeContainer usefull. Without it, its hard + * to access or mutate the container. + */ + +#include "Platform/Define.h" +#include "Utilities/TypeList.h" +#include <map> + +namespace MaNGOS +{ + /* ContainerMapList Helpers */ + // count functions + template<class SPECIFIC_TYPE> size_t Count(const ContainerMapList<SPECIFIC_TYPE> &elements, SPECIFIC_TYPE* /*fake*/) + { + return elements._element.getSize(); + }; + + template<class SPECIFIC_TYPE> size_t Count(const ContainerMapList<TypeNull> &/*elements*/, SPECIFIC_TYPE* /*fake*/) + { + return 0; + } + + template<class SPECIFIC_TYPE, class T> size_t Count(const ContainerMapList<T> &/*elements*/, SPECIFIC_TYPE* /*fake*/) + { + return 0; + } + + template<class SPECIFIC_TYPE, class T> size_t Count(const ContainerMapList<TypeList<SPECIFIC_TYPE, T> >&elements, SPECIFIC_TYPE* fake) + { + return Count(elements._elements,fake); + } + + template<class SPECIFIC_TYPE, class H, class T> size_t Count(const ContainerMapList<TypeList<H, T> >&elements, SPECIFIC_TYPE* fake) + { + return Count(elements._TailElements, fake); + } + + // non-const find functions + template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Find(ContainerMapList<SPECIFIC_TYPE> &/*elements*/, OBJECT_HANDLE /*hdl*/, SPECIFIC_TYPE* /*fake*/) + { + //typename std::map<OBJECT_HANDLE, SPECIFIC_TYPE *>::iterator iter = elements._element.find(hdl); + //return (iter == elements._element.end() ? NULL : iter->second); + return NULL; + }; + + template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Find(ContainerMapList<TypeNull> &/*elements*/, OBJECT_HANDLE /*hdl*/, SPECIFIC_TYPE* /*fake*/) + { + return NULL; // terminate recursion + } + + template<class SPECIFIC_TYPE, class T> SPECIFIC_TYPE* Find(ContainerMapList<T> &/*elements*/, OBJECT_HANDLE /*hdl*/, SPECIFIC_TYPE* /*fake*/) + { + return NULL; // this is a missed + } + + template<class SPECIFIC_TYPE, class H, class T> SPECIFIC_TYPE* Find(ContainerMapList<TypeList<H, T> >&/*elements*/, OBJECT_HANDLE /*hdl*/, SPECIFIC_TYPE* /*fake*/) + { + //SPECIFIC_TYPE* t = Find(elements._elements, hdl,fake); + //return (t != NULL ? t :Find(elements._TailElements, hdl,fake)); + return NULL; + } + + // const find functions + template<class SPECIFIC_TYPE> const SPECIFIC_TYPE* Find(const ContainerMapList<SPECIFIC_TYPE> &/*elements*/, OBJECT_HANDLE /*hdl*/, SPECIFIC_TYPE* /*fake*/) + { + //typename SPECIFIC_TYPE::iterator iter = elements._element.find(hdl); + //return (iter == elements._element.end() ? NULL : iter->second); + return NULL; + }; + + template<class SPECIFIC_TYPE> const SPECIFIC_TYPE* Find(const ContainerMapList<TypeNull> &/*elements*/, OBJECT_HANDLE /*hdl*/, SPECIFIC_TYPE* /*fake*/) + { + return NULL; + } + + template<class SPECIFIC_TYPE, class T> const SPECIFIC_TYPE* Find(const ContainerMapList<T> &/*elements*/, OBJECT_HANDLE /*hdl*/, SPECIFIC_TYPE* /*fake*/) + { + return NULL; + } + + template<class SPECIFIC_TYPE, class H, class T> SPECIFIC_TYPE* Find(const ContainerMapList<TypeList<H, T> >&elements, OBJECT_HANDLE hdl, SPECIFIC_TYPE* fake) + { + SPECIFIC_TYPE* t = Find(elements._elements, hdl,fake); + if( t) + return t; + + return Find(elements._TailElement, hdl,fake); + } + + // non-const insert functions + template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Insert(ContainerMapList<SPECIFIC_TYPE> &elements, SPECIFIC_TYPE *obj, OBJECT_HANDLE /*hdl*/) + { + //elements._element[hdl] = obj; + obj->GetGridRef().link(&elements._element, obj); + return obj; + }; + + template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Insert(ContainerMapList<TypeNull> &/*elements*/, SPECIFIC_TYPE * /*obj*/, OBJECT_HANDLE /*hdl*/) + { + return NULL; + } + + // this is a missed + template<class SPECIFIC_TYPE, class T> SPECIFIC_TYPE* Insert(ContainerMapList<T> &/*elements*/, SPECIFIC_TYPE * /*obj*/, OBJECT_HANDLE /*hdl*/) + { + return NULL; // a missed + } + + // Recursion + template<class SPECIFIC_TYPE, class H, class T> SPECIFIC_TYPE* Insert(ContainerMapList<TypeList<H, T> >&elements, SPECIFIC_TYPE *obj, OBJECT_HANDLE hdl) + { + SPECIFIC_TYPE* t= Insert(elements._elements, obj, hdl); + return (t != NULL ? t : Insert(elements._TailElements, obj, hdl)); + } + + // non-const remove method + template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Remove(ContainerMapList<SPECIFIC_TYPE> & /*elements*/, SPECIFIC_TYPE *obj, OBJECT_HANDLE /*hdl*/) + { + /*typename std::map<OBJECT_HANDLE, SPECIFIC_TYPE *>::iterator iter = elements._element.find(hdl); + if( iter != elements._element.end() ) + { + SPECIFIC_TYPE* t = iter->second; + elements._element.erase(iter); + return t; + }*/ + obj->GetGridRef().unlink(); + return obj; + } + + template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Remove(ContainerMapList<TypeNull> &/*elements*/, SPECIFIC_TYPE * /*obj*/, OBJECT_HANDLE /*hdl*/) + { + return NULL; + } + + // this is a missed + template<class SPECIFIC_TYPE, class T> SPECIFIC_TYPE* Remove(ContainerMapList<T> &/*elements*/, SPECIFIC_TYPE * /*obj*/, OBJECT_HANDLE /*hdl*/) + { + return NULL; // a missed + } + + template<class SPECIFIC_TYPE, class T, class H> SPECIFIC_TYPE* Remove(ContainerMapList<TypeList<H, T> > &elements, SPECIFIC_TYPE *obj, OBJECT_HANDLE hdl) + { + // The head element is bad + SPECIFIC_TYPE* t = Remove(elements._elements, obj, hdl); + return ( t != NULL ? t : Remove(elements._TailElements, obj, hdl) ); + } + +} +#endif diff --git a/src/framework/GameSystem/TypeContainerFunctionsPtr.h b/src/framework/GameSystem/TypeContainerFunctionsPtr.h new file mode 100644 index 00000000000..37ede0f6411 --- /dev/null +++ b/src/framework/GameSystem/TypeContainerFunctionsPtr.h @@ -0,0 +1,167 @@ +/* + * 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 TYPECONTAINER_FUNCTIONS_PTR_H +#define TYPECONTAINER_FUNCTIONS_PTR_H + +/* + * Here you'll find a list of helper functions to make + * the TypeContainer usefull. Without it, its hard + * to access or mutate the container. + */ + +#include "Platform/Define.h" +#include "Utilities/TypeList.h" +#include <map> + +namespace MaNGOS +{ + /* ContainerMapList Helpers */ + // count functions + // template<class SPECIFIC_TYPE> size_t Count(const ContainerMapList<SPECIFIC_TYPE> &elements, CountedPtr<SPECIFIC_TYPE>* /*fake*/) + // { + // return elements._element.size(); + // }; + // + // template<class SPECIFIC_TYPE> size_t Count(const ContainerMapList<TypeNull> &elements, CountedPtr<SPECIFIC_TYPE>* /*fake*/) + // { + // return 0; + // } + // + // template<class SPECIFIC_TYPE, class T> size_t Count(const ContainerMapList<T> &elements, CountedPtr<SPECIFIC_TYPE>* /*fake*/) + // { + // return 0; + // } + // + // template<class SPECIFIC_TYPE, class T> size_t Count(const ContainerMapList<TypeList<SPECIFIC_TYPE, T> >&elements, SPECIFIC_TYPE* fake) + // { + // return Count(elements._elements,fake); + // } + // + // template<class SPECIFIC_TYPE, class H, class T> size_t Count(const ContainerMapList<TypeList<H, T> >&elements, SPECIFIC_TYPE* fake) + // { + // return Count(elements._TailElements, fake); + // } + + // non-const find functions + template<class SPECIFIC_TYPE> CountedPtr<SPECIFIC_TYPE>& Find(ContainerMapList<SPECIFIC_TYPE> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/) + { + typename std::map<OBJECT_HANDLE, CountedPtr<SPECIFIC_TYPE> >::iterator iter = elements._element.find(hdl); + return (iter == elements._element.end() ? NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL) : iter->second); + }; + + template<class SPECIFIC_TYPE> CountedPtr<SPECIFIC_TYPE>& Find(ContainerMapList<TypeNull> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/) + { + return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL);// terminate recursion + } + + template<class SPECIFIC_TYPE, class T> CountedPtr<SPECIFIC_TYPE>& Find(ContainerMapList<T> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/) + { + return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL);// this is a missed + } + + template<class SPECIFIC_TYPE, class H, class T> CountedPtr<SPECIFIC_TYPE>& Find(ContainerMapList<TypeList<H, T> >&elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* fake) + { + CountedPtr<SPECIFIC_TYPE> &t = Find(elements._elements, hdl,fake); + return (!t ? Find(elements._TailElements, hdl,fake) : t); + } + + // const find functions + template<class SPECIFIC_TYPE> const CountedPtr<SPECIFIC_TYPE>& Find(const ContainerMapList<SPECIFIC_TYPE> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/) + { + typename CountedPtr<SPECIFIC_TYPE>::iterator iter = elements._element.find(hdl); + return (iter == elements._element.end() ? NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL) : iter->second); + }; + + template<class SPECIFIC_TYPE> const CountedPtr<SPECIFIC_TYPE>& Find(const ContainerMapList<TypeNull> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/) + { + return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL); + } + + template<class SPECIFIC_TYPE, class T> const CountedPtr<SPECIFIC_TYPE>& Find(const ContainerMapList<T> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/) + { + return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL); + } + + template<class SPECIFIC_TYPE, class H, class T> CountedPtr<SPECIFIC_TYPE>& Find(const ContainerMapList<TypeList<H, T> >&elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* fake) + { + CountedPtr<SPECIFIC_TYPE> &t = Find(elements._elements, hdl,fake); + if(!t) + t = Find(elements._TailElement, hdl,fake); + + return t; + } + + // non-const insert functions + template<class SPECIFIC_TYPE> CountedPtr<SPECIFIC_TYPE>& Insert(ContainerMapList<SPECIFIC_TYPE> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl) + { + elements._element[hdl] = obj; + return obj; + }; + + template<class SPECIFIC_TYPE> CountedPtr<SPECIFIC_TYPE>& Insert(ContainerMapList<TypeNull> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl) + { + return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL); + } + + // this is a missed + template<class SPECIFIC_TYPE, class T> CountedPtr<SPECIFIC_TYPE>& Insert(ContainerMapList<T> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl) + { + return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL);// a missed + } + + // Recursion + template<class SPECIFIC_TYPE, class H, class T> CountedPtr<SPECIFIC_TYPE>& Insert(ContainerMapList<TypeList<H, T> >&elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl) + { + CountedPtr<SPECIFIC_TYPE> &t= Insert(elements._elements, obj, hdl); + return (!t ? Insert(elements._TailElements, obj, hdl) : t); + } + + // non-const remove method + template<class SPECIFIC_TYPE> bool Remove(ContainerMapList<SPECIFIC_TYPE> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl) + { + typename std::map<OBJECT_HANDLE, CountedPtr<SPECIFIC_TYPE> >::iterator iter = elements._element.find(hdl); + if( iter != elements._element.end() ) + { + elements._element.erase(iter); + return true; + } + + return false; // found... terminate the search + } + + template<class SPECIFIC_TYPE> bool Remove(ContainerMapList<TypeNull> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl) + { + return false; + } + + // this is a missed + template<class SPECIFIC_TYPE, class T> bool Remove(ContainerMapList<T> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl) + { + return false; + } + + template<class SPECIFIC_TYPE, class T, class H> bool Remove(ContainerMapList<TypeList<H, T> > &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl) + { + // The head element is bad + bool t = Remove(elements._elements, obj, hdl); + return ( !t ? Remove(elements._TailElements, obj, hdl) : t ); + } + +} +#endif diff --git a/src/framework/GameSystem/TypeContainerVisitor.h b/src/framework/GameSystem/TypeContainerVisitor.h new file mode 100644 index 00000000000..8920b6d14d9 --- /dev/null +++ b/src/framework/GameSystem/TypeContainerVisitor.h @@ -0,0 +1,116 @@ +/* + * 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_TYPECONTAINERVISITOR_H +#define MANGOS_TYPECONTAINERVISITOR_H + +/* + * @class TypeContainerVisitor is implemented as a visitor pattern. It is + * a visitor to the TypeContainerList or TypeContainerMapList. The visitor has + * to overload its types as a visit method is called. + */ + +#include "Platform/Define.h" +#include "TypeContainer.h" + +// forward declaration +template<class T, class Y> class TypeContainerVisitor; + +// visitor helper +template<class VISITOR, class TYPE_CONTAINER> void VisitorHelper(VISITOR &v, TYPE_CONTAINER &c) +{ + v.Visit(c); +}; + +// terminate condition for container list +template<class VISITOR> void VisitorHelper(VISITOR &v, ContainerList<TypeNull> &c) +{ +} + +template<class VISITOR, class T> void VisitorHelper(VISITOR &v, ContainerList<T> &c) +{ + v.Visit(c._element); +} + +// recursion for container list +template<class VISITOR, class H, class T> void VisitorHelper(VISITOR &v, ContainerList<TypeList<H, T> > &c) +{ + VisitorHelper(v, c._elements); + VisitorHelper(v, c._TailElements); +} + +// terminate condition container map list +template<class VISITOR> void VisitorHelper(VISITOR &/*v*/, ContainerMapList<TypeNull> &/*c*/) +{ +} + +template<class VISITOR, class T> void VisitorHelper(VISITOR &v, ContainerMapList<T> &c) +{ + v.Visit(c._element); +} + +// recursion container map list +template<class VISITOR, class H, class T> void VisitorHelper(VISITOR &v, ContainerMapList<TypeList<H, T> > &c) +{ + VisitorHelper(v, c._elements); + VisitorHelper(v, c._TailElements); +} + +// array list +template<class VISITOR, class T> void VisitorHelper(VISITOR &v, ContainerArrayList<T> &c) +{ + v.Visit(c._element); +} + +template<class VISITOR> void VisitorHelper(VISITOR &/*v*/, ContainerArrayList<TypeNull> &/*c*/) +{ +} + +// recursion +template<class VISITOR, class H, class T> void VisitorHelper(VISITOR &v, ContainerArrayList<TypeList<H, T> > &c) +{ + VisitorHelper(v, c._elements); + VisitorHelper(v, c._TailElements); +} + +// for TypeMapContainer +template<class VISITOR, class OBJECT_TYPES> void VisitorHelper(VISITOR &v, TypeMapContainer<OBJECT_TYPES> &c) +{ + VisitorHelper(v, c.GetElements()); +} + +template<class VISITOR, class TYPE_CONTAINER> +class MANGOS_DLL_DECL TypeContainerVisitor +{ + public: + TypeContainerVisitor(VISITOR &v) : i_visitor(v) {} + + void Visit(TYPE_CONTAINER &c) + { + VisitorHelper(i_visitor, c); + } + + void Visit(const TYPE_CONTAINER &c) const + { + VisitorHelper(i_visitor, c); + } + + private: + VISITOR &i_visitor; +}; +#endif diff --git a/src/framework/Makefile.am b/src/framework/Makefile.am new file mode 100644 index 00000000000..aab4f653c41 --- /dev/null +++ b/src/framework/Makefile.am @@ -0,0 +1,64 @@ +# 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 + +## Process this file with automake to produce Makefile.in + +## Sub-directories to parse + +## CPP flags for includes, defines, etc. +AM_CPPFLAGS = -I$(srcdir) + +## Build MaNGOS framework library as convenience library. +# libMaNGOSScript shared library will later be reused by world server daemon. +noinst_LIBRARIES = libmangosframework.a +libmangosframework_a_SOURCES = \ + Policies/ObjectLifeTime.cpp \ + Utilities/EventProcessor.cpp + +## Additional files to include when running 'make dist' +# Source and header files for the Framework. +EXTRA_DIST = \ + Dynamic/FactoryHolder.h \ + Dynamic/ObjectRegistry.h \ + GameSystem/Grid.h \ + GameSystem/GridLoader.h \ + GameSystem/GridRefManager.h \ + GameSystem/GridReference.h \ + GameSystem/NGrid.h \ + GameSystem/TypeContainer.h \ + GameSystem/TypeContainerFunctions.h \ + GameSystem/TypeContainerFunctionsPtr.h \ + GameSystem/TypeContainerVisitor.h \ + Network/SocketDefines.h \ + Platform/CompilerDefs.h \ + Platform/Define.h \ + Policies/CreationPolicy.h \ + Policies/ObjectLifeTime.h \ + Policies/Singleton.h \ + Policies/SingletonImp.h \ + Policies/ThreadingModel.h \ + Utilities/CountedReference/Reference.h \ + Utilities/CountedReference/ReferenceHolder.h \ + Utilities/CountedReference/ReferenceImpl.h \ + Utilities/LinkedReference/RefManager.h \ + Utilities/LinkedReference/Reference.h \ + Utilities/ByteConverter.h \ + Utilities/Callback.h \ + Utilities/EventProcessor.h \ + Utilities/HashMap.h \ + Utilities/LinkedList.h \ + Utilities/TypeList.h + diff --git a/src/framework/Network/SocketDefines.h b/src/framework/Network/SocketDefines.h new file mode 100644 index 00000000000..5b03758815b --- /dev/null +++ b/src/framework/Network/SocketDefines.h @@ -0,0 +1,46 @@ +/* + * 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_SOCKETDEFINES_H +#define MANGOS_SOCKETDEFINES_H + +#ifdef WIN32 + +/* Windows socket definitions + */ +#define FD_SETSIZE 1024 +#include <winsock2.h> +#include <Ws2tcpip.h> + +typedef SOCKET SocketHandle; +typedef fd_set SelectSet; + +#else + +/* The unix socket definitions + */ +#include <sys/socket.h> +#include <netinet/in.h> +#ifdef __APPLE_CC__ +#include <sys/select.h> +#endif + +typedef int SocketHandle; +typedef fd_set SelectSet; +#endif +#endif diff --git a/src/framework/Platform/CompilerDefs.h b/src/framework/Platform/CompilerDefs.h new file mode 100644 index 00000000000..c0f659d55c4 --- /dev/null +++ b/src/framework/Platform/CompilerDefs.h @@ -0,0 +1,61 @@ +/* + * 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_COMPILERDEFS_H +#define MANGOS_COMPILERDEFS_H + +#define PLATFORM_WINDOWS 0 +#define PLATFORM_UNIX 1 +#define PLATFORM_APPLE 2 +#define PLATFORM_INTEL 3 + +// must be first (win 64 also define WIN32) +#if defined( _WIN64 ) +# define PLATFORM PLATFORM_WINDOWS +#elif defined( __WIN32__ ) || defined( WIN32 ) || defined( _WIN32 ) +# define PLATFORM PLATFORM_WINDOWS +#elif defined( __APPLE_CC__ ) +# define PLATFORM PLATFORM_APPLE +#elif defined( __INTEL_COMPILER ) +# define PLATFORM PLATFORM_INTEL +#else +# define PLATFORM PLATFORM_UNIX +#endif + +#define COMPILER_MICROSOFT 0 +#define COMPILER_GNU 1 +#define COMPILER_BORLAND 2 +#define COMPILER_INTEL 3 + +#ifdef _MSC_VER +# define COMPILER COMPILER_MICROSOFT +#elif defined( __BORLANDC__ ) +# define COMPILER COMPILER_BORLAND +#elif defined( __INTEL_COMPILER ) +# define COMPILER COMPILER_INTEL +#elif defined( __GNUC__ ) +# define COMPILER COMPILER_GNU +#else +# pragma error "FATAL ERROR: Unknown compiler." +#endif + +#if COMPILER == COMPILER_MICROSOFT +# pragma warning( disable : 4267 ) // conversion from 'size_t' to 'int', possible loss of data +# pragma warning( disable : 4786 ) // identifier was truncated to '255' characters in the debug information +#endif +#endif diff --git a/src/framework/Platform/Define.h b/src/framework/Platform/Define.h new file mode 100644 index 00000000000..268cc4aab1b --- /dev/null +++ b/src/framework/Platform/Define.h @@ -0,0 +1,229 @@ +/* + * 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_DEFINE_H +#define MANGOS_DEFINE_H + +#include "Platform/CompilerDefs.h" +#include <sys/types.h> + +/* Endian detection code from sha2.c: +------------------------------------------------------------------------- +Copyright (c) 2001, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK. +All rights reserved. + +TERMS + +Redistribution and use in source and binary forms, with or without +modification, are permitted subject to the following conditions: + +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +3. The copyright holder's name must not be used to endorse or promote +any products derived from this software without his specific prior +written permission. + +This software is provided 'as is' with no express or implied warranties +of correctness or fitness for purpose. +------------------------------------------------------------------------- +*/ + +/* 1. PLATFORM SPECIFIC INCLUDES */ + +#if defined(__GNU_LIBRARY__) +# include <endian.h> +# include <byteswap.h> +#elif defined(__CRYPTLIB__) +# if defined( INC_ALL ) +# include "crypt.h" +# elif defined( INC_CHILD ) +# include "../crypt.h" +# else +# include "crypt.h" +# endif +# if defined(DATA_LITTLEENDIAN) +# define PLATFORM_BYTE_ORDER SHA_LITTLE_ENDIAN +# else +# define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN +# endif +#elif defined(_MSC_VER) +# include <stdlib.h> +#elif !defined(WIN32) +# include <stdlib.h> +# if !defined (_ENDIAN_H) +# include <sys/param.h> +# else +# include _ENDIAN_H +# endif +#endif + +/* 2. BYTE ORDER IN 32-BIT WORDS + +To obtain the highest speed on processors with 32-bit words, this code +needs to determine the order in which bytes are packed into such words. +The following block of code is an attempt to capture the most obvious +ways in which various environemnts specify their endian definitions. +It may well fail, in which case the definitions will need to be set by +editing at the points marked **** EDIT HERE IF NECESSARY **** below. +*/ + +#define MANGOS_LITTLEENDIAN 0 +#define MANGOS_BIGENDIAN 1 + +#if !defined(MANGOS_ENDIAN) +# if defined(LITTLE_ENDIAN) || defined(BIG_ENDIAN) +# if defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN) +# if defined(BYTE_ORDER) +# if (BYTE_ORDER == LITTLE_ENDIAN) +# define MANGOS_ENDIAN MANGOS_LITTLEENDIAN +# elif (BYTE_ORDER == BIG_ENDIAN) +# define MANGOS_ENDIAN MANGOS_BIGENDIAN +# endif +# endif +# elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN) +# define MANGOS_ENDIAN MANGOS_LITTLEENDIAN +# elif !defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN) +# define MANGOS_ENDIAN MANGOS_BIGENDIAN +# endif +# elif defined(_LITTLE_ENDIAN) || defined(_BIG_ENDIAN) +# if defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN) +# if defined(_BYTE_ORDER) +# if (_BYTE_ORDER == _LITTLE_ENDIAN) +# define MANGOS_ENDIAN MANGOS_LITTLEENDIAN +# elif (_BYTE_ORDER == _BIG_ENDIAN) +# define MANGOS_ENDIAN MANGOS_BIGENDIAN +# endif +# endif +# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) +# define MANGOS_ENDIAN MANGOS_LITTLE_ENDIAN +# elif !defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN) +# define MANGOS_ENDIAN MANGOS_BIGENDIAN +# endif +# elif 0 /* **** EDIT HERE IF NECESSARY **** */ +# define MANGOS_ENDIAN MANGOS_LITTLEENDIAN +# elif 0 /* **** EDIT HERE IF NECESSARY **** */ +# define MANGOS_ENDIAN MANGOS_BIGENDIAN +# elif (('1234' >> 24) == '1') +# define MANGOS_ENDIAN MANGOS_LITTLEENDIAN +# elif (('4321' >> 24) == '1') +# define MANGOS_ENDIAN MANGOS_BIGENDIAN +# else +# define MANGOS_ENDIAN MANGOS_LITTLEENDIAN +# endif +#endif + +/* End of Endian detection code from sha2.c: */ + +#if PLATFORM == PLATFORM_WINDOWS +#define MANGOS_EXPORT __declspec(dllexport) +#define MANGOS_LIBRARY_HANDLE HMODULE +#define MANGOS_LOAD_LIBRARY(a) LoadLibrary(a) +#define MANGOS_CLOSE_LIBRARY FreeLibrary +#define MANGOS_GET_PROC_ADDR GetProcAddress +#define MANGOS_IMPORT __cdecl +#define MANGOS_SCRIPT_EXT ".dll" +#define MANGOS_SCRIPT_NAME "TrinityScript" +#else +#define MANGOS_LIBRARY_HANDLE void* +#define MANGOS_EXPORT export +#define MANGOS_LOAD_LIBRARY(a) dlopen(a,RTLD_NOW) +#define MANGOS_CLOSE_LIBRARY dlclose +#define MANGOS_GET_PROC_ADDR dlsym + +#if defined(__APPLE_CC__) && defined(BIG_ENDIAN) +#define MANGOS_IMPORT __attribute__ ((longcall)) +#else +#define MANGOS_IMPORT __attribute__ ((cdecl)) +#endif + +#define MANGOS_SCRIPT_EXT ".so" +#define MANGOS_SCRIPT_NAME "libtrinityscript" +#endif + +#ifdef WIN32 +#ifdef MANGOS_WIN32_DLL_IMPORT + +#define MANGOS_DLL_DECL __declspec(dllimport) +#else +#ifdef MANGOS_WIND_DLL_EXPORT +#define MANGOS_DLL_DECL __declspec(dllexport) +#else +#define MANGOS_DLL_DECL +#endif +#endif + +#else +#define MANGOS_DLL_DECL +#endif + +#ifndef DEBUG +#define MANGOS_INLINE inline +#else +#ifndef MANGOS_DEBUG +#define MANGOS_DEBUG +#endif +#define MANGOS_INLINE +#endif + +#if COMPILER == COMPILER_MICROSOFT +typedef __int64 int64; +typedef __int32 int32; +typedef __int16 int16; +typedef __int8 int8; +typedef unsigned __int64 uint64; +typedef unsigned __int32 uint32; +typedef unsigned __int16 uint16; +typedef unsigned __int8 uint8; +#else +typedef __int64_t int64; +typedef __int32_t int32; +typedef __int16_t int16; +typedef __int8_t int8; +typedef __uint64_t uint64; +typedef __uint32_t uint32; +typedef __uint16_t uint16; +typedef __uint8_t uint8; +typedef uint16 WORD; +typedef uint32 DWORD; +#endif +typedef uint64 OBJECT_HANDLE; + +#if PLATFORM == PLATFORM_WINDOWS +# define MANGOS_DLL_SPEC __declspec(dllexport) +# ifndef DECLSPEC_NORETURN +# define DECLSPEC_NORETURN __declspec(noreturn) +# endif +#else +# define MANGOS_DLL_SPEC +# define DECLSPEC_NORETURN +#endif + +#if COMPILER == COMPILER_GNU +# define ATTR_NORETURN __attribute__((noreturn)) +# define ATTR_PRINTF(F,V) __attribute__ ((format (printf, F, V))) +#else +# define ATTR_NORETURN +# define ATTR_PRINTF(F,V) +#endif + +#endif diff --git a/src/framework/Policies/CreationPolicy.h b/src/framework/Policies/CreationPolicy.h new file mode 100644 index 00000000000..20419982965 --- /dev/null +++ b/src/framework/Policies/CreationPolicy.h @@ -0,0 +1,107 @@ +/* + * 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_CREATIONPOLICY_H +#define MANGOS_CREATIONPOLICY_H + +#include <stdlib.h> +#include "Platform/Define.h" + +namespace MaNGOS +{ + /** + * OperatorNew policy creates an object on the heap using new. + */ + template <class T> + class MANGOS_DLL_DECL OperatorNew + { + public: + static T* Create(void) { return (new T); } + static void Destroy(T *obj) { delete obj; } + }; + + /** + * LocalStaticCreation policy creates an object on the stack + * the first time call Create. + */ + template <class T> + class MANGOS_DLL_DECL LocalStaticCreation + { + union MaxAlign + { + char t_[sizeof(T)]; + short int shortInt_; + int int_; + long int longInt_; + float float_; + double double_; + long double longDouble_; + struct Test; + int Test::* pMember_; + int (Test::*pMemberFn_)(int); + }; + public: + static T* Create(void) + { + static MaxAlign si_localStatic; + return new(&si_localStatic) T; + } + + static void Destroy(T *obj) { obj->~T(); } + }; + + /** + * CreateUsingMalloc by pass the memory manger. + */ + template<class T> + class MANGOS_DLL_DECL CreateUsingMalloc + { + public: + static T* Create() + { + void* p = ::malloc(sizeof(T)); + if (!p) return 0; + return new(p) T; + } + + static void Destroy(T* p) + { + p->~T(); + ::free(p); + } + }; + + /** + * CreateOnCallBack creates the object base on the call back. + */ + template<class T, class CALL_BACK> + class MANGOS_DLL_DECL CreateOnCallBack + { + public: + static T* Create() + { + return CALL_BACK::createCallBack(); + } + + static void Destroy(T *p) + { + CALL_BACK::destroyCallBack(p); + } + }; +} +#endif diff --git a/src/framework/Policies/ObjectLifeTime.cpp b/src/framework/Policies/ObjectLifeTime.cpp new file mode 100644 index 00000000000..af40edc1274 --- /dev/null +++ b/src/framework/Policies/ObjectLifeTime.cpp @@ -0,0 +1,33 @@ +/* + * 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 <cstdlib> +#include "ObjectLifeTime.h" + +namespace MaNGOS +{ + extern "C" void external_wrapper(void *p) + { + std::atexit( (void (*)())p ); + } + + void MANGOS_DLL_SPEC at_exit( void (*func)() ) + { + external_wrapper((void*)func); + } +} diff --git a/src/framework/Policies/ObjectLifeTime.h b/src/framework/Policies/ObjectLifeTime.h new file mode 100644 index 00000000000..c47daaca339 --- /dev/null +++ b/src/framework/Policies/ObjectLifeTime.h @@ -0,0 +1,50 @@ +/* + * 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_OBJECTLIFETIME_H +#define MANGOS_OBJECTLIFETIME_H + +#include <stdexcept> +#include "Platform/Define.h" + +typedef void (* Destroyer)(void); + +namespace MaNGOS +{ + void MANGOS_DLL_SPEC at_exit( void (*func)() ); + + template <class T> + class MANGOS_DLL_DECL ObjectLifeTime + { + public: + inline static void ScheduleCall(void (*destroyer)() ) + { + at_exit( destroyer ); + } + + DECLSPEC_NORETURN static void OnDeadReference(void) ATTR_NORETURN; + + }; + + template <class T> + inline void ObjectLifeTime<T>::OnDeadReference(void)// We don't handle Dead Reference for now + { + throw std::runtime_error("Dead Reference"); + } +} +#endif diff --git a/src/framework/Policies/Singleton.h b/src/framework/Policies/Singleton.h new file mode 100644 index 00000000000..b70c5486dff --- /dev/null +++ b/src/framework/Policies/Singleton.h @@ -0,0 +1,62 @@ +/* + * 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_SINGLETON_H +#define MANGOS_SINGLETON_H + +/** + * @brief class Singleton + */ + +#include "CreationPolicy.h" +#include "ThreadingModel.h" +#include "ObjectLifeTime.h" + +namespace MaNGOS +{ + template + < + typename T, + class ThreadingModel = MaNGOS::SingleThreaded<T>, + class CreatePolicy = MaNGOS::OperatorNew<T>, + class LifeTimePolicy = MaNGOS::ObjectLifeTime<T> + > + class MANGOS_DLL_DECL Singleton + { + public: + static T& Instance(); + + protected: + Singleton() {}; + + private: + + // Prohibited actions...this does not prevent hijacking. + Singleton(const Singleton &); + Singleton& operator=(const Singleton &); + + // Singleton Helpers + static void DestroySingleton(); + + // data structure + typedef typename ThreadingModel::Lock Guard; + static T *si_instance; + static bool si_destroyed; + }; +} +#endif diff --git a/src/framework/Policies/SingletonImp.h b/src/framework/Policies/SingletonImp.h new file mode 100644 index 00000000000..ce0a4403472 --- /dev/null +++ b/src/framework/Policies/SingletonImp.h @@ -0,0 +1,90 @@ +/* + * 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_SINGLETONIMPL_H +#define MANGOS_SINGLETONIMPL_H + +#include "Singleton.h" + +// avoid the using namespace here cuz +// its a .h file afterall + +template +< +typename T, +class ThreadingModel, +class CreatePolicy, +class LifeTimePolicy +> +T& +MaNGOS::Singleton<T, ThreadingModel, CreatePolicy, LifeTimePolicy >::Instance() +{ + if( !si_instance ) + { + // double-checked Locking pattern + Guard(); + if( !si_instance ) + { + if( si_destroyed ) + { + si_destroyed = false; + LifeTimePolicy::OnDeadReference(); + } + si_instance = CreatePolicy::Create(); + LifeTimePolicy::ScheduleCall(&DestroySingleton); + } + } + + return *si_instance; +} + +template +< +typename T, +class ThreadingModel, +class CreatePolicy, +class LifeTimePolicy +> +void +MaNGOS::Singleton<T, ThreadingModel, CreatePolicy, LifeTimePolicy>::DestroySingleton() +{ + CreatePolicy::Destroy(si_instance); + si_instance = NULL; + si_destroyed = true; +} + +#define INSTANTIATE_SINGLETON_1(TYPE) \ + template class MANGOS_DLL_DECL MaNGOS::Singleton<TYPE, MaNGOS::SingleThreaded<TYPE>, MaNGOS::OperatorNew<TYPE>, MaNGOS::ObjectLifeTime<TYPE> >; \ + template<> TYPE* MaNGOS::Singleton<TYPE, MaNGOS::SingleThreaded<TYPE>, MaNGOS::OperatorNew<TYPE>, MaNGOS::ObjectLifeTime<TYPE> >::si_instance = 0; \ + template<> bool MaNGOS::Singleton<TYPE, MaNGOS::SingleThreaded<TYPE>, MaNGOS::OperatorNew<TYPE>, MaNGOS::ObjectLifeTime<TYPE> >::si_destroyed = false + +#define INSTANTIATE_SINGLETON_2(TYPE, THREADINGMODEL) \ + template class MANGOS_DLL_DECL MaNGOS::Singleton<TYPE, THREADINGMODEL, MaNGOS::OperatorNew<TYPE>, MaNGOS::ObjectLifeTime<TYPE> >; \ + template<> TYPE* MaNGOS::Singleton<TYPE, THREADINGMODEL, MaNGOS::OperatorNew<TYPE>, MaNGOS::ObjectLifeTime<TYPE> >::si_instance = 0; \ + template<> bool MaNGOS::Singleton<TYPE, THREADINGMODEL, MaNGOS::OperatorNew<TYPE>, MaNGOS::ObjectLifeTime<TYPE> >::si_destroyed = false + +#define INSTANTIATE_SINGLETON_3(TYPE, THREADINGMODEL, CREATIONPOLICY ) \ + template class MANGOS_DLL_DECL MaNGOS::Singleton<TYPE, THREADINGMODEL, CREATIONPOLICY, MaNGOS::ObjectLifeTime<TYPE> >; \ + template<> TYPE* MaNGOS::Singleton<TYPE, THREADINGMODEL, CREATIONPOLICY, MaNGOS::ObjectLifeTime<TYPE> >::si_instance = 0; \ + template<> bool MaNGOS::Singleton<TYPE, THREADINGMODEL, CREATIONPOLICY, MaNGOS::ObjectLifeType<TYPE> >::si_destroyed = false + +#define INSTANTIATE_SINGLETON_4(TYPE, THREADINGMODEL, CREATIONPOLICY, OBJECTLIFETIME) \ + template class MANGOS_DLL_DECL MaNGOS::Singleton<TYPE, THREADINGMODEL, CREATIONPOLICY, OBJECTLIFETIME >; \ + template<> TYPE* MaNGOS::Singleton<TYPE, THREADINGMODEL, CREATIONPOLICY, OBJECTLIFETIME >::si_instance = 0; \ + template<> bool MaNGOS::Singleton<TYPE, THREADINGMODEL, CREATIONPOLICY, OBJECTLIFETIME >::si_destroyed = false +#endif diff --git a/src/framework/Policies/ThreadingModel.h b/src/framework/Policies/ThreadingModel.h new file mode 100644 index 00000000000..8175b3f82af --- /dev/null +++ b/src/framework/Policies/ThreadingModel.h @@ -0,0 +1,127 @@ +/* + * 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_THREADINGMODEL_H +#define MANGOS_THREADINGMODEL_H + +/** + * @class ThreadingModel<T> + * + */ + +#include "Platform/Define.h" + +namespace MaNGOS +{ + inline void Guard(void *) {} + + template<typename MUTEX> class MANGOS_DLL_DECL GeneralLock + { + public: + GeneralLock(MUTEX &m) : i_mutex(m) + { + i_mutex.acquire(); + } + + ~GeneralLock() + { + i_mutex.release(); + } + private: + GeneralLock(const GeneralLock &); + GeneralLock& operator=(const GeneralLock &); + MUTEX &i_mutex; + }; + + template <class T> + class MANGOS_DLL_DECL SingleThreaded + { + public: + + struct Lock // empty object + { + Lock() {} + Lock(const T &) {} + Lock(const SingleThreaded<T> &) // for single threaded we ignore this + { + } + }; + + typedef T VolatileType; + }; + + // object level lockable + template<class T, class MUTEX> + class MANGOS_DLL_DECL ObjectLevelLockable + { + public: + ObjectLevelLockable() : i_mtx() {} + + friend class Lock; + + class Lock + { + public: + Lock(ObjectLevelLockable<T, MUTEX> &host) : i_lock(host.i_mtx) + { + } + + private: + GeneralLock<MUTEX> i_lock; + }; + + typedef volatile T VolatileType; + + private: + // prevent the compiler creating a copy construct + ObjectLevelLockable(const ObjectLevelLockable<T, MUTEX> &); + ObjectLevelLockable<T, MUTEX>& operator=(const ObjectLevelLockable<T, MUTEX> &); + + MUTEX i_mtx; + }; + + template<class T, class MUTEX> + class MANGOS_DLL_DECL ClassLevelLockable + { + public: + class Lock; + friend class Lock; + typedef volatile T VolatileType; + + ClassLevelLockable() {} + + class Lock + { + public: + Lock(T& /*host*/) { ClassLevelLockable<T, MUTEX>::si_mtx.acquire(); } + Lock(ClassLevelLockable<T, MUTEX> &) { ClassLevelLockable<T, MUTEX>::si_mtx.acquire(); } + Lock() { ClassLevelLockable<T, MUTEX>::si_mtx.acquire(); } + ~Lock() { ClassLevelLockable<T, MUTEX>::si_mtx.release(); } + }; + + private: + static MUTEX si_mtx; + }; + +} + +template<class T, class MUTEX> MUTEX MaNGOS::ClassLevelLockable<T, MUTEX>::si_mtx; + +#define INSTANTIATE_CLASS_MUTEX(CTYPE,MUTEX) \ + template class MANGOS_DLL_DECL MaNGOS::ClassLevelLockable<CTYPE, MUTEX > +#endif 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 |