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)
5  2008,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 
26 #ifndef ASSET_STRUCT_FACTORY_IMPL_H
27 #define ASSET_STRUCT_FACTORY_IMPL_H
28 
29 
36 #include "common/config-rules.hpp"
37 #include "common/query.hpp"
38 #include "steam/asset/timeline.hpp"
39 #include "steam/asset/sequence.hpp"
40 #include "steam/asset/procpatt.hpp"
41 #include "steam/asset/pipe.hpp"
42 
44 
45 #include "lib/format-string.hpp"
46 #include "lib/query-util.hpp"
47 #include "lib/symbol.hpp"
48 #include "lib/error.hpp"
49 #include "lib/util.hpp"
50 
51 #include <cstdlib>
52 
53 
54 
55 namespace steam {
56 namespace asset {
57 
58  using lib::Symbol;
59  using util::_Fmt;
60  using util::uNum;
61  using util::isnil;
62  using util::contains;
63  using lumiera::Query;
64  using LERR_(CAPABILITY_QUERY);
66 
75 
76  using idi::StructTraits;
77 
78 
79  namespace {
80 
81  Symbol genericIdSymbol ("id");
82  Symbol seqNrPredicate ("ord");
83 
84  }
85 
86 
87 
88 
96  {
97 
101  template<class STRU>
102  const Asset::Ident
103  createIdent (Query<STRU> const& query)
104  {
105  // does the query somehow specify the desired name-ID?
106  string nameID = query.extractID (genericIdSymbol);
107  if (isnil (nameID))
108  nameID = query.extractID (StructTraits<STRU>::idSymbol());
109  if (isnil (nameID))
110  {
111  // no name-ID contained in the query...
112  // so we'll create a new one
113  static int i=0;
114  nameID = _Fmt("%s.%d")
116  % (++i);
117  }
118  ENSURE (!isnil (nameID));
119 
120  // does the query actually demand the Nth instance/element?
121  string seqID = query.extractID (seqNrPredicate);
122  if (!isnil (seqID) && 1 < uNum(seqID))
123  nameID += "."+seqID;
124 
125  Category cat (STRUCT, StructTraits<STRU>::catFolder());
126  return Asset::Ident (nameID, cat );
127  }
128 
129 
131  RFork
132  getFork_forSequence (string const& desiredID)
133  {
134  RFork fork;
135  if (!isnil (desiredID))
136  fork = Session::current->elements.pick (match_specificFork (desiredID));
137 
138  if (fork && !Scope::containing (fork.getRef()).isRoot())
139  {
140  UNIMPLEMENTED ("how to deal with 'stealing' a fork sub-tree to a new sequence??");
141  }
142  if (!fork)
143  fork = Session::current->getRoot().attach (MObject::create (ForkID (desiredID)));
144 
145  return fork;
146  }
147 
148 
149 
150 
151 
152 
153 
154 
157 
158  public:
159  StructFactoryImpl (StructFactory& interface)
160  : recursive_create_(interface)
161  { }
162 
163 
164 
169  template<class STRU>
170  STRU* fabricate (Query<STRU> const& caps)
171  {
172  throw error::Config ("The following Query could not be resolved: " + caps.asKey()
173  , LUMIERA_ERROR_CAPABILITY_QUERY );
174  }
175 
176  };
177 
178 
179  /* ============= specialisations =========================== */
180 
181  template<>
182  inline const ProcPatt*
184  {
185  TODO ("actually extract properties/capabilities from the query...");
186  return new ProcPatt (createIdent (caps));
187  }
188 
189  template<>
190  inline Pipe*
192  {
193  const Asset::Ident idi (createIdent (caps));
194  string streamID = caps.extractID ("stream");
195  if (isnil (streamID)) streamID = "default";
196  PProcPatt processingPattern = Session::current->defaults (Query<const ProcPatt>("stream("+streamID+")"));
197  return new Pipe( idi
198  , streamID
199  , processingPattern
200  );
201  }
202 
203  template<>
204  inline Timeline*
206  {
207  TODO ("extract additional properties/capabilities from the query...");
208  const Asset::Ident idi (createIdent (caps));
209  string sequenceID = caps.extractID ("sequence");
210  Query<Sequence> desiredSequence (isnil (sequenceID)? "" : "id("+sequenceID+")");
211  PSequence sequence = recursive_create_(desiredSequence);
212  ASSERT (sequence);
213  RBinding newBinding = Session::current->getRoot().attach (MObject::create (sequence));
214  ASSERT (newBinding);
215  PTimeline newTimeline = Timeline::create (idi, newBinding);
216  ENSURE (newTimeline);
217  return newTimeline.get();
218  }
219 
220  template<>
221  inline Sequence*
223  {
224  // when we reach this point it is clear a suitable sequence doesn't yet exist in the model
225  TODO ("actually extract properties/capabilities from the query...");
226  string forkID = caps.extractID ("fork");
227  Query<Fork> desiredFork (isnil (forkID)? "" : "id("+forkID+")");
228 // PFork fork = Session::current->query (desiredFork); ///////////////////////////////////TICKET #639
229  // TODO: handle the following cases
230  // - fork doesn't exist --> create and attach it as root
231  // - fork exists and is root attached, but belongs already to a sequence --> throw
232  // - fork exists, but isn't root attached ---> what do do here? steal it??
233  PSequence newSequence = Sequence::create (createIdent (caps));
234  ENSURE (newSequence);
235  return newSequence.get();
236  }
237 
238 
239 
240 
241 }} // namespace steam::asset
242 #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:85
"Processing Pattern" is a structural Asset representing information how to build some part of the ren...
Definition: procpatt.hpp:52
TODO type comment.
Definition: sequence.hpp:83
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:66
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:120
static Scope containing(PlacementMO const &aPlacement)
discover the enclosing scope of a given Placement
Definition: scope.cpp:184
Steam-Layer implementation namespace root.
A front-end for using printf-style formatting.
DefaultsAccess defaults
manages default configured objects
Definition: session.hpp:122
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:70
A Placement scope within the high-level-model.
Definition: scope.hpp:69
MObject is the interface class for all "Media Objects".
Definition: mobject.hpp:70
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:190
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:92
The (current) Session holds all the user visible content to be edited and manipulated within the Lumi...
Definition: session.hpp:100
Structural building block of the session: a sequence of clips.
Token or Atom with distinct identity.
Definition: symbol.hpp:117
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:149
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:94
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:89
The asset subsystem of the Steam-Layer.
Definition: wrapperptr.hpp:35
Generic interface to express a query for specifically typed result elements exposing some capabilitie...
Definition: query.hpp:270
Naming and labelling scheme for structural assets.
string extractID(Symbol predicate) const
convenience shortcut to extract a desired name-ID.
Definition: query.hpp:586
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:136