Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
placement-index-query-resolver.cpp
Go to the documentation of this file.
1/*
2 placementIndexQueryResolver - using PlacementIndex to resolve scope queries
3
4 Copyright (C)
5 2009, 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
26
28
29#include <memory>
30#include <stack>
31
32
33namespace steam {
34namespace mobject {
35namespace session {
36
37 using std::unique_ptr;
38
39 using lumiera::Goal;
40 using lumiera::Query;
42 using lumiera::getResultTypeID;
43
44
47 typedef QueryID const& QID;
48
51
61
62
63
66 {
67 public:
68 virtual ~Explorer() { };
69 virtual bool exhausted () =0;
70 virtual Pla& step () =0;
71 };
72
73
74
75 /* ==== special strategies to choose from ==== */
76
83 : public Explorer
84 {
86
87 bool
89 {
90 return !tip_;
91 }
92
93 Pla&
95 {
96 REQUIRE (tip_);
97 Pla& pos = *tip_;
98 ++tip_;
99 return pos;
100 }
101
102 public:
104 : tip_(start)
105 { }
106 };
107
114 : public Explorer
115 {
117 std::stack<PIter> scopes_;
118
119 bool
121 {
122 while (not scopes_.empty() and not scopes_.top())
123 scopes_.pop();
124 return scopes_.empty();
125 }
126
127 Pla&
129 {
130 REQUIRE (not scopes_.empty() and scopes_.top());
131 Pla& pos = *scopes_.top();
132 ++scopes_.top();
133 scopes_.push(index_.getReferrers(pos.getID()));
134 return pos;
135 }
136
137 public:
139 : index_(idx)
140 {
141 scopes_.push(start);
142 }
143 };
144
145
151 : public Explorer
152 {
155
156 bool
158 {
159 return !tip_;
160 }
161
162 Pla&
164 {
165 REQUIRE (tip_);
166 Pla& pos = *tip_;
168 if (tip_ == &pos)
169 tip_ = 0;
170 return pos;
171 }
172
173 public:
174 UpExplorer(Pla& start, PIdx idx)
175 : index_(idx)
176 , tip_(&start)
177 { }
178 };
179
180
181 typedef function<bool(Pla const&)> ContentFilter;
182 typedef function<Explorer*()> ExplorerBuilder;
183
184
194 : public lumiera::Resolution
195 {
198 unique_ptr<Explorer> explore_;
199
200
201 virtual Result
203 {
204 explore_.reset (buildExploartion_());
205
206 Result cursor;
207 exploreNext (cursor);
208 return cursor;
209 }
210
211 virtual void
213 {
214 exploreNext (pos);
215 }
216
217 void
219 {
220 typedef Query<Pla>::Cursor Cursor;
221 Cursor& cursor = static_cast<Cursor&> (res);
222
223 while (!explore_->exhausted() )
224 {
225 Pla& elm (explore_->step());
226 if (acceptable_(elm))
227 {
228 cursor.point_at (elm);
229 return;
230 }
231 }
232
233 ASSERT (explore_->exhausted());
234 cursor.point_at (0);
235 }
236
237 public:
239 ,ContentFilter a)
240 : acceptable_(a)
242 , explore_()
243 { }
244 };
245
246
247
248
249 namespace { // Helpers for wiring up a suitable resolutionFunction....
250
251
252 bool acceptAllObjects_(Pla) { return true; }
253
255 template<typename QUERY>
257 getContentFilter (QUERY const& query)
258 {
259 return query.contentFilter();
260 }
261
265 {
266 static ContentFilter acceptAllObjects = bind (&acceptAllObjects_, _1);
267 return acceptAllObjects;
268 }
269
271 template<typename MO>
272 QueryID
274 {
275 QueryID qID(Goal::DISCOVERY, getResultTypeID<Placement<MO>>());
276 return qID;
277 }
278
279 struct
281 {
282 UseThisIndex (PlacementIndex& idx) : refIndex_(idx) {}
283
285 PlacementIndex& operator() (void) { return refIndex_; }
286 };
287 } //(END) Helpers
288
289
290
291
293 : _getIndex(UseThisIndex (theIndex))
294 {
296 }
297
298
299 PlacementIndexQueryResolver::PlacementIndexQueryResolver (function<IndexLink> const& accessIndex)
300 : _getIndex(accessIndex)
301 {
303 }
304
305
306 void
308 {
309 defineHandling<MObject>();
310 defineHandling<Clip>();
311 defineHandling<Effect>();
313
314 defineHandling<mobject::test::DummyMO >();
315 defineHandling<mobject::test::TestSubMO1 >();
316 defineHandling<mobject::test::TestSubMO2 >();
317 defineHandling<mobject::test::TestSubMO21>();
319 }
320
321
322 bool
324 {
325 return qID.kind == Goal::DISCOVERY
326 and( qID.type == getResultTypeID<Placement<MObject>>()
327 or qID.type == getResultTypeID<Placement<Clip>>()
328 or qID.type == getResultTypeID<Placement<Effect>>()
330
331 or qID.type == getResultTypeID<Placement<mobject::test::DummyMO >>()
332 or qID.type == getResultTypeID<Placement<mobject::test::TestSubMO1 >>()
333 or qID.type == getResultTypeID<Placement<mobject::test::TestSubMO2 >>()
334 or qID.type == getResultTypeID<Placement<mobject::test::TestSubMO21>>()
336 );
337 }
338
339
340 template<typename MO>
341 void
343 {
344 installResolutionCase( whenQueryingFor<MO>()
345 , bind (&PlacementIndexQueryResolver::resolutionFunction<MO>,
346 this, _1 )
347 );
348 }
349
350
359 template<typename MO>
362 {
363 QID qID = goal.getQID();
364 REQUIRE (qID == whenQueryingFor<MO>());
365 REQUIRE (INSTANCEOF(ScopeQuery<MO>, &goal));
366
367 ScopeQuery<MO> const& query = static_cast<ScopeQuery<MO> const&> (goal);
368 ScopeQueryKind direction = query.searchDirection();
369 PID scopeID = query.searchScope();
370
372 this, scopeID, direction)
373 , getContentFilter(query)
374 );
375 }
376
377
383 Explorer*
385 {
386 PIdx index = _getIndex(); // access the currently configured PlacementIndex (Session)
387 switch (direction)
388 {
389 case CONTENTS: return new DeepExplorer(index.getReferrers(startID), index);
390 case CHILDREN: return new ChildExplorer(index.getReferrers(startID));
391 case PARENTS: return new UpExplorer(index.getScope(startID),index);
392 case PATH: return new UpExplorer(index.find(startID),index);
393
394 default:
395 throw lumiera::error::Invalid("unknown query direction");
396 }
397 }
398
399
400
401}}} // namespace steam::mobject::session
Iterator tool treating pulled data by a custom transformation (function)
Single Solution, possibly part of a result set.
Definition query.hpp:157
Query ABC: unspecific goal for resolution or retrieval.
Definition query.hpp:118
QueryID const & getQID() const
Definition query.hpp:144
void installResolutionCase(Goal::QueryID const &, ResolutionMechanism)
Generic interface to express a query for specifically typed result elements exposing some capabilitie...
Definition query.hpp:254
ABC representing the result set of an individual query resolution.
Strategy: explore the structure just by following the given iterator; usually this yields an element'...
Strategy: explore the structure depth first.
Interface: strategy for exploring the structure.
lumiera::Resolution * resolutionFunction(Goal const &goal)
virtual bool canHandleQuery(Goal::QueryID const &) const override
Explorer * setupExploration(PlacementIndex::ID startID, ScopeQueryKind direction)
the builder function used to set up an concrete result set object when issuing the query.
Structured compound of Placement instances with lookup capabilities.
PlacementMO & getScope(PlacementMO const &) const
iterator getReferrers(ID) const
Retrieve all the elements attached to the given entry (scope) Each element (Placement) can act as a s...
on query, an individual result set is prepared to be explored by the invoking client code.
ResultSet(ExplorerBuilder b, ContentFilter a)
Query a scope to discover it's contents or location.
ScopeQueryKind searchDirection() const
PlacementMO::ID const & searchScope() const
Strategy: explore the structure upwards, ascending until reaching the root element.
MObject in the Session to represent a clip on the timeline.
LumieraError< LERR_(INVALID)> Invalid
Definition error.hpp:211
ContentFilter getContentFilter(QUERY const &query)
use filter predicate provided by the concrete query
Namespace of Session and user visible high-level objects.
Definition sequence.hpp:65
@ CONTENTS
discover any contained objects depth-first
@ PARENTS
discover the enclosing scopes
@ CHILDREN
discover the immediate children
@ PATH
discover the path to root
function< bool(Pla const &)> ContentFilter
Steam-Layer implementation namespace root.
Implementing resolution of "discover contents"-queries based on PlacementIndex.
Core abstraction: placement of a media object into session context.
Specific queries to explore contents of a scope within the high-level model.
A hierarchy of simple dummy-Media-Objects for easy unit testing.
#define INSTANCEOF(CLASS, EXPR)
shortcut for subclass test, intended for assertions only.
Definition util.hpp:514