diff options
Diffstat (limited to 'src/framework/GameSystem')
-rw-r--r-- | src/framework/GameSystem/Grid.h | 129 | ||||
-rw-r--r-- | src/framework/GameSystem/GridLoader.h | 76 | ||||
-rw-r--r-- | src/framework/GameSystem/GridRefManager.h | 41 | ||||
-rw-r--r-- | src/framework/GameSystem/GridReference.h | 52 | ||||
-rw-r--r-- | src/framework/GameSystem/NGrid.h | 160 | ||||
-rw-r--r-- | src/framework/GameSystem/TypeContainer.h | 128 | ||||
-rw-r--r-- | src/framework/GameSystem/TypeContainerFunctions.h | 172 | ||||
-rw-r--r-- | src/framework/GameSystem/TypeContainerFunctionsPtr.h | 167 | ||||
-rw-r--r-- | src/framework/GameSystem/TypeContainerVisitor.h | 116 |
9 files changed, 1041 insertions, 0 deletions
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 |