Lumiera  0.pre.03
»edit your freedom«
command-registry.hpp
Go to the documentation of this file.
1 /*
2  COMMAND-REGISTRY.hpp - steam-Command object registration and storage management
3 
4  Copyright (C) Lumiera.org
5  2009, 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 
58 #ifndef CONTROL_COMMAND_REGISTRY_H
59 #define CONTROL_COMMAND_REGISTRY_H
60 
61 #include "lib/error.hpp"
62 #include "lib/depend.hpp"
63 #include "lib/sync.hpp"
64 #include "include/logging.h"
65 #include "lib/nocopy.hpp"
66 #include "lib/util.hpp"
67 
72 
73 #include <boost/functional/hash.hpp>
74 #include <unordered_map>
75 #include <memory>
76 #include <string>
77 #include <map>
78 
79 
80 
81 namespace steam {
82 namespace control {
83 
84  using boost::hash;
85  using std::shared_ptr;
86  using std::unordered_map;
89  using util::contains;
90  using std::string;
91  using std::map;
92 
93 
101  {
102  bool
103  operator() (const Command *pC1, const Command *pC2) const
104  {
105  return (!pC1 && pC2)
106  || ( pC1 && pC2 && (*pC1 < *pC2));
107  }
108  };
109 
110 
119  : public lib::Sync<>
121  {
122  // using a hashtable to implement the index
123  typedef unordered_map<Symbol, Command, hash<Symbol>> CmdIndex;
124  typedef map< const Command*, Symbol, order_by_impl> ReverseIndex;
125 
126  TypedAllocationManager allocator_;
127  CmdIndex index_;
128  ReverseIndex ridx_;
129 
130 
131  public:
133 
134 
135  ~CommandRegistry()
136  {
137  if (0 < index_size())
138  TRACE (command, "Shutting down Command system...");
140  ridx_.clear();
141  index_.clear();
142  }
143 
144 
145 
151  void
152  track (Symbol cmdID, Command const& commandHandle)
153  {
154  Lock sync{this};
155 
156  REQUIRE (commandHandle);
157  if (contains (index_,cmdID) || contains(ridx_, &commandHandle))
158  commandHandle.duplicate_detected(cmdID);
159 
160  Command& indexSlot = index_[cmdID];
161  indexSlot = commandHandle;
162  ridx_[&indexSlot] = cmdID;
163 
164  ENSURE (contains(ridx_, &indexSlot));
165  ENSURE (contains(index_, cmdID));
166  }
167 
168 
173  bool
174  remove (Symbol cmdID)
175  {
176  Lock sync{this};
177 
178  bool actually_remove = contains (index_,cmdID);
179  if (actually_remove)
180  {
181  ridx_.erase(& index_[cmdID]);
182  index_.erase(cmdID);
183  }
184  ENSURE (!contains (index_,cmdID));
185  return actually_remove;
186  }
187 
188 
197  Command
199  {
200  Lock sync{this};
201  return getValue_or_default (index_, cmdID, Command() );
202  } //if not found
203 
204 
209  Symbol
210  findDefinition (Command const& cmdInstance) const
211  {
212  Lock sync{this};
213  return getValue_or_default (ridx_, &cmdInstance, Symbol::BOTTOM );
214  } //used as Key
215 
216 
217  size_t
218  index_size() const
219  {
220  return index_.size();
221  }
222 
223 
224  size_t
225  instance_count() const
226  {
227  return allocator_.numSlots<CommandImpl>();
228  }
229 
230 
236  template< typename SIG_OPER
237  , typename SIG_CAPT
238  , typename SIG_UNDO
239  >
241  newCommandImpl (function<SIG_OPER>& operFunctor
242  ,function<SIG_CAPT>& captFunctor
243  ,function<SIG_UNDO>& undoFunctor)
244  {
245 
246  // derive the storage type necessary
247  // to hold the command arguments and UNDO memento
248  typedef typename UndoSignature<SIG_CAPT>::Memento Mem;
250 
251  shared_ptr<Arguments> pArg (allocator_.create<Arguments>());
252 
253  return allocator_.create<CommandImpl> (pArg, operFunctor,captFunctor,undoFunctor);
254  }
255 
256 
257 
258 
273  createCloneImpl (CommandImpl const& refObject);
274 
275 
276  };
277 
278 
279 }} // namespace steam::control
280 #endif
Facility for monitor object based locking.
Definition: sync.hpp:217
Helper for building a std::map with Command* as keys.
Abstract foundation for building custom allocation managers.
shared_ptr< CommandImpl > newCommandImpl(function< SIG_OPER > &operFunctor, function< SIG_CAPT > &captFunctor, function< SIG_UNDO > &undoFunctor)
set up a new command implementation frame
Any copy and copy construction prohibited.
Definition: nocopy.hpp:46
This header is for including and configuring NoBug.
Registry managing command implementation objects (Singleton).
Steam-Layer implementation namespace root.
Access point to singletons and other kinds of dependencies designated by type.
Definition: depend.hpp:289
Symbol findDefinition(Command const &cmdInstance) const
search the command index for a definition
Object Monitor based synchronisation.
Token or Atom with distinct identity.
Definition: symbol.hpp:126
Mix-Ins to allow or prohibit various degrees of copying and cloning.
Command queryIndex(Symbol cmdID)
query the command index by ID
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
Steam-Layer command frontend.
Singleton services and Dependency Injection.
Foundation for a custom allocation manager, tracking the created objects by smart-ptrs.
MAP::mapped_type getValue_or_default(MAP &map, typename MAP::key_type const &key, typename MAP::mapped_type defaultVal)
fetch value from a Map, or return a default if not found
Definition: util.hpp:275
Lumiera error handling (C++ interface).
Handle object representing a single Command instance to be used by client code.
Definition: command.hpp:124
Steam-Layer Command implementation.
void track(Symbol cmdID, Command const &commandHandle)
register a command (Frontend) under the given ID.
Metaprogramming helpers for deriving the precise function signatures necessary to implement a given c...
This is "the" top level CmdClosure implementation.
bool contains(SEQ const &cont, typename SEQ::const_reference val)
shortcut for brute-force containment test in any sequential container
Definition: util.hpp:255
static lib::Depend< CommandRegistry > instance
storage for the singleton factory used to access CommandRegistry
A passive container record holding the actual command arguments & UNDO state.