1 // This file belongs to the "MiniCore" game engine.
2 // Copyright (C) 2015 Jussi Lind <jussi.lind@iki.fi>
3 //
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 2
7 // of the License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 // MA  02110-1301, USA.
18 //
19 
20 #ifndef MCRECYCLER_HH
21 #define MCRECYCLER_HH
22 
23 #include <stack>
24 #include <vector>
25 
26 /*! \class MCRecycler
27  *  \brief Generic object recycler.
28  *
29  *  This class can be used to store and recycle objects. It acts as a
30  *  cache. Objects to be stored must have a default constructor.
31  *  "Freed" Objects are moved to a free-list for fast creation later.
32  *  All created Objects are automatically deleted in the destructor of MCRecycler. */
33 template<typename T>
34 class MCRecycler
35 {
36 public:
37     //! Constructor.
38     MCRecycler();
39 
40     //! Destructor.
41     ~MCRecycler();
42 
43     /*! Return a new object of type T. If the free-list is empty
44      *  then the default constructor is used. The newly created object is
45      *  automatically deleted when Recycler gets of out scope. */
46     T * newObject();
47 
48     /*! \brief Move given object to the free list.
49      *         MCRecycler takes the ownership. */
50     void freeObject(T * p);
51 
52     //! Move all active Objs to the free list
53     void freeObjects();
54 
55 private:
56     unsigned int deleteFreeObjects();
57 
58     unsigned int deleteObjects();
59 
60     typedef std::vector<T *> ObjectPool;
61     ObjectPool m_objs;
62 
63     typedef std::stack<T *> FreeObjectPool;
64     FreeObjectPool m_freeObjs;
65 };
66 
67 template<typename T>
MCRecycler()68 MCRecycler<T>::MCRecycler()
69 {
70 }
71 
72 template<typename T>
newObject()73 T * MCRecycler<T>::newObject()
74 {
75     T * p = nullptr;
76     if (m_freeObjs.size())
77     {
78         p = m_freeObjs.top();
79         m_freeObjs.pop();
80     }
81     else
82     {
83         p = new T;
84         m_objs.push_back(p);
85     }
86     return p;
87 }
88 
89 template<typename T>
deleteObjects()90 unsigned int MCRecycler<T>::deleteObjects()
91 {
92     unsigned int count = 0;
93     for (auto iter = m_objs.begin(); iter != m_objs.end(); iter++)
94     {
95         delete *iter;
96         count++;
97     }
98     m_objs.clear();
99     return count;
100 }
101 
102 template<typename T>
freeObject(T * p)103 void MCRecycler<T>::freeObject(T * p)
104 {
105     m_freeObjs.push(p);
106 }
107 
108 template<typename T>
freeObjects()109 void MCRecycler<T>::freeObjects()
110 {
111     for (auto iter = m_objs.begin(); iter != m_objs.end(); iter++)
112     {
113         m_freeObjs.push(*iter);
114     }
115 }
116 
117 template<typename T>
~MCRecycler()118 MCRecycler<T>::~MCRecycler()
119 {
120     deleteObjects();
121 }
122 
123 #endif // MCRECYCLER_HH
124