Lumiera  0.pre.03
»edit your freedom«
model-port-registry.cpp
Go to the documentation of this file.
1 /*
2  ModelPortRegistry - creating and organising and accessing model ports
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 
39 #include "lib/error.hpp"
40 #include "include/logging.h"
41 #include "lib/sync-classlock.hpp"
45 
46 namespace steam {
47 namespace fixture {
48 
49  namespace error = lumiera::error;
50 
51  using mobject::LUMIERA_ERROR_BUILDER_LIFECYCLE;
52  using mobject::LUMIERA_ERROR_INVALID_MODEL_PORT;
53  using mobject::LUMIERA_ERROR_UNCONNECTED_MODEL_PORT;
54 
55 
56  using MPDescriptor = ModelPortRegistry::ModelPortDescriptor const&;
57  using LockRegistry = lib::ClassLock<ModelPortRegistry>;
58 
59 
63 
64 
65 
67  void
69  {
70  INFO (builder, "disabling ModelPort registry....");
71  LockRegistry global_lock;
72  theGlobalRegistry.clear();
73  }
74 
75 
84  {
85  LockRegistry global_lock;
86  ModelPortRegistry *previous = theGlobalRegistry.isValid()?
87  &( theGlobalRegistry()) : 0;
88  INFO_IF (!previous, builder, "activating new ModelPort registry.");
89  WARN_IF ( previous, builder, "switching ModelPort registry instance.");
90  theGlobalRegistry.link_to (newRegistry);
91  return previous;
92  }
93 
94 
100  {
101  LockRegistry global_lock;
102  if (theGlobalRegistry.isValid())
103  return theGlobalRegistry();
104 
105  throw error::State ("global model port registry is not accessible"
106  , LUMIERA_ERROR_BUILDER_LIFECYCLE);
107  }
108 
109 
110 
115  bool
117  {
118  return bool(key)
119  && util::contains (transaction_, key);
120  }
121 
122 
129  bool
131  {
132  return bool(key)
133  && util::contains (currentReg_, key);
134  }
135 
136 
143  MPDescriptor
145  {
146  if (!key)
147  throw error::State ("This model port is disconnected or NIL"
148  , LUMIERA_ERROR_UNCONNECTED_MODEL_PORT);
149  if (!isRegistered (key))
150  throw error::Logic ("Model port was never registered, or got unregistered meanwhile."
151  ,LUMIERA_ERROR_INVALID_MODEL_PORT);
152 
153  MPTable::const_iterator pos = currentReg_.find (key);
154  ASSERT (pos != currentReg_.end());
155  ASSERT (pos->second.isValid());
156  return pos->second;
157  }
158 
159 
166  MPDescriptor
168  {
169  LockRegistry global_lock;
170  return theGlobalRegistry().get(key);
171  }
172 
173 
174  /* === Mutations === */
175 
178  MPDescriptor
179  ModelPortRegistry::definePort (ID<Pipe> pipe, ID<Struct> element_exposing_this_port)
180  {
181  LockRegistry global_lock;
182  if (contains (pipe))
183  throw error::Logic ("attempt to register a model port with a pipe-ID, "
184  "which has already been used to register a "
185  "model port within this transaction (build process)."
186  , LUMIERA_ERROR_DUPLICATE_MODEL_PORT);
187  return (transaction_[pipe] = ModelPortDescriptor(pipe, element_exposing_this_port));
188  }
189 
190 
192  void
194  {
195  LockRegistry global_lock;
196  transaction_.erase (key);
197  }
198 
199 
203  void
205  {
206  LockRegistry global_lock;
207  transaction_.clear();
208  }
209 
210 
217  void
219  {
220  LockRegistry global_lock;
221  MPTable newTransaction(transaction_);
222  TRACE (builder, "committing new ModelPort list....");
223  swap (currentReg_, transaction_);
224  swap (transaction_, newTransaction);
225  }
226 
227 
231  void
233  {
234  LockRegistry global_lock;
235  TRACE (builder, "discarding changes to ModelPort list (rollback)....");
236  MPTable newTransaction(currentReg_);
237  swap (transaction_, newTransaction);
238  }
239 
240 
241 
242  LUMIERA_ERROR_DEFINE (DUPLICATE_MODEL_PORT, "Attempt to define a new model port with an pipe-ID already denoting an existing port");
243 
244 }// namespace fixture
245 
246 
247 namespace mobject {
248 
249  LUMIERA_ERROR_DEFINE (INVALID_MODEL_PORT, "Referral to unknown model port");
250  LUMIERA_ERROR_DEFINE (UNCONNECTED_MODEL_PORT, "Attempt to operate on an existing but unconnected model port");
251 
252 
253  ModelPort::ModelPort (ID<asset::Pipe> refID)
254  : id_(refID)
255  {
257  }
258 
259 
262  bool
264  {
266  }
267 
268 
275  {
276  ENSURE (this->id_ == fixture::ModelPortRegistry::accessDescriptor(this->id_).id());
277 
278  return fixture::ModelPortRegistry::accessDescriptor(this->id_).id();
279  }
280 
281 
288  {
289  return fixture::ModelPortRegistry::accessDescriptor(this->id_).holder();
290  }
291 
292 
300  {
301  return this->id_.streamType();
302  }
303 
304 
305 
306 }} // namespace steam::mobject
Organising the output data calculation possibilities.
ModelPortDescriptor const & get(PID) const
basic access operation: access the descriptor of a currently valid model port.
ModelPortDescriptor const & definePort(PID pipe, StID element_exposing_this_port)
create and register a new model port entry, within the pending transaction
void clear()
schedule removal of all registry contents.
Optional or switchable link to an existing object.
bool contains(PID) const
does the transaction currently being built already contain a model port registration for the given ID...
void commit()
activate pending model port changes.
static lib::OptionalRef< ModelPortRegistry > theGlobalRegistry
storage for the link to the global Registry instance currently in charge
static bool exists(ID< asset::Pipe >)
check if the global model port registration contains a mapping for the given pipe-ID ...
Mutation and management facility for model ports within the builder.
static ModelPortDescriptor const & accessDescriptor(PID)
access the globally valid model port for the given pipe.
This header is for including and configuring NoBug.
Steam-Layer implementation namespace root.
ModelPortDescriptor records are used as actual storage within the model port registration table; they...
Derived specific exceptions within Lumiera&#39;s exception hierarchy.
Definition: error.hpp:199
ID< asset::Pipe > pipe() const
access the Pipe (ID) of the global model port registered with the ID underlying this model port...
static ModelPortRegistry * setActiveInstance(ModelPortRegistry &newRegistry)
switch the implicit link to the global ModelPort registry to point to the given implementation instan...
static void shutdown()
globally deactivate access to model ports
Management facility for tracking model ports.
Steam-Layer Facade: access to the Builder.
A special implementation of lib::Sync, where the storage of the object monitor is associated directly...
Lumiera error handling (C++ interface).
A synchronisation protection guard employing a lock scoped to the parameter type as a whole...
static ModelPortRegistry & globalInstance()
access the globally valid registry instance.
ID< asset::Struct > holder() const
access the timeline (or similar structural element) holding a global pipe which corresponds to this m...
StreamType::ID streamType() const
convenience shortcut to access the stream type associated with the pipe-ID corresponding to this mode...
void rollback()
discard pending changes.
void remove(PID)
remove a model port entry from the pending transaction
#define LUMIERA_ERROR_DEFINE(err, msg)
Definition and initialisation of an error constant.
Definition: error.h:80
thin wrapper around a size_t hash ID used as primary key for all Asset objects.
Definition: asset.hpp:108