Lumiera  0.pre.03
»edit your freedom«
placement-index.hpp File Reference

Go to the source code of this file.

Description

Core of the session implementation datastructure.

The PlacementIndex is attached to and controlled by the SessionImpl. Client code is not intended to interface directly to this API. Even Steam-Layer internal facilities use the session datastructure through SessionServices. Embedded within the implementation of PlacementIndex is a flat table structure holding all the Placement instances contained in the session. Any further structuring exists on the logical level only.

PlacementIndex, PlacementRef and MObjectRef
Objects are attached to the session by adding (copying) a Placement instance, and doing so creates a new Placement-ID, which from then on acts as a shorthand for "the object instance" within the session. As long as this instance isn't removed from the session / PlacementIndex, a direct (language) reference can be used to work with "the object instance"; accessing this way is adequate for implementation code living within Lumiera's Steam-Layer.

To avoid the dangerous dependency on a direct reference, external code would rather rely on the Placement-ID. Moreover, being a simple value, such an ID can be passed through plain C APIs. PlacementRef is a smart-ptr like wrapper, containing just such an ID; dereferentiation transparently causes a lookup operation through the PlacementIndex of the current session. (accessing an invalid PlacementRef throws)

When it comes to ownership and lifecycle management, external client code should use MObjectRef instances. In addition to containing a PlacementRef, these set up a smart-ptr managing the MObject instance and sharing ownership with the Placement contained within the PlacementIndex. Usually, the commands expressing any mutating operations on the session, bind MObjectRef instances as arguments; similarly, the public API functions on the Session interface (and similar facade interfaces) are written in terms of MObectRef.

placement scopes
When adding a Placement to the index, it is mandatory to specify a Scope: this is another Placement already registered within the index; the new Placement can be thought of as being located "within" or "below" this scope-defining reference Placement. An typical example would be the addition of a Placement<session::Clip>, specifying a Placement<session::Fork> as scope. This would bring the mentioned Clip onto the "Track", as implemented by a Fork-MObject. Thus, all "object instances" within the session are arranged in a tree-like fashion. On creation of the PlacementIndex, a root element needs to be provided. While this root element has a meaning for the session, within the index it is just a scope-providing element. Note that a non-empty scope can't be deleted from the Index.
querying and contents discovery
As "the object instance within the session" is synonymous to the placement instance managed by PlacementIndex, the (hash)-ID of such a placement can be used as an object identifier (it is implemented as LUID and stored within the Placement instance). Thus, a basic operation of the index is to fetch a (language) reference to a Placement, given this hash-ID. Another basic operation is to retrieve the scope an given object is living in, represented by the Placement defining this scope (called "scope top"). The reverse operation is also possible: given a scope-defining Placement, we can discover all the other Placements directly contained within this scope: getReferrers(ID) returns an (possibly empty) "Lumiera Forward Iterator", allowing to enumerate the nested elements. Client code within Lumiera's Steam-Layer typically uses this functionality through a ScopeQuery passed to the SessionServices, while external client code would use either QueryFocus and the Scope wrapper objects, or the specific query functions available on the facade objects accessible through the public session API.
type handling
MObjects form a hierarchy and contain RTTI. By special definition trickery, the various instances of the Placement template mirror this hierarchy to some extent. By using the vtable of the referred MObject, a given Placement<MObject> can be casted into a more specifically typed Placement, thus allowing to re-gain the fully typed context. This technique plays an important role when it comes to generic processing of the session contents by a visitor, and especially within the Builder. This is a fundamental design decision within Steam-Layer: code should not operate on MObjects and do type/capability queries – rather any processing is assumed to happen in a suitable typed context. Consequently, client code will never need to fetch Placements directly from the index. This allows all type information to be discarded on adding (copying) a Placement instance into the PlacementIndex.
Note
PlacementIndex is not threadsafe.
See also
PlacementRef
PlacementIndex_test

Definition in file placement-index.hpp.

#include "lib/error.hpp"
#include "lib/symbol.hpp"
#include "lib/itertools.hpp"
#include "steam/mobject/placement.hpp"
#include "steam/mobject/placement-ref.hpp"
#include "lib/nocopy.hpp"
#include "lib/util.hpp"
#include <unordered_map>
#include <memory>
#include <vector>

Classes

struct  BuildID< PLA >
 Helper for building Placement-ID types. More...
 
struct  BuildID< Placement< MO, BMO > >
 
struct  hash< steam::mobject::PlacementMO::ID >
 
class  PlacementIndex
 Structured compound of Placement instances with lookup capabilities. More...
 

Functions

template<class MOX >
void ___check_compatibleType (PlacementMO &questionable)
 
void __check_knownID (PlacementIndex const &idx, PlacementMO::ID id)
 
 LUMIERA_ERROR_DECLARE (NOT_IN_SESSION)
 referring to a Placement not known to the current session
 
 LUMIERA_ERROR_DECLARE (PLACEMENT_TYPE)
 requested Placement (pointee) type not compatible with data or context
 
 LUMIERA_ERROR_DECLARE (NONEMPTY_SCOPE)
 Placement scope (still) contains other elements.
 

Namespaces

 lumiera
 Lumiera public interface.
 
 steam
 Steam-Layer implementation namespace root.
 
 steam::mobject
 Media-Objects, edit operations and high-level session.
 
 steam::mobject::session
 Namespace of Session and user visible high-level objects.
 

Class Documentation

◆ steam::mobject::session::BuildID

struct steam::mobject::session::BuildID
+ Collaboration diagram for BuildID< PLA >:

◆ steam::mobject::session::BuildID< Placement< MO, BMO > >

struct steam::mobject::session::BuildID< Placement< MO, BMO > >
Class Members
typedef Id< MO > Type
typedef MO Target
+ Collaboration diagram for BuildID< Placement< MO, BMO > >: