Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
output-mapping.hpp
Go to the documentation of this file.
1/*
2 OUTPUT-MAPPING.hpp - generic interface for translation of output designations
3
4 Copyright (C)
5 2010, Hermann Vosseler <Ichthyostega@web.de>
6
7  **Lumiera** is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version. See the file COPYING for further details.
11
12*/
13
14
43#ifndef STEAM_MOBJECT_OUTPUT_MAPPING_H
44#define STEAM_MOBJECT_OUTPUT_MAPPING_H
45
46#include "lib/error.hpp"
47#include "lib/util.hpp"
48#include "lib/hash-value.h"
49#include "steam/asset/pipe.hpp"
50#include "common/query.hpp"
51
52#include <compare>
53#include <map>
54
55
56
57namespace steam {
58namespace mobject {
59
60 namespace { // Helper to extract and rebind definition types
61
66 template<class DEF>
67 class _def
68 {
70
71 template<typename FUN>
72 struct Rebind;
73
74 template<typename RET>
75 struct Rebind<RET(DEF::*)(PId)>
76 {
77 typedef RET Res;
78 };
79
80 using OutputMappingMemberFunc = decltype(&DEF::output) ;
82
83 public:
84 using Target = Rebinder::Res;
85
86 };
87 }//(End) type rebinding helper
88
89 namespace error = lumiera::error;
90 using lumiera::Query;
91 using lib::HashVal;
92
93
94
95
120 template<class DEF>
122 : public DEF
123 {
124 using Setup = _def<DEF>;
125
128
129 /* == mapping table storage == */
130 std::map<HashVal,HashVal> table_;
131
132 public:
133 using Target = Setup::Target;
134
135 // using default ctor and copy operations
136
137 size_t size() const { return table_.size(); }
138 bool empty() const { return 0 == size(); }
139 void clear() { table_.clear(); }
140
141
156 {
158 HashVal& pID_;
159
160 Resolver (OutputMapping& container, HashVal& resultVal)
161 : thisMapping_(container)
162 , pID_(resultVal)
163 { }
164
165 friend class OutputMapping;
166
167 /* copy by clients prohibited */
169
170
171 Target
172 resolve() const
173 {
174 REQUIRE (pID_);
175 PId targetPipeID (pID_);
176 return thisMapping_.resolveTarget (targetPipeID);
177 }
178
179 public:
184 void
185 operator= (PId newId2map)
186 {
187 pID_ = newId2map;
188 }
189
190 void
191 operator= (PPipe newPipe2map)
192 {
193 REQUIRE (newPipe2map);
194 pID_ = newPipe2map->getID();
195 }
196
197 void
199 {
200 pID_ = 0;
201 }
202
209 operator Target()
210 {
211 if (not isValid())
212 throw error::Logic{"attempt to resolve an unconnected output mapping"
213 , LERR_(UNCONNECTED)};
214 return resolve();
215 }
216
217 bool
218 isValid() const
219 {
220 return bool(pID_);
221 }
222
223 explicit
224 operator bool() const
225 {
226 return isValid();
227 }
228
229
230 /* === equality comparisons (boost::operators) === */
231
232 friend bool
233 operator== (Resolver const& a, Resolver const& b)
234 {
235 return a.pID_ == b.pID_;
236 } // note: Resolver depends on template parameter DEF
237 // All instances of DEF are considered equivalent!
238 friend bool
239 operator== (Resolver const& rr, Target const& tval)
240 {
241 return rr.resolve() == tval;
242 }
243 };
244
245
246
247 /* === Map-style access for clients === */
248
249 Resolver operator[] (PId sourcePipeID);
250 Resolver operator[] (PPipe const& pipe);
251 Resolver operator[] (Query<asset::Pipe> query4pipe);
252
253 bool
254 contains (PId mapping4sourcePipeID)
255 {
256 return util::contains (table_, mapping4sourcePipeID);
257 }
258
259 bool
260 contains (PPipe sourcePipe)
261 {
262 return !sourcePipe
263 or this->contains (sourcePipe->getID());
264 }
265
266
267
268 private:
269 Target
270 resolveTarget (PId mappedPipeID)
271 {
272 return DEF::output (mappedPipeID);
273 }
274
275 Resolver
276 buildResolutionWrapper (HashVal tableSlot)
277 {
278 ASSERT (this->contains (tableSlot));
279 return Resolver (*this, table_[tableSlot]);
280 }
281 };
282
283
284
285
286 /* ===== Implementation details ===== */
287
288 namespace _mapping {
289
291 HashVal slot (Query<asset::Pipe> const&);
292
294 HashVal resolveQuery (Query<asset::Pipe> const&);
295
298 uint is_defaults_query_with_channel (Query<asset::Pipe> const&);
299
301 Query<asset::Pipe> build_corresponding_sourceQuery (Query<asset::Pipe> const&);
302 }
303
304
319 template<class DEF>
320 inline OutputMapping<DEF>::Resolver
322 {
323 if (not contains (sourcePipeID))
324 {
325 // issue a defaults query to resolve this mapping first
326 Query<asset::Pipe> query4pipe = DEF::buildQuery (sourcePipeID);
327 table_[sourcePipeID] = _mapping::resolveQuery (query4pipe);
328 }
329 return buildResolutionWrapper (sourcePipeID);
330 }
331
332
335 template<class DEF>
338 {
339 REQUIRE (pipe);
340 return (*this) [pipe->getID()];
341 }
342
343
374 template<class DEF>
377 {
378 HashVal hash4query = _mapping::slot (query4pipe);
379 if (not contains (hash4query))
380 {
381 // need to resolve this query first
382 auto addEntry = [&](auto query)
383 {
384 table_[hash4query] = _mapping::resolveQuery (query);
385 };
386
387 if (uint seqNr = _mapping::is_defaults_query_with_channel (query4pipe))
388 {
389 // treat the special case
390 // when actually requesting the "Nth default of this kind"
391 PPipe corresponding_sourcePipe
394 ENSURE (corresponding_sourcePipe);
395
396 PId sourcePipeID = corresponding_sourcePipe->getID();
397 addEntry (DEF::buildQuery (sourcePipeID, seqNr));
398 }
399 else
400 addEntry (query4pipe);
401 }
402
403 ENSURE (this->contains (hash4query));
404 return buildResolutionWrapper (hash4query);
405 }
406
407
408}} // namespace steam::mobject
409#endif
Customised refcounting smart pointer template, built upon std::shared_ptr, but forwarding type relati...
Definition p.hpp:77
Generic interface to express a query for specifically typed result elements exposing some capabilitie...
Definition query.hpp:254
thin wrapper around a size_t hash ID used as primary key for all Asset objects.
Definition asset.hpp:98
static StructFactory retrieve
storage for the static StructFactory instance
Definition struct.hpp:107
friend bool operator==(Resolver const &a, Resolver const &b)
Resolver(OutputMapping &container, HashVal &resultVal)
bool isValid() const
< is this a valid connected mapping?
Resolver & operator=(Resolver const &)
OutputMapping is a facility to resolve output designations.
std::map< HashVal, HashVal > table_
bool contains(PId mapping4sourcePipeID)
Resolver buildResolutionWrapper(HashVal tableSlot)
bool contains(PPipe sourcePipe)
Resolver operator[](PId sourcePipeID)
standard map-style access to an OutputMapping.
Target resolveTarget(PId mappedPipeID)
asset::ID< asset::Pipe > PId
Lumiera error handling (C++ interface).
#define LERR_(_NAME_)
Definition error.hpp:45
Hash value types and utilities.
unsigned int uint
Definition integral.hpp:29
Definition Setup.py:1
size_t HashVal
a STL compatible hash value
Definition hash-value.h:52
LumieraError< LERR_(LOGIC)> Logic
Definition error.hpp:207
lib::P< Pipe > PPipe
Definition pipe.hpp:43
Query< asset::Pipe > build_corresponding_sourceQuery(Query< asset::Pipe > const &query4pipe)
..and build the corresponding defaults source query for this case
uint is_defaults_query_with_channel(Query< asset::Pipe > const &query4pipe)
detect the special case, when actually the Nth solution of a defaults query is requested
HashVal slot(Query< asset::Pipe > const &query)
yield a suitable table slot for this query
HashVal resolveQuery(Query< asset::Pipe > const &query4pipe)
delegate target pipe resolution to the rules system
Steam-Layer implementation namespace root.
bool contains(MAP &map, typename MAP::key_type const &key)
shortcut for containment test on a map
Definition util.hpp:230
A "processing pipe" represented as Asset.
Basic and generic representation of an internal query.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...