Lumiera  0.pre.03
»edit your freedom«
element-tracker.hpp
Go to the documentation of this file.
1 /*
2  ELEMENT-TRACKER.hpp - registry for tracking instances automatically
3 
4  Copyright (C) Lumiera.org
5  2010, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
23 
61 #ifndef LIB_ELEMENT_TRACKER_H
62 #define LIB_ELEMENT_TRACKER_H
63 
64 #include "lib/p.hpp"
65 #include "lib/optional-ref.hpp"
66 #include "lib/util-foreach.hpp"
67 #include "lib/ref-array-impl.hpp"
68 
69 
70 
71 namespace lib {
72 
73  using util::isSameObject;
74 
91  template<typename ELM>
93  : public lib::RefArrayVector<P<ELM>>
94  {
95  using _Vec = std::vector<P<ELM>>;
96  using Iter = typename _Vec::iterator;
97  using CIter = typename _Vec::const_iterator;
98 
99  public:
100  ~ElementTracker()
101  {
102  try { clear(); }
103  catch(...) {/*ignored*/}
104  }
105 
106  void
107  clear ()
108  {
109  _Vec toKill;
110  toKill.reserve(_Vec::size());
111  toKill.swap(*this); // prevent quadratic detach()
112  ASSERT (0 == _Vec::size());
113  util::for_each (toKill, unlink_it);
114  }
115 
116  void
117  append (P<ELM> const& asset)
118  {
119  REQUIRE (asset, "Attempt to track a NIL element");
120  remove (*asset);
121  this->push_back (asset);
122  }
123 
124  void
125  remove (ELM const& asset)
126  {
127  for (Iter i = _Vec::begin();
128  i != _Vec::end() ; ++i )
129  if (asset == **i) // _Vec contains smart-ptrs
130  { // ELM is required to define '=='
131  this->erase (i);
132  return;
133  }
134  }
135 
136  bool
137  isRegistered (ELM const& asset) const
138  {
139  for (CIter i = _Vec::begin();
140  i != _Vec::end() ; ++i )
141  if (asset == **i)
142  return true;
143 
144  return false;
145  }
146 
147  private:
148  static void
149  unlink_it (P<ELM>& elm)
150  {
151  REQUIRE (elm);
152  try { elm->detach(); }
153  catch(...)
154  {
155  WARN (common,"problems while clearing ElementTracker, ignored.");
156  }
157  }
158  };
159 
160 
161 
173  template<typename TAR>
175  {
176  public:
179 
184  void
186  {
187  if (!getRegistry) return;
188  TAR& element = static_cast<TAR&> (*this);
189 
190  getRegistry().remove(element);
191  ENSURE (!getRegistry().isRegistered(element));
192  }
193 
194 
195  typedef P<TAR> PTarget;
196 
201  static PTarget
203  {
204  REQUIRE (getRegistry);
205 
206  PTarget newElement (new TAR());
207  getRegistry().append (newElement);
208 
209  ENSURE (newElement);
210  ENSURE (getRegistry().isRegistered(*newElement));
211  return newElement;
212  }
213 
214 
215  static void
216  setRegistryInstance (Registry& registry_to_use)
217  {
218  getRegistry.link_to (registry_to_use);
219  }
220 
221  static void
222  deactivateRegistryLink()
223  {
224  getRegistry.clear();
225  }
226 
227  static bool
228  is_attached_to (Registry const& someRegistry)
229  {
230  return getRegistry.points_to (someRegistry);
231  }
232 
233  protected:
234  static RegistryLink getRegistry;
235  };
236 
239  template<typename TAR>
241 
242 
243 
244 } // namespace lib
245 #endif
Optional or switchable link to an existing object.
a checked, switchable reference.
Customised refcounting smart pointer.
Registry for tracking object instances.
Implementation namespace for support and library code.
Helper mixin template for implementing a type intended to participate in automatic element tracking...
static PTarget create()
factory for creating smart-ptr managed TAR instances, automatically registered with the element-track...
void detach()
detach this element from the element-tracking registry.
Some (library-) implementations of the RefArray interface.
The asset subsystem of the Steam-Layer.
Definition: wrapperptr.hpp:44
Perform operations "for each element" of a collection.
static RegistryLink getRegistry
storage for the functor to link an AutoRegistered entity to the corresponding registration service ...
This variation of the wrapper actually is a vector, but can act as a RefArray.
bool isSameObject(A const &a, B const &b)
compare plain object identity, bypassing any custom comparison operators.
Definition: util.hpp:347