Lumiera  0.pre.03
»edit your freedom«
struct-factory-impl.hpp
Go to the documentation of this file.
1 /*
2  STRUCT-FACTORY-IMPL.hpp - crating structural assets (impl details)
3 
4  Copyright (C) Lumiera.org
5  2008,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 
35 #ifndef ASSET_STRUCT_FACTORY_IMPL_H
36 #define ASSET_STRUCT_FACTORY_IMPL_H
37 
38 
45 #include "common/config-rules.hpp"
46 #include "common/query.hpp"
47 #include "steam/asset/timeline.hpp"
48 #include "steam/asset/sequence.hpp"
49 #include "steam/asset/procpatt.hpp"
50 #include "steam/asset/pipe.hpp"
51 
53 
54 #include "lib/format-string.hpp"
55 #include "lib/query-util.hpp"
56 #include "lib/symbol.hpp"
57 #include "lib/error.hpp"
58 #include "lib/util.hpp"
59 
60 #include <cstdlib>
61 
62 
63 
64 namespace steam {
65 namespace asset {
66 
67  using lib::Symbol;
68  using util::_Fmt;
69  using util::uNum;
70  using util::isnil;
71  using util::contains;
72  using lumiera::Query;
73  using LERR_(CAPABILITY_QUERY);
75 
84 
85  using idi::StructTraits;
86 
87 
88  namespace {
89 
90  Symbol genericIdSymbol ("id");
91  Symbol seqNrPredicate ("ord");
92 
93  }
94 
95 
96 
97 
105  {
106 
110  template<class STRU>
111  const Asset::Ident
112  createIdent (Query<STRU> const& query)
113  {
114  // does the query somehow specify the desired name-ID?
115  string nameID = query.extractID (genericIdSymbol);
116  if (isnil (nameID))
117  nameID = query.extractID (StructTraits<STRU>::idSymbol());
118  if (isnil (nameID))
119  {
120  // no name-ID contained in the query...
121  // so we'll create a new one
122  static int i=0;
123  nameID = _Fmt("%s.%d")
125  % (++i);
126  }
127  ENSURE (!isnil (nameID));
128 
129  // does the query actually demand the Nth instance/element?
130  string seqID = query.extractID (seqNrPredicate);
131  if (!isnil (seqID) && 1 < uNum(seqID))
132  nameID += "."+seqID;
133 
134  Category cat (STRUCT, StructTraits<STRU>::catFolder());
135  return Asset::Ident (nameID, cat );
136  }
137 
138 
140  RFork
141  getFork_forSequence (string const& desiredID)
142  {
143  RFork fork;
144  if (!isnil (desiredID))
145  fork = Session::current->elements.pick (match_specificFork (desiredID));
146 
147  if (fork && !Scope::containing (fork.getRef()).isRoot())
148  {
149  UNIMPLEMENTED ("how to deal with 'stealing' a fork sub-tree to a new sequence??");
150  }
151  if (!fork)
152  fork = Session::current->getRoot().attach (MObject::create (ForkID (desiredID)));
153 
154  return fork;
155  }
156 
157 
158 
159 
160 
161 
162 
163 
166 
167  public:
168  StructFactoryImpl (StructFactory& interface)
169  : recursive_create_(interface)
170  { }
171 
172 
173 
178  template<class STRU>
179  STRU* fabricate (Query<STRU> const& caps)
180  {
181  throw error::Config ("The following Query could not be resolved: " + caps.asKey()
182  , LUMIERA_ERROR_CAPABILITY_QUERY );
183  }
184 
185  };
186 
187 
188  /* ============= specialisations =========================== */
189 
190  template<>
191  inline const ProcPatt*
193  {
194  TODO ("actually extract properties/capabilities from the query...");
195  return new ProcPatt (createIdent (caps));
196  }
197 
198  template<>
199  inline Pipe*
201  {
202  const Asset::Ident idi (createIdent (caps));
203  string streamID = caps.extractID ("stream");
204  if (isnil (streamID)) streamID = "default";
205  PProcPatt processingPattern = Session::current->defaults (Query<const ProcPatt>("stream("+streamID+")"));
206  return new Pipe( idi
207  , streamID
208  , processingPattern
209  );
210  }
211 
212  template<>
213  inline Timeline*
215  {
216  TODO ("extract additional properties/capabilities from the query...");
217  const Asset::Ident idi (createIdent (caps));
218  string sequenceID = caps.extractID ("sequence");
219  Query<Sequence> desiredSequence (isnil (sequenceID)? "" : "id("+sequenceID+")");
220  PSequence sequence = recursive_create_(desiredSequence);
221  ASSERT (sequence);
222  RBinding newBinding = Session::current->getRoot().attach (MObject::create (sequence));
223  ASSERT (newBinding);
224  PTimeline newTimeline = Timeline::create (idi, newBinding);
225  ENSURE (newTimeline);
226  return newTimeline.get();
227  }
228 
229  template<>
230  inline Sequence*
232  {
233  // when we reach this point it is clear a suitable sequence doesn't yet exist in the model
234  TODO ("actually extract properties/capabilities from the query...");
235  string forkID = caps.extractID ("fork");
236  Query<Fork> desiredFork (isnil (forkID)? "" : "id("+forkID+")");
237 // PFork fork = Session::current->query (desiredFork); ///////////////////////////////////TICKET #639
238  // TODO: handle the following cases
239  // - fork doesn't exist --> create and attach it as root
240  // - fork exists and is root attached, but belongs already to a sequence --> throw
241  // - fork exists, but isn't root attached ---> what do do here? steal it??
242  PSequence newSequence = Sequence::create (createIdent (caps));
243  ENSURE (newSequence);
244  return newSequence.get();
245  }
246 
247 
248 
249 
250 }} // namespace steam::asset
251 #endif
_PickRes< PRED >::Result pick(PRED const &searchPredicate)
pick the first element from session satisfying a predicate.
RFork getFork_forSequence(string const &desiredID)
either fetch or build a suitable fork root for a new sequence
Utilities to support working with predicate queries.
Definition of a structural asset to express patterns of wiring or processing Processing patterns can ...
A "processing pipe" represented as Asset.
An active (smart-ptr like) external reference to a specifically placed MObject "instance" within the ...
Definition: mobject-ref.hpp:94
"Processing Pattern" is a structural Asset representing information how to build some part of the ren...
Definition: procpatt.hpp:61
TODO type comment.
Definition: sequence.hpp:92
StructFactory & recursive_create_
used for issuing recursive create calls to top level
Basic and generic representation of an internal query.
Tree like classification of Assets.
Definition: category.hpp:75
MORef< MOX > attach(Placement< MOX > const &newPlacement)
attach a child element to the model
function< bool(Placement< Fork > const &)> match_specificFork(string const &forkID)
yield a query predicate to pick a specific fork
Front-end for printf-style string template interpolation.
static session::SessManager & current
access point to the current Session
Definition: session.hpp:129
static Scope containing(PlacementMO const &aPlacement)
discover the enclosing scope of a given Placement
Definition: scope.cpp:193
Steam-Layer implementation namespace root.
A front-end for using printf-style formatting.
DefaultsAccess defaults
manages default configured objects
Definition: session.hpp:131
STRU * fabricate(Query< STRU > const &caps)
make a new structural asset instance.
structural asset corresponding to the part of the model forming a processing pipe for generating medi...
Definition: pipe.hpp:79
A Placement scope within the high-level-model.
Definition: scope.hpp:78
MObject is the interface class for all "Media Objects".
Definition: mobject.hpp:79
Implementation details, especially concerning how configuration queries are resolved and when to crea...
Derived specific exceptions within Lumiera&#39;s exception hierarchy.
Definition: error.hpp:199
string extractID(Symbol sym, const string &termString)
(preliminary) helper: instead of really parsing and evaluating the terms, just do a regular expressio...
Definition: query-util.cpp:101
The (current) Session holds all the user visible content to be edited and manipulated within the Lumi...
Definition: session.hpp:109
Structural building block of the session: a sequence of clips.
Token or Atom with distinct identity.
Definition: symbol.hpp:126
static PTarget create()
factory for creating smart-ptr managed TAR instances, automatically registered with the element-track...
a POD comprised of all the information sufficiently identifying any given Asset.
Definition: asset.hpp:158
MObject in session to represent the top-level binding of a sequence.
Marker types to indicate a literal string and a Symbol.
const Asset::Ident createIdent(Query< STRU > const &query)
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
Search and query services to discover contents of the session.
Lumiera error handling (C++ interface).
Core factory to generate media objects for use in the Session model.
A Fork serves as grouping device within the Session.
Definition: fork.hpp:103
Interface for accessing rule based configuration.
Primary Interface to the current Session.
Supporting queries for session contents.
static session::MObjectFactory create
Storage for the (single, static) MObject factory object.
Definition: mobject.hpp:98
The asset subsystem of the Steam-Layer.
Definition: wrapperptr.hpp:44
Generic interface to express a query for specifically typed result elements exposing some capabilitie...
Definition: query.hpp:279
Naming and labelling scheme for structural assets.
string extractID(Symbol predicate) const
convenience shortcut to extract a desired name-ID.
Definition: query.hpp:595
bool contains(SEQ const &cont, typename SEQ::const_reference val)
shortcut for brute-force containment test in any sequential container
Definition: util.hpp:255
Top level structural element within the session.
Factory specialised for creating Structural Asset objects.
Definition: struct.hpp:145