Job-Ticket: consider how to deal with channels and prerequisites
By reasoning and analysis I conclude that the differentiation into multiple channels is likely misplaced in JobTicket; it belongs ratther into the Segment and should provide a suitable JobTicket for each ModelPort Handling of prerequisites also needs to be reshaped entirely after switching to a pipeline builder for the Job-planning pipeline; as preliminary access point, just add an iterator over the immediate prerequisites, thereby shifting the exploration mechanism entirely out of the JobTicket implementation
This commit is contained in:
parent
db87de3c92
commit
27a8e91fa2
7 changed files with 359 additions and 62 deletions
|
|
@ -472,6 +472,8 @@ namespace diff{
|
|||
bool hasAttribute (string key) const;
|
||||
bool isNested() const;
|
||||
bool hasChildren() const;
|
||||
Rec::scopeIter getChildren() const;
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
|
@ -817,6 +819,12 @@ namespace diff{
|
|||
{
|
||||
return not isnil (data.childIter());
|
||||
}
|
||||
|
||||
inline Rec::scopeIter
|
||||
GenNode::getChildren() const
|
||||
{
|
||||
return data.childIter();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "lib/hierarchy-orientation-indicator.hpp"
|
||||
#include "lib/linked-elements.hpp"
|
||||
#include "lib/iter-adapter.hpp"
|
||||
#include "lib/itertools.hpp"
|
||||
#include "lib/meta/tuple-helper.hpp"
|
||||
#include "lib/meta/trait.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
|
@ -121,7 +122,7 @@ using lib::LUID;
|
|||
};
|
||||
|
||||
|
||||
LinkedElements<Provision> provision_;
|
||||
LinkedElements<Provision> provision_; //////////////////////////////////////////////////TICKET #1297 : retract differentiation into channels here (instead use ModelPorts in the Segment)
|
||||
|
||||
|
||||
template<class IT>
|
||||
|
|
@ -144,8 +145,18 @@ using lib::LUID;
|
|||
|
||||
|
||||
|
||||
ExplorationState startExploration() const;
|
||||
ExplorationState discoverPrerequisites (uint channelNr =0) const;
|
||||
ExplorationState startExploration() const; ////////////////////////////TICKET #1276 : likely to become obsolete
|
||||
ExplorationState discoverPrerequisites (uint channelNr =0) const; ////////////////////////////TICKET #1276 : likely to become obsolete
|
||||
|
||||
auto
|
||||
getPrerequisites (uint slotNr =0) const
|
||||
{
|
||||
return lib::transformIterator (provision_[slotNr].requirements.begin()
|
||||
,[](Prerequisite& prq) -> JobTicket&
|
||||
{
|
||||
return prq.descriptor;
|
||||
});
|
||||
}
|
||||
|
||||
Job createJobFor (FrameCoord coordinates) const;
|
||||
|
||||
|
|
@ -301,7 +312,7 @@ using lib::LUID;
|
|||
,"require at least specification for one channel");
|
||||
|
||||
LinkedElements<Provision> provisionSpec; //////////////////////////////////////////////////TICKET #1292 : need to pass in Allocator as argument
|
||||
for ( ; featureSpec; ++featureSpec)
|
||||
for ( ; featureSpec; ++featureSpec) ///////////////////////////////////////////////////TICKET #1297 : this additional iteration over channels will go away
|
||||
{
|
||||
JobFunctor& func = std::get<0> (*featureSpec);
|
||||
HashVal invoSeed = std::get<1> (*featureSpec);
|
||||
|
|
@ -309,7 +320,7 @@ using lib::LUID;
|
|||
for (Preq pre = std::get<2> (*featureSpec); pre; ++pre)
|
||||
provision.requirements.emplace<Prerequisite> (*pre);
|
||||
}
|
||||
provisionSpec.reverse(); // retain order of given definitions per channel
|
||||
provisionSpec.reverse(); // retain order of given definitions per channel ////////////TICKET #1297 : obsolete; instead we differentiate by OutputSlot in the Segment
|
||||
ENSURE (not isnil (provisionSpec));
|
||||
return provisionSpec;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ namespace fixture {
|
|||
TimeSpan span_;
|
||||
|
||||
/** render plan / blueprint to use for this segment */
|
||||
const engine::JobTicket* jobTicket_;
|
||||
const engine::JobTicket* jobTicket_; ////////////////////////////////////////////////////TICKET #1297 : probably we'll get an array per ModelPort here
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #725 : placeholder code
|
||||
/** relevant MObjects comprising this segment. */
|
||||
|
|
@ -78,7 +78,7 @@ namespace fixture {
|
|||
Segment (TimeSpan covered =TimeSpan::ALL
|
||||
,const engine::JobTicket* ticket =nullptr)
|
||||
: span_{covered}
|
||||
, jobTicket_{ticket? ticket : &engine::JobTicket::NOP}
|
||||
, jobTicket_{ticket? ticket : &engine::JobTicket::NOP} //////////////////////////////////////////TICKET #1297 : ensure to provide a JobTicket for each ModelPort in initialisation
|
||||
{ }
|
||||
|
||||
Segment (Segment const& original, TimeSpan changed)
|
||||
|
|
@ -92,7 +92,7 @@ namespace fixture {
|
|||
Time after() const { return span_.end(); }
|
||||
|
||||
engine::JobTicket const&
|
||||
jobTicket() const
|
||||
jobTicket() const /////////////////////////////////////////////////////////////////TICKET #1297 : introduce additional key per ModelPort here
|
||||
{
|
||||
REQUIRE (jobTicket_);
|
||||
return *jobTicket_;
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
#include "lib/diff/gen-node.hpp"
|
||||
#include "lib/depend.hpp"
|
||||
#include "lib/itertools.hpp"
|
||||
//#include "lib/iter-tree-explorer.hpp"
|
||||
//#include "lib/util-coll.hpp"
|
||||
#include "vault/real-clock.hpp"
|
||||
#include "lib/test/test-helper.hpp"
|
||||
|
|
@ -140,24 +141,21 @@ namespace test {
|
|||
|
||||
|
||||
|
||||
template<class IT>
|
||||
inline auto
|
||||
defineBottomSpec()
|
||||
defineSpec (HashVal seed, IT&& prereq)
|
||||
{
|
||||
auto emptyPrereq = lib::nilIterator<JobTicket&>();
|
||||
using Iter = decltype(emptyPrereq);
|
||||
using SpecTuple = std::tuple<JobFunctor&, HashVal, Iter>;
|
||||
return lib::singleValIterator(
|
||||
SpecTuple(DummyJob::getFunctor(), 0, emptyPrereq));
|
||||
using SpecTuple = std::tuple<JobFunctor&, HashVal, IT>;
|
||||
return lib::singleValIterator( /////////////////////////////////////////////TICKET #1297 : multiplicity per channel will be removed here
|
||||
SpecTuple(DummyJob::getFunctor()
|
||||
, seed
|
||||
, std::forward<IT> (prereq)));
|
||||
}
|
||||
|
||||
inline auto
|
||||
defineSimpleSpec (HashVal seed) /////////////////TODO collapse with defineBottomSpec() ??
|
||||
defineSimpleSpec (HashVal seed =0)
|
||||
{
|
||||
auto emptyPrereq = lib::nilIterator<JobTicket&>();
|
||||
using Iter = decltype(emptyPrereq);
|
||||
using SpecTuple = std::tuple<JobFunctor&, HashVal, Iter>;
|
||||
return lib::singleValIterator(
|
||||
SpecTuple(DummyJob::getFunctor(), seed, emptyPrereq));
|
||||
return defineSpec (seed, lib::nilIterator<JobTicket&>());
|
||||
}
|
||||
|
||||
}//(End)internal test helpers....
|
||||
|
|
@ -178,13 +176,18 @@ namespace test {
|
|||
|
||||
public:
|
||||
MockJobTicket()
|
||||
: JobTicket{defineBottomSpec()}
|
||||
: JobTicket{defineSimpleSpec()}
|
||||
{ }
|
||||
|
||||
MockJobTicket (HashVal seed)
|
||||
: JobTicket{defineSimpleSpec (seed)}
|
||||
{ }
|
||||
|
||||
template<class IT>
|
||||
MockJobTicket (HashVal seed, IT&& prereq)
|
||||
: JobTicket{defineSpec (seed, std::forward<IT> (prereq))}
|
||||
{ }
|
||||
|
||||
bool verify_associated (Job const&) const;
|
||||
static bool isAssociated (Job const&, JobTicket const&);
|
||||
private:
|
||||
|
|
@ -207,16 +210,38 @@ namespace test {
|
|||
{
|
||||
for (auto& spec : specs)
|
||||
{
|
||||
JobTicket* newTicket = nullptr;
|
||||
auto seed = spec.retrieveAttribute<int> ("mark");
|
||||
tickets_.emplace_back (seed? HashVal(*seed) : HashVal(rand() % 1000));
|
||||
newTicket = & tickets_.back();
|
||||
JobTicket& newTicket = buildTicketFromSpec (spec);
|
||||
|
||||
auto start = spec.retrieveAttribute<Time> ("start");
|
||||
auto after = spec.retrieveAttribute<Time> ("after");
|
||||
Segmentation::splitSplice (start, after, newTicket);
|
||||
Segmentation::splitSplice (start, after, &newTicket);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
HashVal
|
||||
buildSeed (GenNode const& spec)
|
||||
{
|
||||
auto seed = spec.retrieveAttribute<int> ("mark");
|
||||
return seed? HashVal(*seed) : HashVal(rand() % 1000);
|
||||
}
|
||||
|
||||
auto
|
||||
buildPrerequisites (GenNode const& spec)
|
||||
{
|
||||
return lib::transformIterator (spec.getChildren()
|
||||
,[this](GenNode const& childSpec) -> JobTicket&
|
||||
{
|
||||
return buildTicketFromSpec (childSpec);
|
||||
});
|
||||
}
|
||||
|
||||
JobTicket&
|
||||
buildTicketFromSpec (GenNode const& spec)
|
||||
{
|
||||
return tickets_.emplace_back (buildSeed(spec)
|
||||
,buildPrerequisites(spec));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ namespace test {
|
|||
verify_MockJob();
|
||||
verify_MockJobTicket();
|
||||
verify_MockSegmentation();
|
||||
verify_MockPrerequisites();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -81,7 +82,7 @@ namespace test {
|
|||
CHECK (3 == mockSegs.size());
|
||||
fixture::Segment const& seg = mockSegs[Time{0,15}]; // access anywhere 10s <= t < 20s
|
||||
|
||||
JobTicket const& ticket = seg.jobTicket();
|
||||
JobTicket const& ticket = seg.jobTicket(); ///////////////////////////////////////////////////TICKET #1297 : will need to pass a ModelPort number here (use the first one, i.e. 0)
|
||||
|
||||
FrameCoord coord;
|
||||
coord.absoluteNominalTime = Time(0,15);
|
||||
|
|
@ -291,6 +292,44 @@ namespace test {
|
|||
CHECK (0 == probeKey(s5));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @test build a Segment with additional prerequisites,
|
||||
* resulting in additional JobTickets to explore and
|
||||
* additional prerequisite Jobs to build for each frame.
|
||||
*/
|
||||
void
|
||||
verify_MockPrerequisites()
|
||||
{
|
||||
FrameCoord coord;
|
||||
//-----------------------------------------------------------------/// one Segment with one additional prerequisite
|
||||
{
|
||||
MockSegmentation mockSegs{MakeRec()
|
||||
.attrib("mark", 11)
|
||||
.scope(MakeRec()
|
||||
.attrib("mark",23)
|
||||
.genNode())
|
||||
.genNode()};
|
||||
CHECK (1 == mockSegs.size());
|
||||
JobTicket const& ticket = mockSegs[Time::ZERO].jobTicket();
|
||||
auto prereq = ticket.getPrerequisites();
|
||||
CHECK (not isnil (prereq));
|
||||
|
||||
JobTicket const& preTicket = *prereq;
|
||||
++prereq;
|
||||
CHECK (isnil (prereq));
|
||||
|
||||
Job job1 = preTicket.createJobFor (coord);
|
||||
Job job2 = ticket.createJobFor (coord);
|
||||
|
||||
job1.triggerJob();
|
||||
job2.triggerJob();
|
||||
CHECK (23 == DummyJob::invocationAdditionalKey (job1));
|
||||
CHECK (11 == DummyJob::invocationAdditionalKey (job2));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2303,7 +2303,7 @@ Any feed corresponds to a specific ModelPort, which in turn typically correspond
|
|||
When starting playback or render, a play process (with a PlayController front-end for client code) is established to coordinate the processing. This ongoing data production might encompass multiple media streams, i.e. multiple feeds pulled from several model ports and delivered into several [[output slots|OutputSlot]]. Each feed in turn might carry structured MultichannelMedia, and is thus further structured into individual [[streams of calculation|CalcStream]]. Since the latter are //stateless descriptors,// while the player and play process obviously is stateful, it's the feed's role to mediate between a state-based (procedural) and a stateless (functional and parallelised) organisation model -- ensuring a seamless data feed even during modification of the playback parameters.
|
||||
</pre>
|
||||
</div>
|
||||
<div title="Fixture" modifier="Ichthyostega" created="200706220324" modified="202304271631" tags="def spec Builder Model" changecount="2">
|
||||
<div title="Fixture" modifier="Ichthyostega" created="200706220324" modified="202305111228" tags="def spec Builder Model" changecount="7">
|
||||
<pre>a specially configured view -- joining together high-level and low-level model.
|
||||
The Fixture acts as //isolation layer// between the two models, and as //backbone to attach the render nodes.//
|
||||
* all MObjects have their position, length and configuration set up ready for rendering.
|
||||
|
|
@ -2325,11 +2325,10 @@ The fixture is like a grid, where one dimension is given by the [[model ports|Mo
|
|||
;Model Ports
|
||||
:The model ports share a single uniform and global name space: actually they're keyed by ~Pipe-ID
|
||||
:Model ports are derived as a result of the build process, as the //residuum// of all nodes not connected any further
|
||||
:Each port belongs to a specific Timeline and is associated with the [[Segmentation]] of that timeline.
|
||||
:Each port belongs to a specific Timeline and is associated with the [[Segmentation]] of that timeline, yet this partitioning of the time axis is relevant for all the model ports //of this timeline// -- while //segment// is defined as a time interval with an uniform (non-changing) calculation scheme.
|
||||
|
||||
;Segmentation
|
||||
:The segmentation partitiones the time axis of a single timeline into segments of constant (wiring) configuration
|
||||
:Together, the segments form a seamless sequence of time intervals. They contain a copy of each (explicit) placement of a visible object touching that time interval. Besides that, segments are the top level grouping device of the render engine node graph; individual segments are immutable, they are built and discarded as a whole chunk.
|
||||
:The segmentation partitiones the time axis of a single timeline into segments of constant (wiring) configuration. Together, the segments form a seamless sequence of time intervals. They expose an API (»JobTicket«) for generating render jobs for each port -- and they contain a copy of each (explicit) placement of a visible object touching that time interval. Besides that, segments are the top level grouping device of the render engine node graph; individual segments are immutable, they are built and discarded as a whole chunk.
|
||||
:Segments (and even a different Segmentation) may be //hot swapped// into an ongoing render.
|
||||
|
||||
;Exit Nodes
|
||||
|
|
@ -2531,7 +2530,7 @@ Additionally, they may be used for resource management purposes by embedding a r
|
|||
#* one OpenGL Dataframe could contain raw texture data (but I am lacking expertise for this topic)
|
||||
</pre>
|
||||
</div>
|
||||
<div title="FrameDispatcher" modifier="Ichthyostega" created="201105222330" modified="202304170244" tags="def Rendering" changecount="18">
|
||||
<div title="FrameDispatcher" modifier="Ichthyostega" created="201105222330" modified="202305111243" tags="def Rendering" changecount="20">
|
||||
<pre>An entity within the RenderEngine, responsible for translating a logical [[calculation stream|CalcStream]] (corresponding to a PlayProcess) into a sequence of individual RenderJob entries, which can then be handed over to the [[Scheduler]]. Performing this operation involves a special application of [[time quantisation|TimeQuant]]: after establishing a suitable starting point, a typically contiguous series of frame numbers need to be generated, together with the time coordinates for each of those frames.
|
||||
|
||||
The dispatcher works together with the job ticket(s) and the scheduler; actually these are the //core abstractions//&nbsp; the process of ''job planning'' relies on. While the actual scheduler implementation lives within the Vault, the job tickets and the dispatcher are located within the [[Segmentation]], which is the backbone of the [[low-level model|LowLevelModel]]. More specifically, the dispatcher interface is //implemented//&nbsp; by a set of &rarr; [[dispatcher tables|DispatcherTables]] within the segmentation.
|
||||
|
|
@ -2566,7 +2565,7 @@ These complex relationships are reflected in the invocation structure leading to
|
|||
While the sequence of frame jobs to be planned is possibly infinite, the actual evaluation is confined to the current planning chunk. When done with planning such a chunk of jobs, an additional ''continuation job'' is included to prepare a re-invocation of the planning function for preparation of the next chunk. Terminating playback is equivalent to not including or not invoking this continuation job. Please note that planning proceeds independently for each [[Feed]] -- in Lumiera the //current playback position//&nbsp; is just a conceptual projection of wall clock time to nominal time, yet there is no such thing like a synchronously proceeding "Playhead"
|
||||
|
||||
!!!producing actual jobs
|
||||
The JobTicket is created on demand, specialised for a single [[segment|Segmentation]] of the timeline and a single [[feed|Feed]] of data frames to be pulled from a ModelPort. Consequently this means that all frames and all channels within that realm will rely on the same job ticket -- which is a //higher order function,// a function producing another function: when provided with the actual channel number and the specific frame coordinates, the job ticket produces a [[concrete job definition|RenderJob]], which itself is a function to be invoked by the [[scheduler|Scheduler]] just in time.
|
||||
The JobTicket is created on demand, specialised for a single [[segment|Segmentation]] of the timeline and a single [[feed|Feed]] of data frames to be pulled from a ModelPort. Consequently this means that all frames and all channels within that realm will rely on the same job ticket -- which is a //higher order function,// a function producing another function: when provided with the specific frame coordinates (frame number and time point), the job ticket produces a [[concrete job definition|RenderJob]], which itself is a function to be invoked by the [[scheduler|Scheduler]] to carry out the necessary calculations just in time.
|
||||
</pre>
|
||||
</div>
|
||||
<div title="GAVL" modifier="Ichthyostega" created="200809220251" tags="def">
|
||||
|
|
@ -4290,13 +4289,13 @@ Thus an invocation trail represents one specific path leading to the invocation
|
|||
''Note'': {{red{future plans and visions -- no clear and distinct meaning -- as of 4/21}}}
|
||||
</pre>
|
||||
</div>
|
||||
<div title="JobTicket" modifier="Ichthyostega" created="201202120018" modified="201208311625" tags="spec Rendering draft">
|
||||
<div title="JobTicket" modifier="Ichthyostega" created="201202120018" modified="202305111241" tags="spec Rendering draft" changecount="4">
|
||||
<pre>The actual media data is rendered by [[individually scheduled render jobs|RenderJob]]. All these calculations together implement a [[stream of calculations|CalcStream]], as demanded and directed by the PlayProcess. During the preparation of playback, a ''node planning phase'' is performed, to arrange for [[dispatching|FrameDispatcher]] the individual calculations per frame. The goal of these //preparations//&nbsp; is to find out
|
||||
* what channel(s) to pull
|
||||
* what prerequisites to prepare
|
||||
* which [[model ports|ModelPort]] can be processed independently
|
||||
* what prerequisites to prepare beforehand
|
||||
* what parameters to provide
|
||||
The result of this planning phase is the {{{JobTicket}}}, a complete ''execution plan''.
|
||||
This planning is uniform for each [[segment|Segmentation]] and treated for all channels together, resulting in a nested tree structure of sub job tickets, allocated and stored alongside with the processing nodes and wiring descriptors to form the segment's data and descriptor network. Job tickets are //higher order functions:// entering a concrete frame number and channel into a given job ticket will produce an actual job descriptor, which in itself is again a function, to be invoked through the scheduler when it's time to trigger the actual calculations.
|
||||
This planning is uniform for each [[segment|Segmentation]] and treated for all channels together, resulting in a nested tree structure of sub job tickets, allocated and stored alongside with the processing nodes and wiring descriptors to form the segment's data and descriptor network. Job tickets are //higher order functions:// entering a concrete frame number and //absolute nominal time point// of that frame into a given job ticket will produce an actual job descriptor, which in itself is again a function, to be invoked through the scheduler when it's time to trigger the actual calculations.
|
||||
|
||||
!Structure of the Render Jobs created
|
||||
To be more precise: in the general case, invoking the ~JobTicket with a given frame number will produce //multiple jobs// -- typically each frame rendering will require at least one further source media frame; and because Lumiera render jobs will //never block waiting on IO,// this source media access will be packaged as a separate [[resource retrieving job|ResourceJob]], to be treated specifically by the scheduler.
|
||||
|
|
@ -4663,15 +4662,15 @@ These are used as token for dealing with other objects and have no identity of t
|
|||
|
||||
</pre>
|
||||
</div>
|
||||
<div title="ModelPort" modifier="Ichthyostega" created="201011100234" modified="201204150027" tags="def spec Model">
|
||||
<pre>Any point where output possibly might be produced. Model port entities are located within the [[Fixture]] &mdash; model port as a concept spans the high-level and low-level view. A model port can be associated both to a pipe in the HighLevelModel but at the same time denotes a set of corresponding [[exit nodes|ExitNode]] within the [[segments|Segmentation]] of the render nodes network.
|
||||
<div title="ModelPort" modifier="Ichthyostega" created="201011100234" modified="202305111238" tags="def spec Model" changecount="1">
|
||||
<pre>Any point where output possibly might be produced. Model port entities are located within the [[Fixture]] &mdash; model port as a concept spans the high-level and low-level view. A model port can be associated both to a pipe in the HighLevelModel but at the same time denotes a set of corresponding [[exit nodes|ExitNode]] within the [[segments|Segmentation]] of the render nodes network. As far as rendering is concerned, a port corresponds to a [[stream of calculations|CalcStream]] to produce a distinct output data stream, generated time-bound yet asynchronously.
|
||||
|
||||
A model port is rather derived than configured; it emerges when a pipe [[claims|WiringClaim]] an output destination, while some other entity at the same time actually //uses this designation as a target,// either directly or indirectly. This match of provision and usage is detected during the build process and produces an entry in the fixture's model port table. These model ports in the fixture are keyed by ~Pipe-ID, thus each model port has an associated StreamType.
|
||||
|
||||
Model ports are the effective, resulting outputs of each timeline; additional ports result from [[connecting a viewer|ViewConnection]]. Any render or display process happens at a model port.
|
||||
Model ports are the effective, resulting outputs of each timeline; additional ports result from [[connecting a viewer|ViewConnection]]. Any render or display process happens at a model port. The //granularity// of the ports is defined by what data has to be delivered time-bound and together for any conceivable output activity.
|
||||
|
||||
!formal specification
|
||||
Model port is a //conceptual entity,// denoting the possibility to pull generated data of a distinct (stream)type from a specific bus within the model -- any possible output produced or provided by Lumiera is bound to appear at a model port. The namespace of model ports is global, each being associated with a ~Pipe-ID.
|
||||
Model port is a //conceptual entity,// denoting the possibility to pull generated data of a distinct (stream)type from a specific bus within the model -- any possible output produced or provided by Lumiera is bound to appear at a model port. The namespace of model ports is global, each being associated with a ~Pipe-ID. Media can be inherently multi-channel, and when it is delivered as a whole (with multiplexed or planar channels), then such a possible media output stream is represented by a single model port.
|
||||
|
||||
Model ports are represented by small non-copyable descriptor objects with distinct identity, which are owned and managed by the [[Fixture]]. Clients are mandated to resolve a model port on each usage, as configuration changes within the model might cause ports to appear and decease. To stress this usage pattern, actually {{{ModelPort}}} instances are small copyable value objects (smart handles), which can be used to access data within an opaque registry. Each model port belongs to a specific Timeline and is aware of this association, as is the timeline, allowing to get the collection of all ports of a given timeline. Besides, within the Fixture each model port refers to a specific [[segmentation of the time axis|Segmentation]] (relevant for this special timeline actually). Thus, with the help of this segmentation, a model port can yield an ExitNode to pull frames for a given time.
|
||||
|
||||
|
|
@ -6186,7 +6185,7 @@ This is the core service provided by the player subsystem. The purpose is to cre
|
|||
:any details of this processing remain opaque for the clients; even the player subsystem just accesses the EngineFaçade
|
||||
</pre>
|
||||
</div>
|
||||
<div title="PlaybackVerticalSlice" creator="Ichthyostega" modifier="Ichthyostega" created="202303272236" modified="202304132132" tags="overview impl discuss draft" changecount="20">
|
||||
<div title="PlaybackVerticalSlice" creator="Ichthyostega" modifier="Ichthyostega" created="202303272236" modified="202305100203" tags="overview impl discuss draft" changecount="21">
|
||||
<pre>//Integration effort to promote the development of rendering, playback and video display in the GUI//
|
||||
This IntegrationSlice was started in {{red{2023}}} as [[Ticket #1221|https://issues.lumiera.org/ticket/1221]] to coordinate the completion and integration of various implementation facilities, planned, drafted and built during the last years; this effort marks the return of development focus to the lower layers (after years of focussed UI development) and will implement the asynchronous and time-bound rendering coordinated by the [[Scheduler]] in the [[Vault|Vault-Layer]]
|
||||
|
||||
|
|
@ -6196,7 +6195,7 @@ This IntegrationSlice was started in {{red{2023}}} as [[Ticket #1221|https://iss
|
|||
|
||||
|
||||
!Ascent
|
||||
__12.Apr.23__: At start, this is a dauntingly complex effort, prompting to reconcile several unfinished design drafts from years ago, unsuccessful attempts at that time towards a first »breakthrough«. Including a first run-up towards node invocation, the drafts regarding BuilderMechanics and FixtureDatastructure, a complete but never actually implemented OutputManagement concept and the groundwork pertaining to the [[Player]]. At that time, it occurred to me that the planning of render jobs exhibits structures akin to the //Monads// known from functional programming -- seemingly a trending topic. Following this blueprint, it was indeed straight forward to hook up all functional dependencies into a working piece of code -- a piece of code however, that turns out almost impenetrable after completion, since while it can be //verified// step by step, it does not support understanding and convey meaning. This experience (and a lot of similar ones) make me increasingly wary towards the self-proclaimed superiority of functional programming. Especially the Monads might be considered an Anti-pattern, something superficially compelling that lures into fostering unhealthy structures.
|
||||
__12.Apr.23__: At start, this is a dauntingly complex effort, demanding to reconcile several unfinished design drafts from years ago, unsuccessful attempts at that time towards a first »breakthrough«. Including a first run-up towards node invocation, the drafts regarding BuilderMechanics and FixtureDatastructure, a complete but never actually implemented OutputManagement concept and the groundwork pertaining to the [[Player]]. At that time, it occurred to me that the planning of render jobs exhibits structures akin to the //Monads// known from functional programming -- seemingly a trending topic. Following this blueprint, it was indeed straight forward to hook up all functional dependencies into a working piece of code -- a piece of code however, that turns out almost impenetrable after completion, since while it can be //verified// step by step, it does not support understanding and convey meaning. This experience (and a lot of similar ones) make me increasingly wary towards the self-proclaimed superiority of functional programming. Especially the Monads might be considered an Anti-pattern, something superficially compelling that lures into fostering unhealthy structures.
|
||||
&rarr; see the critical review in AboutMonads
|
||||
|
||||
So the difficulties to understand my own (finished, working) code after several years compelled me to attempt a [[#1276|https://issues.lumiera.org/ticket/1276#comment:1]] refactoring of the FrameDispatcher, which I use as entrance point into the implementation of this //vertical slice//. This time I will approach the task as //on-demand processing pipeline// with //recursive expansion// -- attempting to segregate better what the monadic approach tended to interweave.
|
||||
|
|
@ -7101,7 +7100,7 @@ We need to detect attaching and detaching of
|
|||
* root &harr; [[Fork]]
|
||||
</pre>
|
||||
</div>
|
||||
<div title="Segmentation" modifier="Ichthyostega" created="201012121901" modified="202305020219" tags="def spec Builder" changecount="5">
|
||||
<div title="Segmentation" modifier="Ichthyostega" created="201012121901" modified="202305111222" tags="def spec Builder" changecount="6">
|
||||
<pre>//Segmentation of timeline// denotes a data structure and a step in the BuildProcess.
|
||||
When [[building the fixture|BuildFixture]], ~MObjects -- as handled by their Placements -- are grouped below each timeline using them; Placements are then to be resolved into [[explicit Placements|ExplicitPlacement]], resulting in a single well defined time interval for each object. This allows to cut this effective timeline into slices of constant wiring structure, which are represented through the ''Segmentation Datastructure'', a time axis with segments holding object placements and [[exit nodes|ExitNode]]. &nbsp;&rarr; see [[structure of the Fixture|Fixture]]
|
||||
* for each Timeline we get a Segmentation
|
||||
|
|
@ -7109,6 +7108,7 @@ When [[building the fixture|BuildFixture]], ~MObjects -- as handled by their Pla
|
|||
*** each holding
|
||||
**** an ExplicitPlacement for each object touching that time interval
|
||||
**** an ExitNode for each ModelPort of the corresponding timeline
|
||||
**** a JobTicket as blueprint for [[frame Job|RenderJob]] generation corresponding to each ModelPort
|
||||
|
||||
!Usage pattern
|
||||
;(1) build process
|
||||
|
|
|
|||
|
|
@ -68407,6 +68407,58 @@
|
|||
<node CREATED="1681685173232" ID="ID_1497274477" MODIFIED="1681685179516" TEXT="Play-controller"/>
|
||||
<node CREATED="1681685180222" ID="ID_1922002466" MODIFIED="1681685183138" TEXT="Play-Process"/>
|
||||
<node CREATED="1681685183696" ID="ID_453528685" MODIFIED="1681685186032" TEXT="CalcStream">
|
||||
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1683764496171" ID="ID_1519871278" MODIFIED="1683764510173" TEXT="Definition">
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1683764524455" ID="ID_225445096" MODIFIED="1683764836855" TEXT="jeder CalcStream korrespondiert zu einem realen Daten-Strom">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Und zwar 1:1
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
hierbei bedeutet »Datenstrom« eine Folge von Daten-Frames, die in <i>timed delivery</i> übergeben werden
|
||||
</li>
|
||||
<li>
|
||||
jeder Datenstrom entspricht <i>genau einer Instanz</i> eines Protokolls zur Puffer-Übergabe
|
||||
</li>
|
||||
<li>
|
||||
jeder Datenstrom kann <i>für sich gesondert</i> unterbrochen sein, sich verzögern und hat eine einzige, wohldefinierte Stromgeschwindigkeit
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1683764857963" ID="ID_852816952" MODIFIED="1683765160558" TEXT="ein CalcStream kann durchaus mehrere Berechnungs-Stränge für logische Kanäle beinhalten">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Aber nur, insofern diese logischen Kanäle in den einzigen Datenstrom einfließen, und stets gebündelt auftreten; sie müssen hierfür durch einen Multiplex-Schritt in einen Datenstrom zusammengeführt werden. Die rein logische Ordnung der Kanäle zu einem Medium ist bedeutungslos; was zählt ist was konkret in einem Strom hergestellt und geliefert werden muß
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1683764942060" ID="ID_272807498" MODIFIED="1683765236302" TEXT="ein CalcStream ist aber ein Unikat und ist nicht weiter differenzierbar">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Sofern eine CalcStream-Instanz besteht, bedeutet das, daß Berechnungen laufen und Daten im Datenstrom anfallen. Ein Datenstrom ist insofern nicht weiter zerlegbar und auch nicht weiter parametrisierbar
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1681685187803" ID="ID_1654025761" MODIFIED="1681685196333" TEXT="Umbau 4/23">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1681685197444" ID="ID_1313231227" MODIFIED="1681685335962" TEXT="kann man CalcStream move-only machen?">
|
||||
|
|
@ -69361,9 +69413,10 @@
|
|||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1681007034731" ID="ID_380471864" MODIFIED="1681007071540" TEXT="Implementierung (dispatcher-table) nur gestubbed">
|
||||
<icon BUILTIN="bell"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1681425423695" ID="ID_1928295133" MODIFIED="1681685384037" TEXT="Reorganisation : RenderDrive verwenden">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1681425423695" ID="ID_1928295133" MODIFIED="1683836443972" TEXT="Reorganisation : RenderDrive verwenden">
|
||||
<linktarget COLOR="#f4fec9" DESTINATION="ID_1928295133" ENDARROW="Default" ENDINCLINATION="-1068;-69;" ID="Arrow_ID_362199078" SOURCE="ID_1888344503" STARTARROW="None" STARTINCLINATION="1381;58;"/>
|
||||
<linktarget COLOR="#ffe4c9" DESTINATION="ID_1928295133" ENDARROW="Default" ENDINCLINATION="-724;353;" ID="Arrow_ID_1773297165" SOURCE="ID_845968912" STARTARROW="None" STARTINCLINATION="-257;23;"/>
|
||||
<linktarget COLOR="#fed5d7" DESTINATION="ID_1928295133" ENDARROW="Default" ENDINCLINATION="-463;400;" ID="Arrow_ID_1972838231" SOURCE="ID_580321819" STARTARROW="None" STARTINCLINATION="-412;-64;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1681597653622" ID="ID_1608883275" MODIFIED="1681597683317" TEXT="Eigenschaften">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
|
|
@ -69648,10 +69701,10 @@
|
|||
<node COLOR="#338800" CREATED="1681833031252" HGAP="29" ID="ID_1232985944" MODIFIED="1682953126289" TEXT="leer" VSHIFT="14">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1681833034545" ID="ID_1378629902" MODIFIED="1681833049605" TEXT="rekursiv mit Prerequisite">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1682205060282" ID="ID_290012620" MODIFIED="1683835350728" TEXT="mehrere Segmente">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1682205060282" ID="ID_290012620" MODIFIED="1682205066370" TEXT="mehrere Segmente">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1681833034545" ID="ID_1378629902" MODIFIED="1681833049605" TEXT="rekursiv mit Prerequisite">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -69699,7 +69752,7 @@
|
|||
<node CREATED="1682613762760" ID="ID_970667296" MODIFIED="1682613815597" TEXT="Datenstruktur kann (bedenkenlos) direkt manipuliert werden">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1682613782480" ID="ID_178794461" MODIFIED="1682614001907" TEXT="Split-and-Splice-Operation implementieren">
|
||||
<node COLOR="#338800" CREATED="1682613782480" ID="ID_178794461" MODIFIED="1683809842806" TEXT="Split-and-Splice-Operation implementieren">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
|
|
@ -69724,7 +69777,7 @@
|
|||
</ul>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -69765,7 +69818,7 @@
|
|||
<node CREATED="1682385053111" ID="ID_285349039" MODIFIED="1682385061769" TEXT="Reihenfolge ist zu erhalten"/>
|
||||
<node CREATED="1682385069872" ID="ID_1300373934" MODIFIED="1682385080052" TEXT="dabei aber noch sortiert nach Channel"/>
|
||||
</node>
|
||||
<node CREATED="1682384817342" ID="ID_1041945883" MODIFIED="1682385604629" TEXT="Channel-Zuordnung nur per Filter/Marker">
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1682384817342" ID="ID_1041945883" MODIFIED="1683809828917" TEXT="Channel-Zuordnung nur per Filter/Marker">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
|
|
@ -69776,6 +69829,16 @@
|
|||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="hourglass"/>
|
||||
<node COLOR="#435e98" CREATED="1683809711717" ID="ID_1916276594" LINK="#ID_1346581014" MODIFIED="1683809780483" TEXT="Channel sind tatsächlich OutputSlots">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1683809741762" ID="ID_610603117" MODIFIED="1683809760081" TEXT="daher wandern sie vom JobTicket in das Segment">
|
||||
<icon BUILTIN="hourglass"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1683809804057" ID="ID_733275282" MODIFIED="1683809818893" TEXT="Thema vorerst ignorieren (immer ein Channel und gut is)">
|
||||
<icon BUILTIN="bell"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -69821,9 +69884,16 @@
|
|||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1682204997554" ID="ID_599701197" MODIFIED="1682205023588" TEXT="Prerequisites hinzufügen">
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1682204997554" ID="ID_599701197" MODIFIED="1683837481941" TEXT="Prerequisites hinzufügen">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1683836490113" ID="ID_1045524420" MODIFIED="1683837475432" TEXT="per rekursiver GenNode-Auswertung">
|
||||
<icon BUILTIN="pencil"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1683836500089" ID="ID_993440863" MODIFIED="1683836585531" TEXT="testen über neues Interface getPrerequisites()">
|
||||
<arrowlink COLOR="#eb64a1" DESTINATION="ID_885444410" ENDARROW="Default" ENDINCLINATION="338;-2145;" ID="Arrow_ID_1011579074" STARTARROW="None" STARTINCLINATION="-152;9;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1682868258074" ID="ID_1743148920" MODIFIED="1682898174253" TEXT="Job aus Ticket erstellen und ausführbar machen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1682885817579" ID="ID_1080671855" MODIFIED="1682886037986" TEXT="Hash für Zeitwerte definieren">
|
||||
|
|
@ -70727,8 +70797,8 @@
|
|||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1681861418620" ID="ID_1440642182" MODIFIED="1682027038910" TEXT="Spezifikations-Schnittstelle schaffen">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1681861418620" ID="ID_1440642182" MODIFIED="1683809676177" TEXT="Spezifikations-Schnittstelle schaffen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1681861430131" ID="ID_38853136" MODIFIED="1681861501198" TEXT="dort könnte auch das ganze Problem Allokation mit verborgen werden">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
|
@ -70797,8 +70867,8 @@
|
|||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1681947704128" ID="ID_1307528426" MODIFIED="1682027027824" TEXT="vorläufige Lösung: Iterator über std::tuple">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1681947704128" ID="ID_1307528426" MODIFIED="1683809658570" TEXT="vorläufige Lösung: Iterator über std::tuple">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1681947910447" ID="ID_1183443190" MODIFIED="1681947934893" TEXT="Begründung">
|
||||
<node CREATED="1681947935610" ID="ID_218509707" MODIFIED="1681947935610" TEXT="sonst müßten wir hier doch einen Deskriptor-Record-Typ einführen"/>
|
||||
<node CREATED="1681947938444" ID="ID_1201610351" MODIFIED="1681947959060" TEXT="und damit einer späteren ausgebauten Builder-Syntax vorgreifen"/>
|
||||
|
|
@ -70850,10 +70920,13 @@
|
|||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1681948045301" ID="ID_1777275098" MODIFIED="1681948056012" TEXT="dann Beispiel-Impl für Mock">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1681948045301" ID="ID_1777275098" MODIFIED="1683809657666" TEXT="dann Beispiel-Impl für Mock">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1683809659597" ID="ID_1140176298" MODIFIED="1683809675249" TEXT="darauf aufbauend: GenNode-Spec für eine MockSegmentation">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -70896,7 +70969,7 @@
|
|||
<linktarget COLOR="#82597c" DESTINATION="ID_922277724" ENDARROW="Default" ENDINCLINATION="43;-81;" ID="Arrow_ID_941233317" SOURCE="ID_946385163" STARTARROW="None" STARTINCLINATION="-124;34;"/>
|
||||
<node CREATED="1681166276225" ID="ID_877524227" MODIFIED="1681166317636" TEXT="ein Execution-Plan gülitg für ein Segment + ModelPort"/>
|
||||
<node CREATED="1681167533752" ID="ID_1794156121" MODIFIED="1681167538096" TEXT="Anforderungen">
|
||||
<node CREATED="1681167546919" ID="ID_1656777068" MODIFIED="1681239514849" TEXT="startExploration()">
|
||||
<node COLOR="#5b280f" CREATED="1681167546919" ID="ID_1656777068" MODIFIED="1683836193612" TEXT="startExploration()">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1681239526094" ID="ID_1262163051" MODIFIED="1681239557592" TEXT="redundant">
|
||||
<icon BUILTIN="closed"/>
|
||||
|
|
@ -70905,10 +70978,23 @@
|
|||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1681167559614" ID="ID_1796690712" MODIFIED="1681167566611" TEXT="discoverPrerequisites()">
|
||||
<node COLOR="#5b280f" CREATED="1681167559614" ID="ID_1796690712" MODIFIED="1683836188333" TEXT="discoverPrerequisites()">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1681239648250" ID="ID_543821327" MODIFIED="1681239654691" TEXT="lazy-on-demand gestartet"/>
|
||||
<node CREATED="1681239661863" ID="ID_893985229" MODIFIED="1681239699686" TEXT="liefert Iterator über alle Voraussetzungen"/>
|
||||
<node CREATED="1681239735718" ID="ID_464013545" MODIFIED="1681239741761" TEXT="rekursive Tiefensuche"/>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1683836139691" ID="ID_1421998826" MODIFIED="1683836159152" TEXT="wird durch neue Impl ersetzt">
|
||||
<icon BUILTIN="closed"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1683836197004" ID="ID_885444410" MODIFIED="1683836585531" TEXT="getPrerequisites">
|
||||
<linktarget COLOR="#eb64a1" DESTINATION="ID_885444410" ENDARROW="Default" ENDINCLINATION="338;-2145;" ID="Arrow_ID_1011579074" SOURCE="ID_993440863" STARTARROW="None" STARTINCLINATION="-152;9;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1683836203943" ID="ID_1933667832" MODIFIED="1683836212926" TEXT="liefert einen Iterator über JobTicket&"/>
|
||||
<node CREATED="1683836213973" ID="ID_571829359" MODIFIED="1683836218117" TEXT="nur eine Ebene tief"/>
|
||||
<node CREATED="1683836226928" ID="ID_580321819" MODIFIED="1683836458419" TEXT="für RenderDrive">
|
||||
<arrowlink COLOR="#fed5d7" DESTINATION="ID_1928295133" ENDARROW="Default" ENDINCLINATION="-463;400;" ID="Arrow_ID_1972838231" STARTARROW="None" STARTINCLINATION="-412;-64;"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1681167579899" ID="ID_428564529" MODIFIED="1681167585941" TEXT="createJobFor(FrameCoord)"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1681861351924" ID="ID_446140172" MODIFIED="1681861366116" TEXT="Builder-Mechanismus bereitstellen">
|
||||
|
|
@ -70973,6 +71059,41 @@
|
|||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1682622228183" ID="ID_1660287725" MODIFIED="1682622235360" TEXT="Redundanz in der Storage?">
|
||||
<icon BUILTIN="help"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1683764368252" ID="ID_304759385" MODIFIED="1683764379441" TEXT="Mehrere Channel oder Slots?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1683765330093" ID="ID_1932564452" LINK="#ID_1519871278" MODIFIED="1683765371671" TEXT="vgl: Identität eines CalcStream">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1683765386669" ID="ID_891227892" MODIFIED="1683765880297" TEXT="Entscheidung: jeder Slot entspricht einem möglichen CalcStream">
|
||||
<arrowlink COLOR="#b9234e" DESTINATION="ID_1133872595" ENDARROW="Default" ENDINCLINATION="78;-135;" ID="Arrow_ID_1952784533" STARTARROW="Default" STARTINCLINATION="-66;89;"/>
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1683765419921" ID="ID_1234868983" MODIFIED="1683765568907" TEXT="es wäre auch anders denkbar">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...uns anders wäre es sogar erst mal viel plausibler; ich selber habe lange Zeit anders gedancht, nämlich das die Channel hier den Medienkanälen entsprechen. Dann müßte man aber jedem CalcStream noch ein Channel-Mapping mitgeben, und auch für Prerequisites müßte eine Transformation für dieses Mapping mit angegeben werden. Daraus wird plausibel, warum ich diesen <i>naiven Ansatz</i> verworfen habe....
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1683765427639" ID="ID_394509672" MODIFIED="1683765784137" TEXT="diese Entscheidung ist eine Konsequenz des Builder-Ansatzes">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...denn der Builder-Ansatz bedeutet, daß das semantische / domänen-bezogene high-level-Modell explizit übersetzt wird in ein reines Ausführungs-Modell. Letzteres soll keine Intelligenz mehr zur Interpretation enthalten, sondern nur noch zwangsläufig ausgeführt werden. Dem entsprechend muß in diesem Ausführungs-Modell (low-level-Modell) jedweder <i>dynamische Auswertungszustand</i> soweit möglich vermieden werden. Zur konkreten Ausführung dennoch erforderlicher Zustand wird symbolisch repräsentiert ("representational state")
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1681167767260" ID="ID_247185233" MODIFIED="1681167820893" TEXT="JobTicket::ExplorationState">
|
||||
<linktarget COLOR="#5c74b4" DESTINATION="ID_247185233" ENDARROW="Default" ENDINCLINATION="28;-86;" ID="Arrow_ID_1572923842" SOURCE="ID_1056088464" STARTARROW="None" STARTINCLINATION="-77;9;"/>
|
||||
|
|
@ -70990,7 +71111,8 @@
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1681742004652" ID="ID_806189817" MODIFIED="1681742017755" TEXT="Addressierung ModelPort / ExitNode">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1681742024628" ID="ID_1133872595" MODIFIED="1681742050101" TEXT="bis auf welchen Level wird differenziert?">
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1681742024628" ID="ID_1133872595" MODIFIED="1683765880297" TEXT="bis auf welchen Level wird differenziert?">
|
||||
<linktarget COLOR="#b9234e" DESTINATION="ID_1133872595" ENDARROW="Default" ENDINCLINATION="78;-135;" ID="Arrow_ID_1952784533" SOURCE="ID_891227892" STARTARROW="Default" STARTINCLINATION="-66;89;"/>
|
||||
<icon BUILTIN="help"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1681742053502" ID="ID_122410804" MODIFIED="1681742065769" TEXT="Idee: auch noch Channel auflösen">
|
||||
<icon BUILTIN="idea"/>
|
||||
|
|
@ -71054,10 +71176,63 @@
|
|||
</html></richcontent>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node CREATED="1683809347294" ID="ID_1241935016" MODIFIED="1683809573348" TEXT="läuft darauf hinaus daß nein!">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...Kernargument ist: das Multiplexing von Medienchannels ist Teil der Berechnungen selber, tritt also nicht auf Interface-Ebene auf. Selbst die Funktionalität des <b>Switch-Board</b> im GUI-Player wird <i>in der Renderpipeline selber</i> implementiert...
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<arrowlink COLOR="#889fa8" DESTINATION="ID_1346581014" ENDARROW="Default" ENDINCLINATION="80;-96;" ID="Arrow_ID_377227941" STARTARROW="None" STARTINCLINATION="-288;25;"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1683766106245" ID="ID_1346581014" MODIFIED="1683809411187">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Klärung: „Channel“ ist hier eine <i>Port-Nummer</i>
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Dies folgt aus den Überlegungen zur Identität eines CalcStream, sowie aus dem Builder-Ansatz: es handelt sich demnach nicht um den Medien-Channel, sondern nur um die Auswahl aus N an dieser Stelle theoretisch möglichen CalcStrams / Daten-Strömen. Im klassischen Standard-Beispiel gäbe es also einen Port für Video und einen Port für Sound, und ein Play-Prozeß könnte optional nur einen oder alle beide abspielen, aber jeder von diesen geht an ein anderes Device und läuft deshalb selbständig. Die Zuordnung eines solchen möglichen Datenstroms zu einer ganz bestimmten Processing-Pipeline ist schon im Build-Vorgang vorentschieden worden, und ist im Job-Ticket jeweils für ein Segment komplett voreingestellt; soll dann konkret ein bestimmter Datenstrom erzeugt werden, muß man nur noch diese Port-Nummer anzugeben, um dafür die passenden Jobs zu generieren
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<linktarget COLOR="#889fa8" DESTINATION="ID_1346581014" ENDARROW="Default" ENDINCLINATION="80;-96;" ID="Arrow_ID_377227941" SOURCE="ID_1241935016" STARTARROW="None" STARTINCLINATION="-288;25;"/>
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1683766676673" ID="ID_1958408222" MODIFIED="1683766698835" TEXT="alle weitere Flexibilität ist im JobFunktor bereits vorverdrahtet"/>
|
||||
<node CREATED="1683766700206" ID="ID_945659088" MODIFIED="1683809030223" TEXT="es ist sinnvoll, die Segmentation über alle Port-Nummern hinweg zu machen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Dies ist erst mal nicht offensichtlich, denn grundsätzlich wird ja immer auf einheitliche Topologie hin segmentiert; es wäre sehr wohl denkbar, daß z.B. der Sound fast durchgehend nur eine einzige Topologie der Processing-Pipeline hat, während für Video mehrfach die Topologie gewechselt wird (Fades, Overlays...). Aber eine praktische Abschätzung ergibt, daß im Regelfall für jeden Clip sowohl die Sound-Quelle, alsauch die Video-Quelle jeweils spezifish ist, auch bezüglich des Offset im Quellmedium; wenn ein Clip wechselt, dann wechseln sowohl Bild und Ton. Daher ist es wahrscheinlich, daß eine feingranularer angesetzte Segmentation in der Regel redundant wäre. Und diese Redundanz wäre kostspielig, denn die Zahl der Segmente ist erwartungsgemäß hoch.
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<arrowlink COLOR="#666dd9" DESTINATION="ID_793444617" ENDARROW="Default" ENDINCLINATION="249;-20;" ID="Arrow_ID_632376357" STARTARROW="None" STARTINCLINATION="-454;17;"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1681742018442" ID="ID_596503548" MODIFIED="1681742022940" TEXT="Addressierung JobTicket">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
|
|
@ -71110,7 +71285,46 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1682611408260" ID="ID_408388335" MODIFIED="1682611410703" TEXT="Interface"/>
|
||||
<node CREATED="1682611408260" ID="ID_408388335" MODIFIED="1682611410703" TEXT="Interface">
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1683762819868" ID="ID_876134804" MODIFIED="1683762858623" TEXT="Fragen / zu klären">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1683764133596" ID="ID_499268961" MODIFIED="1683764143358" TEXT="Struktur und Kardinalität">
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1683764154161" ID="ID_1601922359" MODIFIED="1683764220217" TEXT="wie viele Fixtures gibt es?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1683809057766" ID="ID_1299037485" MODIFIED="1683809073293">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
nur eine einzige, <i>die Aktive</i>
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1683809084326" ID="ID_470102835" MODIFIED="1683809104940" TEXT="innerhalb der Fixture gibt es jedoch eine Gruppierung nach effektiver Timeline"/>
|
||||
<node CREATED="1683809110335" ID="ID_506724008" MODIFIED="1683809142582" TEXT="jedwede Änderung zieht eine partielle transaktionale Modifikation der Fixture nach sich"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1683764165757" ID="ID_793444617" MODIFIED="1683809030223" TEXT="wie viele Segmentations gibt es?">
|
||||
<linktarget COLOR="#666dd9" DESTINATION="ID_793444617" ENDARROW="Default" ENDINCLINATION="249;-20;" ID="Arrow_ID_632376357" SOURCE="ID_945659088" STARTARROW="None" STARTINCLINATION="-454;17;"/>
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1683767134444" ID="ID_666242122" MODIFIED="1683767143720" TEXT="nur eine einzige pro Timeline">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node CREATED="1683767157932" ID="ID_1466742626" MODIFIED="1683767175611" TEXT="jedes Segment bietet N Port-Nummern"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1683764191932" ID="ID_1401439878" MODIFIED="1683764220219" TEXT="was ist das Verhältnis von ModelPorts und Segmenten?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1683809160424" ID="ID_652410728" MODIFIED="1683809196086" TEXT="jeder möglicherweise unabhängig laufende Output-stream wird durch einen Port repräsentiert"/>
|
||||
<node CREATED="1683809196931" ID="ID_1982770217" MODIFIED="1683809220505" TEXT="ModelPorts entstehen also als effektives Residuum des Build-Vorganges"/>
|
||||
<node CREATED="1683809222486" ID="ID_407178268" MODIFIED="1683809261695" TEXT="ModelPorts sind jeweils noch einer Timeline (und separaten Segmentation) zugeordnet"/>
|
||||
<node CREATED="1683809266764" ID="ID_742096528" LINK="#ID_945659088" MODIFIED="1683809302469" TEXT="innerhalb einer Timeline gilt die Segmentation für alle Ports gleichermaßen"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1683762860166" ID="ID_1202392530" MODIFIED="1683762863249" TEXT="Konzepte"/>
|
||||
</node>
|
||||
<node CREATED="1680563454868" ID="ID_1187556686" MODIFIED="1680563459014" TEXT="Backbone"/>
|
||||
<node CREATED="1680563460649" ID="ID_127710483" MODIFIED="1680563474067" TEXT="MemManagement"/>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue