OutputSlot: attempt to address deeply rooted structural problems
This changeset attempts to breach into the implementation design of OutputSlot (while largely retaining the API and the »Output Slot Protocol«). While the actual problem that brought me to this point can be traced back to some rather obvious mistake, namely to conflate the `BufferProvider` used as backing implementation with a `BufferProvider` used as front-end API, creating the new connections to use an `OutputBufferProxy` unveils some further long-standing structural mismatch; notably this leads to the difficulties to get the lifecylce management of `OutputSlot` and `DataSink` under control. So I remove one entire level from the implementation, in a bold move to realign the design with the prospective usage pattern. Obviously, this breaks a lot of further code, and I need to rewire the Allocation implementation altogether, and provide a new functor based implementation for `DataSink`
This commit is contained in:
parent
0438571b73
commit
473299fb5a
14 changed files with 763 additions and 190 deletions
|
|
@ -69,14 +69,14 @@ namespace engine{
|
|||
CalcStreams
|
||||
EngineService::calculate(ModelPort mPort,
|
||||
Timings nominalTimings,
|
||||
OutputConnection& output,
|
||||
OutputSlot& outputSlot,
|
||||
Quality serviceQuality)
|
||||
{ //////////////////////////////////////////////////TICKET #1301 : prepare proper Dispatcher here, including translation ModelPort -> portIDX
|
||||
RenderEnvironment& renderConfig = configureCalculation (mPort,nominalTimings,serviceQuality);
|
||||
function<CalcStream(DataSink)> triggerRenderStart = bind (activateCalculation, _1, ref(renderConfig));
|
||||
|
||||
CalcStreams runningCalculations;
|
||||
append_all (transform (output.getOpenedSinks()
|
||||
append_all (transform (outputSlot.getOpenedSinks()
|
||||
,triggerRenderStart
|
||||
)
|
||||
,runningCalculations);
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ namespace engine{
|
|||
using mobject::ModelPort;
|
||||
using vault::out::Timings;
|
||||
|
||||
using OutputConnection = vault::out::OutputSlot::Allocation;
|
||||
using vault::out::OutputSlot;
|
||||
|
||||
|
||||
|
||||
|
|
@ -141,7 +141,7 @@ namespace engine{
|
|||
CalcStreams
|
||||
calculate(ModelPort mPort,
|
||||
Timings nominalTimings,
|
||||
OutputConnection& output,
|
||||
OutputSlot& outputSlot,
|
||||
Quality serviceQuality =QoS_DEFAULT);
|
||||
|
||||
CalcStreams
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ namespace play {
|
|||
{
|
||||
REQUIRE (outputResolver_);
|
||||
OutputSlot& slot = outputResolver_->getOutputFor (port);
|
||||
if (!slot.isFree())
|
||||
if (not slot.isActive())
|
||||
throw error::State{"unable to acquire a suitable output slot" /////////////////////TICKET #197 #816 --- could use util::_Fmt here
|
||||
, LERR_(CANT_PLAY)};
|
||||
return slot;
|
||||
|
|
@ -78,16 +78,16 @@ namespace play {
|
|||
engine::CalcStreams
|
||||
buildCalculationStreams (ModelPort port, OutputSlot& output)
|
||||
{
|
||||
OutputSlot::Allocation& activeOutputConnection = output.allocate();
|
||||
Timings nominalTimings = activeOutputConnection.timingConstraints()
|
||||
.constrainedBy(playbackTimings_);
|
||||
Timings nominalTimings = output.timingConstraints()
|
||||
.constrainedBy(playbackTimings_);
|
||||
|
||||
return activateEngine (port, nominalTimings, activeOutputConnection, renderQuality_);
|
||||
//////////////////////////////////////////TICKET #878 consider to store a copy of the OutputSlot (≙ref-couting handle) somewhere in a »PlayProcess« to keep it alive
|
||||
return activateEngine (port, nominalTimings, output, renderQuality_);
|
||||
}
|
||||
|
||||
|
||||
engine::CalcStreams
|
||||
activateEngine (ModelPort port, Timings timings, OutputSlot::Allocation& activeOutputConnection, RenderQuality quality)
|
||||
activateEngine (ModelPort port, Timings timings, OutputSlot& activeOutputConnection, RenderQuality quality)
|
||||
{
|
||||
return EngineService::instance().calculate (port, timings, activeOutputConnection, quality);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -397,15 +397,19 @@ namespace out {
|
|||
TrackingInMemoryBlockSequence const&
|
||||
accessSequence (uint channel)
|
||||
{
|
||||
#if false //////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : disabled code to disentangle BufferProvider implementation
|
||||
REQUIRE (!isFree(), "diagnostic OutputSlot not (yet) connected");
|
||||
REQUIRE (channel <= getOutputChannelCount());
|
||||
// return static_cast<TrackingInMemoryBlockSequence&> (state_->access (channel));
|
||||
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : (end) disabled code
|
||||
UNIMPLEMENTED ("the old tracking API is abandoned, the new one not yet implemented");
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
DiagnosticOutputSlot() { }
|
||||
DiagnosticOutputSlot()
|
||||
: OutputSlot(unique_ptr<Allocation>{nullptr}) //////////////////////OOO Kabooooooom!! --- should actually configure a suitable Allcation subclass here
|
||||
{ }
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -71,9 +71,9 @@ namespace out {
|
|||
/** @internal represents the \em active
|
||||
* point in each of the per-channel connections
|
||||
* used when this OutputSlot is operational.
|
||||
*
|
||||
*
|
||||
* # OutputSlot Core API
|
||||
*
|
||||
*
|
||||
* Actually, this extension point towards the implementation
|
||||
* of the actual output handling carries the core API of OutputSlot.
|
||||
* Thus, the task of actually implementing an OutputSlot boils down
|
||||
|
|
@ -127,40 +127,29 @@ namespace out {
|
|||
{
|
||||
using Connections = lib::ScopedCollection<CON>;
|
||||
using OpenedSinks = OutputSlot::OpenedSinks;
|
||||
using BufferProxy = OutputBufferProxy<AllocState>;
|
||||
|
||||
Connections connections_;
|
||||
|
||||
OutputBufferProxy<AllocState> proxyBufferProvider_;
|
||||
|
||||
BufferProxy bufferProxy_;
|
||||
|
||||
|
||||
/* == Allocation Interface == */
|
||||
|
||||
OpenedSinks
|
||||
getOpenedSinks()
|
||||
void
|
||||
release() override
|
||||
{
|
||||
//////////////////////////TICKET #878 not re-entrant, lifecycle isn't clear
|
||||
REQUIRE (this->isActive());
|
||||
return lib::iter_source::transform (eachElm(connections_), connectOutputSink);
|
||||
TODO ("propagate closing of output");
|
||||
}
|
||||
|
||||
Timings
|
||||
timingConstraints()
|
||||
{
|
||||
UNIMPLEMENTED ("find out about timing constraints"); //////////////////////////TICKET #831
|
||||
getTimings() override
|
||||
{ //////////////////TODO somehow configure the timings into this implementation object
|
||||
UNIMPLEMENTED ("a lot regarding the Timings is still not clear..."); //////////////////////////TICKET #831
|
||||
}
|
||||
|
||||
bool
|
||||
isActive() const
|
||||
{
|
||||
return 0 < connections_.size();
|
||||
}
|
||||
|
||||
CON&
|
||||
access (uint chanNr) const
|
||||
{
|
||||
return connections_[chanNr];
|
||||
}
|
||||
/* == Callback API for BufferProxy == */
|
||||
|
||||
|
||||
|
||||
protected: /* == API for OutputSlot-Impl == */
|
||||
|
|
@ -176,7 +165,7 @@ namespace out {
|
|||
template<class CTOR>
|
||||
AllocState(uint numChannels, CTOR&& populator)
|
||||
: connections_(numChannels, std::forward<CTOR>(populator))
|
||||
, proxyBufferProvider_{*this}
|
||||
, bufferProxy_{*this}
|
||||
{ }
|
||||
|
||||
|
||||
|
|
@ -187,9 +176,9 @@ namespace out {
|
|||
{
|
||||
TRACE (test, "activating Con=%p", &connection );
|
||||
|
||||
DataSink newSink;
|
||||
newSink.activate(&connection, shutdownConnection);
|
||||
return newSink;
|
||||
// DataSink newSink;
|
||||
// newSink.activate(&connection, shutdownConnection);
|
||||
// return newSink;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -34,68 +34,61 @@ namespace out {
|
|||
|
||||
|
||||
|
||||
OutputSlot::~OutputSlot() { } // emit VTables here....
|
||||
|
||||
// emit VTables here....
|
||||
OutputSlot::Allocation::~Allocation() { }
|
||||
|
||||
OutputSlot::Connection::~Connection() { }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** whether this output slot is occupied
|
||||
* @return true if currently unconnected and
|
||||
* able to connect and handle output data
|
||||
/**
|
||||
* @internal setup of the OutputSlot and the PImpl (Allocation) for active connected state.
|
||||
* Some wiring must be carried out here, so that the ref-count based lifecycle management
|
||||
* works as desired. All customisation for some specific kind of output mechanism and
|
||||
* the corresponding OutputSlot::Connection implementation is embedded into the actual
|
||||
* type of the PImpl, i.e. the Allocation subclass passed in as argument. The OutputSlot,
|
||||
* together with the DataSink handles, will take shared ownership of the connection setup.
|
||||
*/
|
||||
bool
|
||||
OutputSlot::isFree() const
|
||||
shared_ptr<OutputSlot::Allocation>
|
||||
OutputSlot::connect (unique_ptr<Allocation> allocation)
|
||||
{
|
||||
return not this->state_;
|
||||
REQUIRE (allocation);
|
||||
return {allocation.release()
|
||||
,[](Allocation* allo) {// disconnection call-back
|
||||
REQUIRE(allo);
|
||||
allo->release();
|
||||
delete allo;
|
||||
}};
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** claim this OutputSlot for active use as output sink(s).
|
||||
* At any point, a given slot can only be used for a single
|
||||
* ongoing output process (which may serve several channels though).
|
||||
* The assumption is for the OutputSlot to be picked through a query
|
||||
* to some OutputManater, so the parameters (resolution, sample rate...)
|
||||
* should be suited for the intended use. Thus no additional configuration
|
||||
* is necessary.
|
||||
* @return Allocation representing the "connected state" from the client's POV.
|
||||
* The client may retrieve the effectively required Timings from there,
|
||||
* as well as the actual output sinks, ready for use.
|
||||
* @remarks calls back into #buildState, where the concrete OutputSlot
|
||||
* is expected to provide a private Connection implementation,
|
||||
* subclassing OutputSlot::Allocation
|
||||
/**
|
||||
* Entrance point: retrieve a sequence of actual DataSink handles, one for each data feed.
|
||||
* Typically, these _sink handles_ will be propagated to some calculation stream and further
|
||||
* embedded into render job definitions, so that the render invocation can use the sink handle
|
||||
* to get a buffer for each frame.
|
||||
* @return an iterator that produces DataSink objects; these are ref-counting handles
|
||||
* and also functor objects with the signature `BuffHandle(FrameID)`, where the
|
||||
* FrameID is defined in relation to the _frame grid_ defined by the Timings.
|
||||
*/
|
||||
OutputSlot::Allocation&
|
||||
OutputSlot::allocate()
|
||||
OutputSlot::OpenedSinks
|
||||
OutputSlot::getOpenedSinks()
|
||||
{
|
||||
if (not isFree())
|
||||
throw err::Logic ("Attempt to open/allocate an OutputSlot already in use.");
|
||||
|
||||
state_ = this->buildState();
|
||||
return *state_;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
OutputSlot::disconnect()
|
||||
Timings
|
||||
OutputSlot::timingConstraints()
|
||||
{
|
||||
if (not isFree())
|
||||
state_.reset(0);
|
||||
REQUIRE(alloc_);
|
||||
return alloc_->getTimings();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* === DataSink frontend === */
|
||||
|
||||
BuffHandle
|
||||
DataSink::lockBufferFor(FrameID frameNr)
|
||||
{
|
||||
return impl().claimBufferFor(frameNr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -21,33 +21,44 @@
|
|||
**
|
||||
** Each OutputSlot is an unique and distinguishable entity. It corresponds explicitly to an
|
||||
** external output, or a group of such outputs (e.g. left and right sound card output channels),
|
||||
** or an output file or similar capability accepting media content. Initially, an output slot
|
||||
** needs to be provided, configured and registered, using an implementation suitable for the
|
||||
** kind of media data to be sent (sound, video) and also suitable for the special circumstances
|
||||
** of the output capability (render a file, display video in a GUI widget, send video to some
|
||||
** full screen display, establish a Jack port, just use some kind of "sound out"). An output
|
||||
** slot is always limited to a single kind of media, and to a single connection unit, but
|
||||
** this connection may still be comprised of multiple channels
|
||||
** (e.g. stereoscopic video, multichannel sound).
|
||||
** or an output file or similar capability accepting media content. The setup for an OutputSlot
|
||||
** is provided, configured and registered with an OutputManager, using an implementation suitable
|
||||
** for the kind of media data to be sent (sound, video) and also suitable for the desired kind if
|
||||
** output capability (render to file, display video in a GUI widget, send video to a full screen
|
||||
** display, establish a Jack port or use any kind of "sound out"). Thus it is always limited to
|
||||
** a single kind of media, and to a single connection unit, but this connection may still comprise
|
||||
** several data feeds (e.g. stereoscopic video, multichannel sound). The number of such feeds
|
||||
** and the expected data format depends on the _media stream type_ used for configuring or
|
||||
** retrieving this OutputSlot. For example, a stereo sound output may expect only a single
|
||||
** data feed, where data blocks for both channels are sent in interleaved format.
|
||||
**
|
||||
** In order to be usable as output sink, an output slot needs to be \em allocated: At any time,
|
||||
** there may be only a single client using a given output slot this way. To stress this point:
|
||||
** output slots don't provide any kind of inherent mixing capability; any adaptation, mixing,
|
||||
** overlaying and sharing needs to be done within the nodes network producing the output data
|
||||
** to be fed into the slot. (in special cases, some external output capabilities -- e.g. the
|
||||
** Jack audio connection system -- may still provide additional mixing capabilities,
|
||||
** but that's beyond the scope of the Lumiera application)
|
||||
** Once the client retrieves some OutputSlot, it was _allocated_ for exclusive use for that client;
|
||||
** At any time, there may be only a single client using a given output capability this way. It should
|
||||
** be noted thus that output slots don't provide any kind of inherent mixing capability; any adaptation,
|
||||
** mixing, overlaying and sharing needs to be done within the Render Node Network that produces the
|
||||
** data to be output. (As an aside, _some_ external output frameworks — e.g. the Jack audio connection
|
||||
** system — may still provide additional mixing capabilities, yet these are beyond the scope of the
|
||||
** Lumiera application)
|
||||
**
|
||||
** The OutputSlot object is a (copyable) front-end handle, that should be stored by the client and
|
||||
** discarded when further output is no longer required. From the OutputSlot, a set of actual DataSink
|
||||
** handles can be retrieved (one for each possible data feed). Starting from these handles, a two-phase
|
||||
** output protocol can be executed for each frame of data to send to the output. This includes obtaining
|
||||
** a BuffHandle, similar to what the BufferProvider exposes. The suitability of the buffer and the data
|
||||
** format is not validated in any way at that level, since the setup works under the assumption that
|
||||
** the stream type and further metadata has been validated or configured suitably at a higher level.
|
||||
** However, the OutputSlot exposes a definition of _timing constraints_ to describe when data must
|
||||
** be provided, and what deadline to observe for each frame. The client is required to comply to these
|
||||
** vault::out::Timings both when acquiring the BuffHandle for some frame and when _emitting_ data --
|
||||
** any use outside these limits will cause that frame to be treated as a glitch. Furthermore,
|
||||
** the client is required to invoke BuffHandle::release() as soon as no further access to
|
||||
** the buffer is required (and after invoking `emit()`). Failure to do so will cause
|
||||
** a blocked buffer and typically leads to abort of the output and play process.
|
||||
** However, individual frames that miss the deadline are handled gracefully;
|
||||
** the actual implementation is expected to provide some kind of de-click
|
||||
** or de-flicker facility, which kicks in automatically whenever
|
||||
** a timing failure is detected.
|
||||
**
|
||||
** Once allocated, the output slot returns a set of concrete sink handles (one for each
|
||||
** physical channel expecting data). The calculating process feeds its results into those handles.
|
||||
** Size and other characteristics of the data frames are assumed to be suitable, which typically
|
||||
** won't be verified at that level anymore. Besides that, the allocation of an output slot reveals
|
||||
** detailed timing expectations. The client is required to comply to these timings when _emitting_
|
||||
** data -- they are even required to provide a current time specification, alongside with the data.
|
||||
** Based on this information, the output slot has the ability to handle timing failures gracefully;
|
||||
** the concrete output slot implementation is expected to provide some kind of de-click or
|
||||
** de-flicker facility, which kicks in automatically when a timing failure is detected.
|
||||
**
|
||||
** @see OutputSlotProtocol_test
|
||||
** @see diagnostic-output-slot.hpp
|
||||
*/
|
||||
|
|
@ -66,6 +77,7 @@
|
|||
#include "lib/util.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
|
||||
|
||||
namespace vault {
|
||||
|
|
@ -73,101 +85,114 @@ namespace out {
|
|||
|
||||
using vault::mem::BuffHandle;
|
||||
using lib::time::FrameCnt;
|
||||
using std::shared_ptr;
|
||||
using std::unique_ptr;
|
||||
|
||||
|
||||
|
||||
class DataSink;
|
||||
|
||||
using FrameID = FrameCnt;
|
||||
|
||||
|
||||
/**
|
||||
* Handle to represent an opened connection ready to receive media data for output.
|
||||
* Each DataSink (handle) corresponds to an OutputSlot::Connection entry. Data is
|
||||
* published frame wise in a two-phase protocol: in the first stage, the client
|
||||
* gets exclusive access to an output buffer. Once the data is ready for output,
|
||||
* the client signals `emit()` and the buffer enters the second stage, where the
|
||||
* intern output mechanism of that specific connection gets exclusive access.
|
||||
*
|
||||
* The DataSink handle is a _functor_ and can be invoked with a frame number,
|
||||
* to start such a two-phase transaction for _this specific frame._ The result
|
||||
* is a BuffHandle, to be used in the usual way as with a BufferProvider:
|
||||
* - the client can access the buffer memory, either raw or with a forced cast
|
||||
* - the client invokes BuffHandle::emit() to indicate that data is ready for output
|
||||
* - once the client is done with that handle, it **must** invoke BuffHandle::release()
|
||||
* Each output mechanism defines specific constraints regarding the time window when
|
||||
* to get such a BuffHandle and when `emit()` must have been called. These constraints
|
||||
* are indicated by the vault::out::Timings, that can be retrieved from the OutputSlot.
|
||||
*
|
||||
* @note DataSink embeds a ref-counting handle to detect automatically when some
|
||||
* connection can be released; the _allocation of an OutputSlot_ is released
|
||||
* once all connections were discarded.
|
||||
*/
|
||||
class DataSink
|
||||
: public std::function<BuffHandle(FrameID)>
|
||||
{ };
|
||||
|
||||
|
||||
|
||||
/****************************************************************************//**
|
||||
* Interface: Generic output sink.
|
||||
* An OutputSlot represents the possibility to send data through multiple
|
||||
* channels to some kind of external sink (video in GUI window, video full screen,
|
||||
* sound, Jack, rendering to file). Clients are expected to retrieve a suitably
|
||||
* preconfigured implementation from some OutputManager instance. An OutputSlot
|
||||
* needs to be _claimed_ for output by invoking #allocate, which returns a
|
||||
* representation of the connection state. This operation is exclusive.
|
||||
* The actual [output sinks](\ref DataSink) can be retrieved
|
||||
* through the Allocation object returned from there.
|
||||
* preconfigured instance from some OutputManager. At that point, the given
|
||||
* OutputSlot is already activated and reserved for exclusive use for the client.
|
||||
* The further lifecycle is managed by ref-count, which implies that OutputSlot
|
||||
* is a (copyable) front-end handle. For the actual output, the client has to
|
||||
* [retrieve the DataSink handles](\ref getOpenedSinks()), one for each independent
|
||||
* data feed associated with this OutputSlot. How many feeds this are, depends on
|
||||
* the _media stream type_ for which this OutputSlot was configured. The retrieved
|
||||
* DataSink handles also participate in the ref-count based connection state; once
|
||||
* the OutputSlot and all DataSink handles are discarded, the output connection
|
||||
* and all associated resources are released.
|
||||
* @see DataSink for the next steps to perform on the handles for output
|
||||
* in compliance with the »Output Slot protocol«.
|
||||
*/
|
||||
class OutputSlot
|
||||
: util::NonCopyable
|
||||
{
|
||||
|
||||
public:
|
||||
virtual ~OutputSlot();
|
||||
|
||||
using OpenedSinks = lib::IterSource<DataSink>::iterator;
|
||||
|
||||
class Allocation
|
||||
OpenedSinks getOpenedSinks();
|
||||
Timings timingConstraints();
|
||||
|
||||
/** is this OutputSlot allocated/activated? */
|
||||
bool
|
||||
isActive() const
|
||||
{
|
||||
public:
|
||||
virtual OpenedSinks getOpenedSinks() =0;
|
||||
virtual Timings timingConstraints() =0;
|
||||
|
||||
virtual bool isActive() const =0;
|
||||
|
||||
~Allocation(); ///< this is an interface
|
||||
};
|
||||
|
||||
|
||||
/** can this OutputSlot be allocated? */
|
||||
bool isFree() const;
|
||||
|
||||
/** claim this slot for exclusive use */
|
||||
Allocation& allocate();
|
||||
|
||||
/** disconnect from this OutputSlot
|
||||
* @warning may block until DataSinks are gone */
|
||||
void disconnect();
|
||||
return bool(alloc_);
|
||||
}
|
||||
|
||||
/** established output feed */
|
||||
class Connection;
|
||||
|
||||
|
||||
protected:
|
||||
/** @internal interface for the allocated state */
|
||||
class Allocation
|
||||
{
|
||||
public:
|
||||
virtual ~Allocation(); ///< this is an interface
|
||||
|
||||
virtual void release() =0;
|
||||
virtual Timings getTimings() =0;
|
||||
};
|
||||
|
||||
/** active connections through this OutputSlot */
|
||||
template<class CON>
|
||||
class AllocState;
|
||||
|
||||
unique_ptr<Allocation> state_;
|
||||
shared_ptr<Allocation> alloc_;
|
||||
|
||||
/** build the _connected state,_
|
||||
* based on the existing configuration
|
||||
* within this concrete OutputSlot */
|
||||
virtual unique_ptr<Allocation> buildState() =0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* denotes an opened connection ready to receive media data for output.
|
||||
* Each DataSink (handle) corresponds to an OutputSlot::Connection entry.
|
||||
* Data is handed over frame wise in a two-phase protocol: first, the client
|
||||
* gets exclusive access to an output buffer, and then, when done, the buffer
|
||||
* is handed over by an #emit call.
|
||||
*/
|
||||
class DataSink
|
||||
: public lib::Handle<OutputSlot::Connection>
|
||||
{
|
||||
shared_ptr<Allocation>
|
||||
connect (unique_ptr<Allocation>);
|
||||
|
||||
public:
|
||||
BuffHandle lockBufferFor(FrameID);
|
||||
/** by default marked as inactive/defunct */
|
||||
OutputSlot() = default;
|
||||
|
||||
/**
|
||||
* Build an OutputSlot that is in _connected state_.
|
||||
* @param allocation fully configured for a specific kind of Connection.
|
||||
*/
|
||||
OutputSlot (unique_ptr<Allocation> allocation)
|
||||
: alloc_{connect (move(allocation))}
|
||||
{ }
|
||||
|
||||
friend bool operator== (DataSink const& sink1, DataSink const& sink2)
|
||||
{
|
||||
return not (sink1 and sink2)
|
||||
or (sink1 and sink2
|
||||
and util::isSameObject (sink1.impl(), sink2.impl()));
|
||||
}
|
||||
// standard copy operations acceptable
|
||||
};
|
||||
|
||||
|
||||
|
||||
}} // namespace vault::out
|
||||
#endif /*VAULT_OUT_OUTPUT_SLOT_H*/
|
||||
|
|
|
|||
|
|
@ -47,8 +47,7 @@ namespace test {
|
|||
using vault::out::Timings;
|
||||
using lib::time::FrameRate;
|
||||
|
||||
typedef asset::ID<Pipe> PID;
|
||||
typedef OutputSlot::Allocation Allocation;
|
||||
using PID = asset::ID<Pipe>;
|
||||
|
||||
|
||||
namespace { // test fixture...
|
||||
|
|
@ -89,11 +88,10 @@ namespace test {
|
|||
ModelPort port(pipe);
|
||||
|
||||
DiagnosticOutputSlot oSlot;
|
||||
Allocation& output = oSlot.allocate();
|
||||
Timings timings (FrameRate::PAL); /////////TODO
|
||||
|
||||
// Invoke test subject...
|
||||
CalcStreams calc = engine.calculate(port, timings, output);
|
||||
CalcStreams calc = engine.calculate(port, timings, oSlot);
|
||||
|
||||
////TODO some direct checks on the calculation stream??
|
||||
|
||||
|
|
|
|||
|
|
@ -389,13 +389,21 @@ namespace test {
|
|||
auto [port0,sink0] = dispatcher.getDummyConnection(0);
|
||||
auto [port1,sink1] = dispatcher.getDummyConnection(1);
|
||||
CHECK (port0 != port1);
|
||||
UNIMPLEMENTED ("Identity of a DataSink");
|
||||
#if false //////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : disabled code to allow refactoring of OutputSlot
|
||||
CHECK (sink0 != sink1);
|
||||
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : (end) disabled code
|
||||
CHECK (port0.isValid());
|
||||
CHECK (port1.isValid());
|
||||
#if false //////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : disabled code to allow refactoring of OutputSlot
|
||||
/////////////////////////OOO seemingly this is no longer possible (and unnecessary), since DataSink participates in the ref-count now
|
||||
CHECK (sink0.isValid());
|
||||
CHECK (sink1.isValid());
|
||||
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : (end) disabled code
|
||||
CHECK (not ModelPort().isValid());
|
||||
#if false //////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : disabled code to allow refactoring of OutputSlot
|
||||
CHECK (not DataSink().isValid());
|
||||
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : (end) disabled code
|
||||
|
||||
CHECK (0 == dispatcher.resolveModelPort(port0));
|
||||
CHECK (1 == dispatcher.resolveModelPort(port1));
|
||||
|
|
|
|||
|
|
@ -27,7 +27,16 @@
|
|||
** - a set of ModelPort elements
|
||||
** - a set of DataSink handles, as if an actual playback connection has been established
|
||||
** @todo 5/2023 add more elements as needed for test driven integration of Player and engine
|
||||
** @todo this was invented in 2012 -- but development of the player subsystem stalled thereafter.
|
||||
** @todo this was invented in 2012 -- as an act of desperation, since everything to build upon
|
||||
** seemed to evade my grip. My hope at that time was so somehow _bootstrap_ an explorative
|
||||
** design in order to get away from that top-down reasoning, that seemed to lead nowhere.
|
||||
** However, work on the player had to be postponed to care for the GUI first; meanwhile
|
||||
** I follow a similar idea, relying on »vertical integration slices«
|
||||
** @deprecated 3/2026 not sure if we need this henceforth...
|
||||
** It might be useful though in case we consider to build some kind of
|
||||
** _component integration test_ -- yet for this to work, we'd need
|
||||
** - a fake calculation
|
||||
** - a fake OutputSlot
|
||||
**
|
||||
** @see mock-dispatcher.hpp
|
||||
** @see JobPlanningPipeline_test
|
||||
|
|
@ -66,7 +75,7 @@ namespace test {
|
|||
|
||||
/**
|
||||
* @todo 5/2023 quick-n-dirty placeholder to be able to fabricate fake DataSink handles (`Handle<Connection>`)
|
||||
*/
|
||||
*/ /////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : after the refactoring of OutputSlot 3/2026 it is not that easy any more. We need a Fake OutputSlot
|
||||
class UnimplementedConnection
|
||||
: public vault::out::OutputSlot::Connection
|
||||
{
|
||||
|
|
@ -166,8 +175,11 @@ namespace test {
|
|||
modelPorts_.push_back (ModelPort(pipeB));
|
||||
|
||||
// prepare corresponding placeholder DataSink (a fake active output connection)
|
||||
UNIMPLEMENTED ("need mock/fake OutputSlot");
|
||||
#if false //////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : disabled code to disentangle BufferProvider implementation
|
||||
dataSinks_.emplace_back().activate (std::make_shared<UnimplementedConnection>());
|
||||
dataSinks_.emplace_back().activate (std::make_shared<UnimplementedConnection>());
|
||||
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : (end) disabled code
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,11 @@
|
|||
** @todo this was invented in 2012 -- but development of the player subsystem stalled thereafter.
|
||||
** As of 2016, I still consider this design valid and intend to pick up development when
|
||||
** able to address this topic again. At the moment, the UI-Session connection is more urgent.
|
||||
** @deprecated 3/2026 the idea as such is valid, but I doubt it can be implemented this way
|
||||
** without creating a massive amount of fake implementation for the sole purpose of
|
||||
** demonstrating the component integration. On the other hand, it might be worthwhile
|
||||
** to build a complete framework for dummy data so that a running render engine
|
||||
** can be demonstrated at integration test level.
|
||||
**
|
||||
** @see stage::PlaybackController usage exampleS
|
||||
*/
|
||||
|
|
@ -128,7 +133,7 @@ namespace test {
|
|||
|
||||
/** search through all port <-> sink connections
|
||||
* supported by this DummyPlayConnection
|
||||
* @return `true` if found both a math on port an sink.
|
||||
* @return `true` if found both a match on port an sink.
|
||||
*/
|
||||
bool
|
||||
isSupported (ModelPort port, DataSink sink)
|
||||
|
|
@ -138,8 +143,11 @@ namespace test {
|
|||
if (port == *it)
|
||||
{
|
||||
auto [refPort, refSink] = getModelPort(i);
|
||||
UNIMPLEMENTED ("need a fake OutputSlot and need to place some Stream-ID into the data sink");
|
||||
#if false //////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : disabled code to allow refactoring of the OutputSlot default implementation
|
||||
if (refSink == sink)
|
||||
return true;
|
||||
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : (end) disabled code
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,28 +58,27 @@ namespace test {
|
|||
// and then registered with / retrieved from an OutputManager
|
||||
DiagnosticOutputSlot oSlot;
|
||||
|
||||
// Client claims the OutputSlot
|
||||
// and opens it for exclusive use.
|
||||
OutputSlot::Allocation& alloc = oSlot.allocate();
|
||||
// Note: an OutputSlot is automatically activated / allocated
|
||||
// for exclusive use by this client.
|
||||
|
||||
// Now the client is able to prepare
|
||||
// "calculation streams" for the individual
|
||||
// Channels to be output through this slot.
|
||||
OutputSlot::OpenedSinks sinks = alloc.getOpenedSinks();
|
||||
OutputSlot::OpenedSinks sinks = oSlot.getOpenedSinks();
|
||||
DataSink sink0 = *sinks;
|
||||
DataSink sink1 = *++sinks;
|
||||
|
||||
// within the frame-calculation "loop"
|
||||
// we perform a data exchange cycle
|
||||
FrameCnt frameNr = 123;
|
||||
BuffHandle buff00 = sink0.lockBufferFor (frameNr);
|
||||
BuffHandle buff10 = sink1.lockBufferFor (frameNr);
|
||||
BuffHandle buff00 = sink0(frameNr);
|
||||
BuffHandle buff10 = sink1(frameNr);
|
||||
|
||||
// rendering process calculates content....
|
||||
buff00.accessAs<TestFrame>() = testData(0,0);
|
||||
|
||||
// while further frames might be processed in parallel
|
||||
BuffHandle buff11 = sink1.lockBufferFor (frameNr+1);
|
||||
BuffHandle buff11 = sink1(frameNr+1);
|
||||
buff11.accessAs<TestFrame>() = testData(1,1);
|
||||
buff10.accessAs<TestFrame>() = testData(1,0);
|
||||
|
||||
|
|
|
|||
|
|
@ -5214,7 +5214,7 @@ Thus there are two serious problem situations
|
|||
&rarr; OutputSlotImpl
|
||||
</pre>
|
||||
</div>
|
||||
<div title="OutputSlotDesign" modifier="Ichthyostega" created="201112190322" modified="202603190010" tags="design decision" changecount="7">
|
||||
<div title="OutputSlotDesign" modifier="Ichthyostega" created="201112190322" modified="202603202151" tags="design decision" changecount="8">
|
||||
<pre>The OutputSlot interface describes a point where generated media data can actually be sent to the external world. It is expected to be implemented by adapters and bridges to existing drivers or external interface libraries, like a viewer widget in the GUI, ALSA or Jack sound output, rendering to file, using an external media format library. The design of this core facility was rather difficult and stretched out over quite some time span -- this page documents the considerations and the decisions taken.
|
||||
|
||||
!intention
|
||||
|
|
@ -5291,6 +5291,12 @@ So the problem is that BufferProvider is conceived as a central service facility
|
|||
* an actual output buffer, provided by the {{{Connection}}} back-end, is registered with the metadata and represented as BuffHandle
|
||||
* calls on that BuffHandle will invoke the {{{BufferStore}}} API and must be delegated to the corresponding {{{Connection}}}.
|
||||
Taken together, this implies that the {{{OutputSlot::AllocState<CON>}}} turns into a delegation hub. It has to maintain the active connections and can thus be used to back a custom made {{{BufferStore}}} implementation, using the information embedded into the {{{LocalTag}}} to select the proper {{{Connection}}} for delegation -- which provides the actual implementation of all buffer management and state handling for the specific output mechanism.
|
||||
|
||||
-----
|
||||
!!! Establish a proper Lifecycle
|
||||
While the original design for OutputSlot seems //elegant, on a theoretical level,// the implementation was constantly plagued with complexities related to the lifecycle. Some relevant aspects could not be settled at all -- which was not noticed until the recent attempts to integrate the OutputSlot into the (likewise reworked) Render Engine implementation. A turning point in all this evolution of design is to remove the //state abstraction// -- in favour of representing the progression of state directly as a sequence of context data frames. The deeper change, which motivated this shift, was to abandon the idea of a single, global, overarching and final scheme of »Rendering«. It is acknowledged rather that the actual rendering for some unspecified »rendering« will be done by an external library -- and each such library establishes its own terminology, processing scheme and conventions, which finally are rooted in some specific ''Domain Onotology''. The Lumiera Render Engine is now understood as a connected graph of //adaptors//, organised around some minimal common denominator, like the fact that data frames are calculated, and that each such frame can be addressed by a media type and a point in time.
|
||||
|
||||
In line with this shift in focus, the OutputSlot is seen as yet another element of representational state: it is a token to embody an allocated output connection. This implies to unify the notion of the {{{OutputSlot}}} with the {{{Allocation}}}, and turn both into a handle passed to the client process. All aspects of lifecycle can be managed automatically with such ref-counting handles. This has some cost in terms of performance (thread contention when accessing the atomic ref count), but that is deemed acceptable, since output is handled on a rather slow time scale, like producing a data frame every 10 milliseconds. The specific output mechanism remains »allocated« thus as long as some element of the client processing still holds onto any such handle, either the {{{OutputSlot}}} or some {{{DataSink}}}. The latter is reduced into a //named function//, which however also embeds a shared handle to the common allocation state. With this rearrangement in the design, there is now a cohesive domain of connection management, while the actual, technical connection is separated out and packaged behind the {{{Connection}}} interface.
|
||||
</pre>
|
||||
</div>
|
||||
<div title="OutputSlotImpl" modifier="Ichthyostega" created="201107102343" modified="201109232235" tags="spec operational">
|
||||
|
|
|
|||
|
|
@ -83808,7 +83808,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1685050903817" ID="ID_947140645" MODIFIED="1714778184561" TEXT="konkrete Data-Sink">
|
||||
<linktarget COLOR="#a95a75" DESTINATION="ID_947140645" ENDARROW="Default" ENDINCLINATION="-637;77;" ID="Arrow_ID_686370160" SOURCE="ID_1575034395" STARTARROW="None" STARTINCLINATION="747;-40;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1685058050639" ID="ID_143173446" MODIFIED="1685058108822" TEXT="Sink ist ein Handle (ref-counting)">
|
||||
<node CREATED="1685058050639" ID="ID_143173446" MODIFIED="1773940668348" TEXT="Sink ist ein Handle (ref-counting)">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
|
|
@ -83817,6 +83817,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<arrowlink COLOR="#5a6a7d" DESTINATION="ID_1007087496" ENDARROW="Default" ENDINCLINATION="1062;0;" ID="Arrow_ID_358885146" STARTARROW="None" STARTINCLINATION="687;54;"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1685062340977" ID="ID_1162744930" MODIFIED="1714776491235" TEXT="diese Info braucht der JobFunktor">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
|
|
@ -84485,7 +84486,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1685802725228" ID="ID_848236204" MODIFIED="1685802740418" TEXT="Parameter-Paket">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1685802741818" ID="ID_87044302" MODIFIED="1685803707711" TEXT="DataSink(Handle)">
|
||||
<linktarget COLOR="#4b3ea5" DESTINATION="ID_87044302" ENDARROW="Default" ENDINCLINATION="248;-35;" ID="Arrow_ID_594271482" SOURCE="ID_953619048" STARTARROW="None" STARTINCLINATION="669;36;"/>
|
||||
<linktarget COLOR="#4b3ea5" DESTINATION="ID_87044302" ENDARROW="Default" ENDINCLINATION="1839;-50;" ID="Arrow_ID_594271482" SOURCE="ID_953619048" STARTARROW="None" STARTINCLINATION="669;36;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1685986803653" ID="ID_666925478" MODIFIED="1686498849033" TEXT="Exit-Node(Referenz)">
|
||||
|
|
@ -85389,7 +85390,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1714581244537" ID="ID_1987838291" MODIFIED="1714581558881" TEXT="tatsächlich ist die InvocationInstanceID redundant">
|
||||
<node CREATED="1714581244537" ID="ID_1987838291" MODIFIED="1773941777860" TEXT="tatsächlich ist die InvocationInstanceID redundant">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
|
|
@ -85398,6 +85399,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<arrowlink COLOR="#a35e64" DESTINATION="ID_1047888380" ENDARROW="Default" ENDINCLINATION="807;-31;" ID="Arrow_ID_1643361924" STARTARROW="None" STARTINCLINATION="861;0;"/>
|
||||
</node>
|
||||
<node CREATED="1714581651294" ID="ID_1318663500" MODIFIED="1714581669752" TEXT="⟹ es ist sogar noch etwas »Luft«">
|
||||
<node CREATED="1714581688960" ID="ID_554965848" MODIFIED="1714581707552" TEXT="oder man kommt mit einem Feed-Token (statt mit zwei) aus"/>
|
||||
|
|
@ -111079,7 +111081,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1685987007275" ID="ID_953619048" MODIFIED="1685987465547" TEXT="daher per Pointer auf den Calc-Stream verweisen">
|
||||
<arrowlink COLOR="#4b3ea5" DESTINATION="ID_87044302" ENDARROW="Default" ENDINCLINATION="248;-35;" ID="Arrow_ID_594271482" STARTARROW="None" STARTINCLINATION="669;36;"/>
|
||||
<arrowlink COLOR="#4b3ea5" DESTINATION="ID_87044302" ENDARROW="Default" ENDINCLINATION="1839;-50;" ID="Arrow_ID_594271482" STARTARROW="None" STARTINCLINATION="669;36;"/>
|
||||
<arrowlink COLOR="#4b3ea5" DESTINATION="ID_1078372838" ENDARROW="Default" ENDINCLINATION="416;-39;" ID="Arrow_ID_209843242" STARTARROW="None" STARTINCLINATION="669;36;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
|
|
@ -111128,6 +111130,26 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
</html></richcontent>
|
||||
<icon BUILTIN="hourglass"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1686872616987" ID="ID_774940151" MODIFIED="1773958152739" TEXT="latent gefährlich — Entwurf noch nicht abgeschlossen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<ul>
|
||||
<li>
|
||||
Werden DataSink über Threadgrenzen hinweg propagiert?
|
||||
</li>
|
||||
<li>
|
||||
muß irgendwo eine automatische Instanzverwaltung angehängt werden? (⟶ ref-counting)
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<linktarget COLOR="#ff1125" DESTINATION="ID_774940151" ENDARROW="Default" ENDINCLINATION="681;34;" ID="Arrow_ID_1530530196" SOURCE="ID_795422547" STARTARROW="None" STARTINCLINATION="1318;69;"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#b20d41" CREATED="1773942956748" HGAP="63" ID="ID_1326409567" MODIFIED="1773942989402" TEXT="Lebenszyklus macht mir Sorge" VSHIFT="1">
|
||||
<icon BUILTIN="smiley-neutral"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1711548381477" ID="ID_664146362" MODIFIED="1769124792851" TEXT="Buffer-Manager">
|
||||
<linktarget COLOR="#5a4f77" DESTINATION="ID_664146362" ENDARROW="Default" ENDINCLINATION="-493;1406;" ID="Arrow_ID_297212964" SOURCE="ID_1433806835" STARTARROW="None" STARTINCLINATION="-1768;-2925;"/>
|
||||
|
|
@ -118951,7 +118973,8 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
<node CREATED="1512923592590" ID="ID_540019681" MODIFIED="1557498707237" TEXT="Engine">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1679783052390" ID="ID_1851394144" MODIFIED="1684869799933" TEXT="gründen">
|
||||
<icon BUILTIN="stop"/>
|
||||
<node CREATED="1680563559852" ID="ID_580288207" MODIFIED="1680563577773" TEXT="plainPlay">
|
||||
<node CREATED="1680563559852" ID="ID_580288207" MODIFIED="1773944316424" TEXT="plainPlay">
|
||||
<linktarget COLOR="#523364" DESTINATION="ID_580288207" ENDARROW="Default" ENDINCLINATION="-1850;513;" ID="Arrow_ID_420590547" SOURCE="ID_1057786773" STARTARROW="None" STARTINCLINATION="-3285;-3404;"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1681086194343" ID="ID_1293419166" MODIFIED="1681086200999" TEXT="gemeinsame Datenstrukturen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1681086202821" ID="ID_274575596" MODIFIED="1681425341555" TEXT="Job">
|
||||
|
|
@ -118973,6 +118996,85 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f9f3e3" COLOR="#a50125" CREATED="1773959558830" ID="ID_1973724646" MODIFIED="1773963271195" TEXT="Achtung: ursprüngliches Konzept »Job« löst sich auf">
|
||||
<linktarget COLOR="#fd2e1b" DESTINATION="ID_1973724646" ENDARROW="Default" ENDINCLINATION="-1379;72;" ID="Arrow_ID_862194975" SOURCE="ID_1593586171" STARTARROW="None" STARTINCLINATION="1316;57;"/>
|
||||
<linktarget COLOR="#fe6c6c" DESTINATION="ID_1973724646" ENDARROW="Default" ENDINCLINATION="-1379;72;" ID="Arrow_ID_663742943" SOURCE="ID_589497720" STARTARROW="None" STARTINCLINATION="-974;63;"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1773959604840" ID="ID_1430634387" MODIFIED="1773959706305" TEXT="notiere diese Beobachtung im Rückblick 2026 (nach einiger Verwirrung)">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
oh (Her)Mann!
|
||||
</p>
|
||||
<p>
|
||||
Damals, 2023 dachte ich, ich kann das in einem Ansturm alles »wuppen«. Inzwischen hab ich ¾ meiner sehr guten Einsichten schon wieder vergessen, und sitze nur auf den alten Vorstellungen, die sich irgendwie ins Hirn eingegraben haben
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fefc4e" COLOR="#351d75" CREATED="1773959710895" ID="ID_8416678" LINK="https://issues.lumiera.org/ticket/1295#comment:4" MODIFIED="1773959856511" TEXT="siehe Hinweis in: #1295 new todo draft job invocation parameter representation">
|
||||
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1773959885626" ID="ID_98265372" MODIFIED="1773959897523" TEXT="anfangs dachten wir, der Scheduler würde Jobs managen"/>
|
||||
<node CREATED="1773959901312" ID="ID_627540736" MODIFIED="1773959917098" TEXT="indem ich in die Analyse / Konstruktion des Schedulers eingestiegen bin..."/>
|
||||
<node CREATED="1773959917902" ID="ID_616732684" MODIFIED="1773959954543" TEXT="habe ich dieses Konzept komplett umgekrempelt">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
..wie üblich, ich setze auf symbolische Repräsentation von Sprach-artigen Konzepten
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1773959968927" ID="ID_539680342" MODIFIED="1773959980852" TEXT="der Scheduler verarbeitet nun Acticity-Terme"/>
|
||||
<node CREATED="1773960226836" ID="ID_97033416" MODIFIED="1773960254265">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
die Job-Daten werden in den BlockFlow <b>kopiert</b>
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1773960255841" ID="ID_323840653" MODIFIED="1773960295743" TEXT="nur der JobFunktor hängt irgendwo an der Fixture">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
und zwar letztlich tief verborgen im JobTicket
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<node CREATED="1773960298898" ID="ID_736834401" MODIFIED="1773960347148" TEXT="hab ich das korrekt verstanden?">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
das notiere ich jetzt, 3/2026, während ich grade versuche, meine eigene (halbfertige) Konzeption von vor 2 Jahren in Erinnerung zu rufen
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1773960008708" ID="ID_1749591448" MODIFIED="1773960213646" TEXT="neue Begriffe zeichnen sich ab">
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1773960015755" ID="ID_891443984" MODIFIED="1773960030115" TEXT="JobTicket ⟻ ein Tempalte / Blueprint"/>
|
||||
<node CREATED="1773960031046" ID="ID_1684085347" MODIFIED="1773960048747" TEXT="JobFunktor ⟻ der feste Teil pro Segment"/>
|
||||
<node CREATED="1773960065970" ID="ID_63834987" MODIFIED="1773960078868" TEXT="JobParameter ⟻ der bewegliche Teil pro Frame"/>
|
||||
<node CREATED="1773960114595" ID="ID_194181398" MODIFIED="1773960136881" TEXT="»Job« ⟻ ein Definitions-Record aus der Job-Planung">
|
||||
<node CREATED="1773960138176" ID="ID_805663525" MODIFIED="1773960148496" TEXT="das sind transiente Daten">
|
||||
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1773960151771" ID="ID_85736689" MODIFIED="1773960171567" TEXT="Invocation-Activity ⟻ was tatsächlich gescheduled und ausgeführt wird"/>
|
||||
<node CREATED="1773960173827" ID="ID_663719055" MODIFIED="1773960192027" TEXT="JobInvocation ⟻ dern Anker-Record für den Node-pull()"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1701486985336" ID="ID_651799474" MODIFIED="1701486990571" TEXT="Eigenschaften">
|
||||
<node CREATED="1681086385917" ID="ID_1193213661" MODIFIED="1701487006678" TEXT="leichtgewichtig, kopierbar, stateful, Scheduler-impl-owned">
|
||||
|
|
@ -119123,8 +119225,15 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1686872232642" ID="ID_656864702" MODIFIED="1686872236953" TEXT="Output-Handles">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1686872616987" ID="ID_1351243761" MODIFIED="1686872629371" TEXT="Vorsicht mit DataSink">
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1686872616987" ID="ID_1351243761" MODIFIED="1773943191255" TEXT="Vorsicht mit DataSink">
|
||||
<linktarget COLOR="#ff1125" DESTINATION="ID_1351243761" ENDARROW="Default" ENDINCLINATION="669;80;" ID="Arrow_ID_1409482268" SOURCE="ID_795422547" STARTARROW="None" STARTINCLINATION="788;42;"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1773942789187" HGAP="48" ID="ID_1528268098" MODIFIED="1773942802378" TEXT="Contention">
|
||||
<font NAME="SansSerif" SIZE="10"/>
|
||||
</node>
|
||||
<node CREATED="1773942804689" HGAP="47" ID="ID_690486099" MODIFIED="1773942827527" TEXT="stale Sink" VSHIFT="-13">
|
||||
<font NAME="SansSerif" SIZE="10"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -119274,7 +119383,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
</node>
|
||||
<node CREATED="1684980982361" ID="ID_1863198468" MODIFIED="1684980987321" TEXT="Themen">
|
||||
<node CREATED="1684980991406" ID="ID_1812192430" MODIFIED="1698948793241" TEXT="Timings nachführen">
|
||||
<arrowlink COLOR="#705783" DESTINATION="ID_1565158605" ENDARROW="Default" ENDINCLINATION="588;-13;" ID="Arrow_ID_516157232" STARTARROW="None" STARTINCLINATION="126;24;"/>
|
||||
<arrowlink COLOR="#705783" DESTINATION="ID_1565158605" ENDARROW="Default" ENDINCLINATION="588;-13;" ID="Arrow_ID_516157232" STARTARROW="None" STARTINCLINATION="240;35;"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -131037,7 +131146,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1684980732965" ID="ID_1914429002" MODIFIED="1684980742528" TEXT="Thema: Timing-Updates">
|
||||
<icon BUILTIN="hourglass"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1684980744406" ID="ID_1565158605" LINK="https://issues.lumiera.org/ticket/1302" MODIFIED="1698948793241" TEXT="#1302 maintain consistent job timings">
|
||||
<linktarget COLOR="#705783" DESTINATION="ID_1565158605" ENDARROW="Default" ENDINCLINATION="588;-13;" ID="Arrow_ID_516157232" SOURCE="ID_1812192430" STARTARROW="None" STARTINCLINATION="126;24;"/>
|
||||
<linktarget COLOR="#705783" DESTINATION="ID_1565158605" ENDARROW="Default" ENDINCLINATION="588;-13;" ID="Arrow_ID_516157232" SOURCE="ID_1812192430" STARTARROW="None" STARTINCLINATION="240;35;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -137658,6 +137767,9 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<node COLOR="#491367" CREATED="1773953799330" HGAP="32" ID="ID_1722445287" MODIFIED="1773953842134" TEXT="insofern steht »Video« hier für Output generell" VSHIFT="2">
|
||||
<font NAME="SansSerif" SIZE="10"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1771531261826" ID="ID_921952522" MODIFIED="1771531308773" TEXT="es sollen erstmals die Komponenten des geplanten Output-Frameworks skizziert werden">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
|
|
@ -138024,7 +138136,8 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
<node CREATED="1773423115479" ID="ID_1275456830" MODIFIED="1773423123305" TEXT="Probleme / Hürden">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1773423124811" ID="ID_1029911055" MODIFIED="1773423172313" TEXT="die Deallokation soll automatisch sein!">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node COLOR="#5b280f" CREATED="1773512654297" ID="ID_1638173657" MODIFIED="1773512694248" TEXT="eine explizite disconnect() - Operation ist nicht möglich">
|
||||
<node COLOR="#5b280f" CREATED="1773512654297" ID="ID_1638173657" MODIFIED="1773954217403" TEXT="eine explizite disconnect() - Operation ist nicht möglich">
|
||||
<linktarget COLOR="#8f0506" DESTINATION="ID_1638173657" ENDARROW="Default" ENDINCLINATION="122;886;" ID="Arrow_ID_1863490886" SOURCE="ID_921042105" STARTARROW="None" STARTINCLINATION="93;-343;"/>
|
||||
<icon BUILTIN="stop-sign"/>
|
||||
<node CREATED="1773512696096" ID="ID_1294019243" MODIFIED="1773512707442" TEXT="theoretisch schon ...">
|
||||
<node CREATED="1773512708976" ID="ID_1096604252" MODIFIED="1773512720076" TEXT="aber dann können wir entweder nur blocken"/>
|
||||
|
|
@ -138056,7 +138169,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
<linktarget COLOR="#4b1ec1" DESTINATION="ID_49953306" ENDARROW="Default" ENDINCLINATION="-1107;45;" ID="Arrow_ID_474360109" SOURCE="ID_497122958" STARTARROW="None" STARTINCLINATION="687;22;"/>
|
||||
<linktarget COLOR="#5a22df" DESTINATION="ID_49953306" ENDARROW="Default" ENDINCLINATION="770;-33;" ID="Arrow_ID_886780269" SOURCE="ID_1831855764" STARTARROW="None" STARTINCLINATION="751;0;"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1773703618287" HGAP="62" ID="ID_914494536" MODIFIED="1773703647578" TEXT="muß BufferProxyAdaptor in OutputSlot::Allocstate integrieren" VSHIFT="33">
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1773703618287" HGAP="62" ID="ID_914494536" MODIFIED="1774041144417" TEXT="muß BufferProxyAdaptor in OutputSlot::AllocState integrieren" VSHIFT="33">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1773703751137" ID="ID_340628735" MODIFIED="1773703998020" TEXT="Überlegung am Rande: längerfristig wollen wir einen globalen Metadaten-Store">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
|
|
@ -138206,6 +138319,351 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
<node CREATED="1773888873544" ID="ID_1930210997" MODIFIED="1773888889891" TEXT="Vorteil: ich kann die back-Reference nach innen in den BufferStore schieben"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1773934250649" ID="ID_1023733837" MODIFIED="1774041080914" TEXT="Umstellen der DataSink">
|
||||
<arrowlink COLOR="#512fb3" DESTINATION="ID_848279587" ENDARROW="Default" ENDINCLINATION="-42;-865;" ID="Arrow_ID_998347051" STARTARROW="None" STARTINCLINATION="-628;72;"/>
|
||||
<node CREATED="1773934262265" ID="ID_1065611224" MODIFIED="1773934275092" TEXT="möglichst das sichtbare API nicht anpassen">
|
||||
<node CREATED="1773934291293" ID="ID_736836401" MODIFIED="1773934304615" TEXT="AllocState ist erst der OutputSlot-Impl bekannt"/>
|
||||
<node CREATED="1773934310714" ID="ID_424279130" MODIFIED="1773934328756" TEXT="der Vorteil von shared-ptr / lib::Handle war das nachträgliche »connect«"/>
|
||||
<node CREATED="1773934473493" ID="ID_95161604" MODIFIED="1773934735954" TEXT="müßte also irgendwo noch eine Operation »verstecken«">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Das bisherige Design war da relativ <i>elegant,</i> insofern man die Verschaltung von außen praktisch nicht sehen konnte. Denn das Connection-API war zwar da, aber üblicherweise für den Client verborgen (dazu müßte man output-slot-connection.hpp includieren). Diese Eleganz war aber dadurch erkauft, daß die Connection-Impl sehr eng mit der Allocation-Impl verwoben sein mußte, es gab da ein komplexes Ping-Pong, und das trägt viel zur verwirrenden Struktur bei, denn das bleibt auf Ebene der Schnittstellen-Definition eine implizite Annahme, und wird erst sichtbar, wenn man sich eine konkrete Implementierung anschaut.
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1773934737674" ID="ID_520921768" MODIFIED="1773935142203" TEXT="Idee: eigentlich ist DataSink ein SAM-Interface">
|
||||
<arrowlink COLOR="#fdfcce" DESTINATION="ID_1441463746" ENDARROW="Default" ENDINCLINATION="8;-14;" ID="Arrow_ID_1724278464" STARTARROW="None" STARTINCLINATION="-103;6;"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1773935062041" ID="ID_1441463746" MODIFIED="1773935142204" TEXT="könnte man durch einen (benannten) Funktor ersetzen">
|
||||
<linktarget COLOR="#fdfcce" DESTINATION="ID_1441463746" ENDARROW="Default" ENDINCLINATION="8;-14;" ID="Arrow_ID_1724278464" SOURCE="ID_520921768" STARTARROW="None" STARTINCLINATION="-103;6;"/>
|
||||
<node CREATED="1773935150587" ID="ID_161241432" MODIFIED="1773935173747" TEXT="damit wäre die Callback-Verbindung komplett Opaque"/>
|
||||
<node CREATED="1773935174519" ID="ID_264086972" MODIFIED="1773935193465" TEXT="und kann auch spät, aus dem bereits erzeugten AllocState heraus festgelegt werden"/>
|
||||
<node CREATED="1773935205347" ID="ID_1089094468" MODIFIED="1773935412447" TEXT="man könnte dann die DataSink sogar wieder beliebig kopierbar machen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
denn nun hängt alles an dem kontextuellen Binding, das man in einem Lambda einrichtet und dann in die Funktion speichert; ein Lambda mit Ref-Closure ist beliebig kopierbar, aber nicht zuweisbar; eine std::function, die mit einem solchen Lambda initialisiert wurde, wäre sogar zuweisbar
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1773935429109" ID="ID_845267707" MODIFIED="1773935529473" TEXT="Aber: dann kann DataSink nicht mehr per Ref-counting den Allocation-Lebenszyklus steuern">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Durch die Lösung mit dem Funktor gäbe es dann wirklich nur noch eine einzige Operation; bisher hatten wir eine versteckte weitere Operation, insofern das lib::Handle mit einem Deleter konfiguriert wurde
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1773935626212" ID="ID_638151363" MODIFIED="1773935640598" TEXT="also neue Lösung für den Lebenszyklus finden"/>
|
||||
</node>
|
||||
<node CREATED="1774058024248" ID="ID_82008745" MODIFIED="1774058054776" TEXT="aber: daran denken daß die DataSink auch sowas wie eine Stream-ID bieten sollte"/>
|
||||
</node>
|
||||
<node CREATED="1774041166497" ID="ID_1405169811" MODIFIED="1774041789004" TEXT="Design nochmal überdenken">
|
||||
<linktarget COLOR="#96171e" DESTINATION="ID_1405169811" ENDARROW="Default" ENDINCLINATION="32;82;" ID="Arrow_ID_1850815871" SOURCE="ID_1695581190" STARTARROW="None" STARTINCLINATION="-700;32;"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#8b0655" CREATED="1774041267592" ID="ID_1373364216" MODIFIED="1774041446113" TEXT="dabei ist dieses Design theoretisch so elegant....">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Es ist <i>elegant, </i>insofern alle Zustände und Momente des Protokolls direkt repräsentiert sind. Das ist aber eine rein schematische Betrachtungsweise. Von einer tatsächich geeigneten Architektur erwarte ich, daß sie den notwendigen Raum gibt, in einer zwanglosen Weise. Das ist hier nicht der Fall. Daher muß ich mich von meinen eigenen Errungenschaften von »damals« trennen (denn damals hatte ich diese Perspektive noch nicht)
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="smily_bad"/>
|
||||
</node>
|
||||
<node CREATED="1774041230081" ID="ID_1126521339" MODIFIED="1774041621832" TEXT="deute die notorischen Problme mit dem State/Lifecycle als einen Wink">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Zusammengenommen fällt auf
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
die Anker-Entität ist weitgehend leer und spielt weder in der Implementierung, noch im Interface eine Rolle
|
||||
</li>
|
||||
<li>
|
||||
der zentrale pImpl wird jetzt zu einem weak-ptr (also einem reinen »Anhängsel«)
|
||||
</li>
|
||||
<li>
|
||||
ich kämpfe immerfort mit Problemen, daß Callbacks nicht „an der richtigen Stelle ankommen“
|
||||
</li>
|
||||
<li>
|
||||
die Zugangspunkte und der Kontext müssen auf verschlungenden Pfaden dorthin gebracht werden, wo sie gebraucht werden.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
Kurz gefaßt, was geschieht, geschieht nicht am rechten Ort
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<node CREATED="1774041659645" ID="ID_35281124" MODIFIED="1774041668866" TEXT="der PImpl pImpelt gar nicht"/>
|
||||
<node CREATED="1774041669975" ID="ID_293144991" MODIFIED="1774041701614" TEXT="OutputSlot ist fast nur ein Marker"/>
|
||||
<node CREATED="1774041702802" ID="ID_1059075539" MODIFIED="1774041716165" TEXT="sogar die Allocation ist nur transient"/>
|
||||
<node CREATED="1774041720512" ID="ID_699098233" MODIFIED="1774041746264" TEXT="und mit dem shared-ptr kommt noch ein weiteres front-end-Handle ins Spiel"/>
|
||||
</node>
|
||||
<node CREATED="1774041802165" ID="ID_400821992" MODIFIED="1774041817127" TEXT="OutputSlot und Allocation zu einem neuen front-end-Handle verschmelzen">
|
||||
<node CREATED="1774041822205" ID="ID_527875329" MODIFIED="1774041843283" TEXT="künftig bekommt man also den OutputSlot sofort im »allozierten« Zustand"/>
|
||||
<node CREATED="1774041847407" ID="ID_883089965" MODIFIED="1774041871047" TEXT="was ich mal (theoretisch) für den OutputSlot vorgesehen hatte ⟶ in den OutputManager"/>
|
||||
<node CREATED="1774041924787" ID="ID_1979509297" MODIFIED="1774041966755" TEXT="OutputSlot wird damit kopierbar und verliert die VTable"/>
|
||||
<node CREATED="1774041982834" ID="ID_1851190390" MODIFIED="1774042051311" TEXT="der Konstruktor nimmt nun direkt einen unique_ptr<Allocation>"/>
|
||||
<node CREATED="1774042055979" ID="ID_1678190677" MODIFIED="1774042077220" TEXT="...und pflanzt den in einen shared-ptr als pImpl"/>
|
||||
<node CREATED="1774042095382" ID="ID_409572046" MODIFIED="1774042116105" TEXT="getOpenedSinks() hat darauf nun direkt Zugriff"/>
|
||||
<node CREATED="1774042144135" ID="ID_398645730" MODIFIED="1774042163080" TEXT="und delegiert an eine builder/verdrahtungs-Funktion auf dem PImpl"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1773954149241" ID="ID_203883845" MODIFIED="1773954234498" TEXT="Allocation / Lebenszyklus in den Griff bekommen">
|
||||
<arrowlink COLOR="#d0020f" DESTINATION="ID_671153651" ENDARROW="Default" ENDINCLINATION="-3;-427;" ID="Arrow_ID_1331623727" STARTARROW="Default" STARTINCLINATION="-756;0;"/>
|
||||
<node CREATED="1773971803964" ID="ID_987627732" MODIFIED="1773971813190" TEXT="gemeinamen shared-ptr einführen">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1773973038119" ID="ID_322920487" MODIFIED="1773973052086" TEXT="Problem: diesen erzeugen und verdrahten">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1773973059692" ID="ID_1788170271" MODIFIED="1773973087364" TEXT="muß eine Deleter-Funktion einbinden"/>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1773973088177" ID="ID_534312365" MODIFIED="1773973144984" TEXT="muß aber diesen Pointer auch im AllocState selber zugänglich machen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
weil wir ihn dann später in die DataSinks verdrahten wollen
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node CREATED="1773973156752" ID="ID_1805849643" MODIFIED="1773973178296" TEXT="und zudem muß die OutputSlot-Impl den tatsächlichen AllocState konstruieren können"/>
|
||||
<node CREATED="1774041751196" ID="ID_1946395022" MODIFIED="1774041772893" TEXT="nun könnte man eine Factory bauen, und ein leere Handle überall hin durchschieben"/>
|
||||
<node CREATED="1774041103709" ID="ID_1695581190" MODIFIED="1774041789004" TEXT="das ist alles so kompliziert ⟹ etwas mit dem Design stimmt nicht">
|
||||
<arrowlink COLOR="#96171e" DESTINATION="ID_1405169811" ENDARROW="Default" ENDINCLINATION="32;82;" ID="Arrow_ID_1850815871" STARTARROW="None" STARTINCLINATION="-700;32;"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1773971813999" ID="ID_36151402" MODIFIED="1773971845114" TEXT="dieser wird per λ-closure im DataSink-Funktor verborgen"/>
|
||||
<node CREATED="1773971849966" ID="ID_1738000581" MODIFIED="1773971868607" TEXT="der »pImpl« in OutputSlot wird ein daran angekoppelter weak-ptr"/>
|
||||
<node CREATED="1773971873811" ID="ID_264465688" MODIFIED="1773971898075" TEXT="auf das vorzeitige Schließen einzelner Connections wird verzichtet"/>
|
||||
<node CREATED="1773971902700" ID="ID_967293485" MODIFIED="1773971931718" TEXT="aber es muß einen globalen (virtuellen) release-Hook im OutputSlot geben"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1773935649392" ID="ID_671153651" MODIFIED="1773954244683" TEXT="Steuern des Allocation-Lebenszyklus">
|
||||
<linktarget COLOR="#d0020f" DESTINATION="ID_671153651" ENDARROW="Default" ENDINCLINATION="-3;-427;" ID="Arrow_ID_1331623727" SOURCE="ID_203883845" STARTARROW="Default" STARTINCLINATION="-756;0;"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1773935662405" ID="ID_921042105" MODIFIED="1773954217403" TEXT="ehrlich gesagt: diese Aufgabe war bisher gar nicht richtig gelöst">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
der Deleter hat bisher nur Connection::shutDown() aufgerufen; alles darüberhinaus war nur eine <i>Absichtserklärung</i> — im Besonderen das Problem mit dem Blocken (im Fall eines Emergency-Shutdown) hab ich seinerzeit (2012) noch nicht einmal erkannt ...  inzwischen hab ich es wenigstens mal notiert als Anforderung »für später«
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<arrowlink COLOR="#8f0506" DESTINATION="ID_1638173657" ENDARROW="Default" ENDINCLINATION="122;886;" ID="Arrow_ID_1863490886" STARTARROW="None" STARTINCLINATION="93;-343;"/>
|
||||
</node>
|
||||
<node CREATED="1773936076352" ID="ID_1795427929" MODIFIED="1773936082775" TEXT="mögliche Alternativen">
|
||||
<node CREATED="1773936156477" ID="ID_1492599648" MODIFIED="1773936162362" TEXT="auf den Client abwälzen">
|
||||
<node CREATED="1773936163386" ID="ID_744734834" MODIFIED="1773936184925" TEXT="der muß explizit ein release() auf der Allokation aufrufen"/>
|
||||
<node CREATED="1773936196111" ID="ID_1044373385" MODIFIED="1773936333545" TEXT="das öffnet die Möglichkeit einer »dangling connection«">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
wenn ein Client noch eine Connection hat, dann ist nicht klar, was passieren soll, wenn auf oberer Ebene die Allocation geschlossen wird — und zwar weil nicht klar ist wie die Allokation und die einzelnen Feeds zusammenhängen
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1773936791960" ID="ID_215146115" MODIFIED="1773937017157">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
der typische low-level-Ansatz wäre: <i>dann mach's halt nich falsch</i>
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
und das heißt, man löst Probleme nicht architektonisch, durch eine Anordnung die dem Wesen der Sache entspricht, sondern man setzt einfach einen Machtspruch, und wältzt damit alles Unpassende, das man selber nicht bewältigt hat, auf den Client ab
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1773936852379" ID="ID_1329021680" MODIFIED="1773936875361" TEXT="das hier ist aber kein low-level-System">
|
||||
<node CREATED="1773937344238" ID="ID_1294714046" MODIFIED="1773937377709" TEXT="Output-Verbindungen werden nur selten geöffnet oder geschlossen"/>
|
||||
<node CREATED="1773937390145" ID="ID_1687721673" MODIFIED="1773937410754" TEXT="einzelne Frames werden im Bereich 4-20ms abgeliefert"/>
|
||||
<node CREATED="1773937469494" ID="ID_1230761301" MODIFIED="1773937482156" TEXT="der einzige relevante Belang wäre Thread-Contention"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1773944395757" ID="ID_1306067965" MODIFIED="1773944400656" TEXT="an die Allocation binden">
|
||||
<node CREATED="1773944410058" ID="ID_1827849947" MODIFIED="1773944432364" TEXT="der Client bekommt einen shared-ptr<Allocation>"/>
|
||||
<node CREATED="1773944469539" ID="ID_67616665" MODIFIED="1773944482101" TEXT="wenn der weggeht, wird der OutputSlot freigegeben"/>
|
||||
<node CREATED="1773944493868" ID="ID_217054546" MODIFIED="1773944499034" TEXT="mögliche Probleme">
|
||||
<node CREATED="1773944500318" ID="ID_184117470" MODIFIED="1773944531470" TEXT="Allocation wird eigentlich nur initial benötigt um die einzelnen CalcStreams einzurichten"/>
|
||||
<node CREATED="1773944550244" ID="ID_686326233" MODIFIED="1773944582203" TEXT="wenn Allocation verworfen wird, dürfen keine DataSinks mehr im aktiven Gebrauch sein"/>
|
||||
</node>
|
||||
<node CREATED="1773945187767" ID="ID_1860567905" MODIFIED="1773945214554" TEXT="technischer Kniff: dann müßte der PImpl in OutputSlot ein weak-ptr sein"/>
|
||||
</node>
|
||||
<node CREATED="1773944592095" ID="ID_299411111" MODIFIED="1773944597932" TEXT="an die DataSink(s) binden">
|
||||
<node CREATED="1773944609912" ID="ID_1668244618" MODIFIED="1773944628254" TEXT="eine Kopie residiert ganz sicher im CalcStream / RenderDrive"/>
|
||||
<node CREATED="1773944659698" ID="ID_1827478956" MODIFIED="1773944672187" TEXT="mit dem Ende von Playback oder Render fällt das automatisch weg"/>
|
||||
<node CREATED="1773944676829" ID="ID_907280843" MODIFIED="1773944691969" TEXT="mögliche Probleme">
|
||||
<node CREATED="1773944693525" ID="ID_1393650746" MODIFIED="1773944752276" TEXT="falls ref-counting ⟹ mögliche Thread-Contention bei Kopie"/>
|
||||
<node CREATED="1773944994707" ID="ID_746408900" MODIFIED="1773945023884" TEXT="falls per ref weitergegeben ⟹ dangling / stale connection"/>
|
||||
<node CREATED="1773945042934" ID="ID_251245550" MODIFIED="1773945062808" TEXT="speziell die Jobs können noch „unterwegs sein“"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1773945071243" ID="ID_1122677891" MODIFIED="1773945082045" TEXT="an beides binden">
|
||||
<node CREATED="1773945083241" ID="ID_1495556789" MODIFIED="1773945089643" TEXT="dann ist das definitiv ref-counting"/>
|
||||
<node CREATED="1773945092503" ID="ID_1121188819" MODIFIED="1773945475636" TEXT="das wäre die sichterste Lösung (in unklarem Umfeld)">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Diese geanzen Schwierigkeiten, die Rolle der DataSinks festzulegen, deuten doch vor allem darauf hin, daß nicht nur der Bau, sondern auch die Architektur selber noch unklar ist, und erst schrittweise entfaltet werden soll
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1773945238116" ID="ID_367765995" MODIFIED="1773945276359" TEXT="würde auch unnötige Design-Festlegungen vermeiden"/>
|
||||
</node>
|
||||
<node COLOR="#5b280f" CREATED="1773952231249" ID="ID_1285340586" MODIFIED="1773952238537" TEXT="unique?">
|
||||
<icon BUILTIN="help"/>
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1773952241591" ID="ID_119174352" MODIFIED="1773952253027" TEXT="geht schon ... wird aber komplex"/>
|
||||
<node CREATED="1773952260855" ID="ID_1648261489" MODIFIED="1773952377382" TEXT="zunächst einmal: dann müßte es eine back-reference geben zum OutputSlot">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...damit sich eine Allocation, die nicht mehr benötigt wird, von dort <i>abmelden </i>kann. Das bedeutet, der OutputSlot <b>muß non-copyable sein</b>. (Was er derzeit ist, aber man verliert so einen Freiheitsgrad)
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1773952438637" ID="ID_1210325081" MODIFIED="1773952511056">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
außerdem ist <b>Thread-Safety</b> hier ein echtes Problem
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
OutputSlot wird <i>definitiv stets und massiv über Thread-Grenzen hinweg </i>verwendet
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1773957264534" ID="ID_969840903" MODIFIED="1773957275425" TEXT="Kontext für die Entscheidung">
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1773962991267" ID="ID_589497720" MODIFIED="1773963381592" TEXT="Konzept »Job« hat sich unterwegs verändert">
|
||||
<arrowlink COLOR="#fe6c6c" DESTINATION="ID_1973724646" ENDARROW="Default" ENDINCLINATION="-1379;72;" ID="Arrow_ID_663742943" STARTARROW="None" STARTINCLINATION="-974;63;"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node CREATED="1773957282397" ID="ID_1508520426" MODIFIED="1773957301670" TEXT="die Data-Sink muß vom Job zugänglich sein">
|
||||
<node CREATED="1773957303194" ID="ID_1255413814" MODIFIED="1773957310531" TEXT="Jobs werden per Value erzeugt"/>
|
||||
<node CREATED="1773957326523" ID="ID_661258827" MODIFIED="1773963300365" TEXT="der Job-Record dient nur der Definition"/>
|
||||
<node CREATED="1773963301185" ID="ID_1244291880" MODIFIED="1773963350058">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
die Parameter / Kenndaten werden in den Acticity-Term <b>kopiert</b>
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...sie liegen also während der Lebensdauer des Jobs im BlockFlow (Memory-Manager)
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1773963397196" ID="ID_450040445" MODIFIED="1773963401655" TEXT="Konsequenzen">
|
||||
<node CREATED="1773963404355" ID="ID_1299672622" MODIFIED="1773963422509" TEXT="selbst Jobs für einen bereits gestoppten Play-Process können noch aufgerufen werden"/>
|
||||
<node CREATED="1773963434541" ID="ID_1279046407" MODIFIED="1773963450237" TEXT="ein Play-Process kann concurrent gestoppt werden, während grade eine Berechnung läuft"/>
|
||||
<node CREATED="1773963462458" ID="ID_1647276372" MODIFIED="1773963532738">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
der Bezug auf die DataSink hat <i><font color="#a40f60">value semantics</font></i> (als Job-Parameter)
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1773963570901" ID="ID_54756312" MODIFIED="1773963597461" TEXT="bis zum Scheduling wird dieser Bezug viel kopiert"/>
|
||||
<node CREATED="1773963598478" ID="ID_533020256" MODIFIED="1773963700574" TEXT="während der Job-Ausführung aber liegt er im BlockFlow, und hinter einer read-barrier">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Und zwar wird diese Read-Barrier vom GroomingToken impliziert, denn der Thread, der letztlich den Job ausführt, hat vorher stets und garantiert etwas Admin-Arbeit geleistet und dafür das (atomic) GroomingToken erlangt ⟹ data visibility guaranteed
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1773968819539" ID="ID_1045661370" MODIFIED="1773968861683" TEXT="und wichtig: diese Planung soll auf Flexibilität zielen">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1773968864012" ID="ID_1325171495" MODIFIED="1773968882197" TEXT="wir wissen definitiv noch nicht wo genau der »Knackpunkt« liegt"/>
|
||||
<node CREATED="1773968885005" ID="ID_243921844" MODIFIED="1773968896251" TEXT="es fehlt an Kontext um genaue Zielabwägungen zu treffen"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1773969731041" ID="ID_1083742526" MODIFIED="1773969741797" TEXT="Entscheidung für Prototyp">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1773969746830" ID="ID_187653058" MODIFIED="1773969766296" TEXT="verwende gemeinsamen shared-ptr für Allocation (incl. DataSink)"/>
|
||||
<node CREATED="1773969768795" ID="ID_794465081" MODIFIED="1773969784333" TEXT="der PImpl im OutputSlot wird ein daran gekoppelter weak-ptr"/>
|
||||
<node CREATED="1773969790564" ID="ID_1539390314" MODIFIED="1773970166449" TEXT="einzelne Connections werden (vorerst) nicht direkt freigegeben">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...und zwar aus mehrerlei Gründen
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
wir müßten hierzu für jede Connection einen eigenen ref-cnt pflegen
|
||||
</li>
|
||||
<li>
|
||||
dieser ref-count müßte als Atomic implementiert sein und von einem separaten destructor-Hook in einem speziellen Handle-Typ aufgerufen werden, was die Implementierung deutlich komplexer macht
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1773969819811" ID="ID_1016530309" MODIFIED="1773969866458" TEXT="es muß aber eine virtuelle Funktion auf OutputSlot als Shutdown-Hook aufgerufen werden"/>
|
||||
<node CREATED="1773970167566" ID="ID_236888985" MODIFIED="1773970608281" TEXT="wir unterstellen daß Daten-Sichtbarkeit bereits aus dem Aufrufkontext sichergestlellt ist">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
⟹ kein weiteres Locking in AllocState notwendig. Der ref-count in shared-ptr verwendet bereits einen Atomic (effektiv würde das allein bereits genügen, aber ich bin mir dessen nicht ganz sicher). Zudem gibt es das GroomingToken. Bliebe nur noch der Fall, daß die Connection durch Beenden des Play-Prozesses geschlossen wird; in diesem Fall sollte man wohl noch etwas tun.
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1773970935147" ID="ID_946367752" LINK="https://issues.lumiera.org/ticket/878" MODIFIED="1773971040192" TEXT="später überprüfen ⟹ #878">
|
||||
<icon BUILTIN="bell"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -138242,6 +138700,22 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
</node>
|
||||
<node CREATED="1771532464268" ID="ID_1570776013" MODIFIED="1771532466986" TEXT="Aufbau"/>
|
||||
<node CREATED="1771532467904" ID="ID_296392657" MODIFIED="1771532475206" TEXT="Test / Integration"/>
|
||||
<node CREATED="1773943696478" ID="ID_804733574" MODIFIED="1773944340005" TEXT="Design-Fragen">
|
||||
<arrowlink COLOR="#7e1044" DESTINATION="ID_1994801177" ENDARROW="Default" ENDINCLINATION="-916;-101;" ID="Arrow_ID_1846104737" STARTARROW="None" STARTINCLINATION="-1069;199;"/>
|
||||
<node CREATED="1773943137275" ID="ID_848279587" MODIFIED="1774041080915" TEXT="sehe DataSink als kritischen Verknüpfungspunkt">
|
||||
<linktarget COLOR="#512fb3" DESTINATION="ID_848279587" ENDARROW="Default" ENDINCLINATION="-42;-865;" ID="Arrow_ID_998347051" SOURCE="ID_1023733837" STARTARROW="None" STARTINCLINATION="-628;72;"/>
|
||||
<node CREATED="1773940626128" ID="ID_1007087496" MODIFIED="1773940659120" TEXT="DataSink bleibt (indirekt) ref-counting">
|
||||
<linktarget COLOR="#5a6a7d" DESTINATION="ID_1007087496" ENDARROW="Default" ENDINCLINATION="1062;0;" ID="Arrow_ID_358885146" SOURCE="ID_143173446" STARTARROW="None" STARTINCLINATION="687;54;"/>
|
||||
</node>
|
||||
<node CREATED="1773937504609" ID="ID_795422547" MODIFIED="1773958152739" TEXT="hab mir schon mehrfach darüber den Kopf zerbrochen">
|
||||
<arrowlink COLOR="#ff1125" DESTINATION="ID_1351243761" ENDARROW="Default" ENDINCLINATION="669;80;" ID="Arrow_ID_1409482268" STARTARROW="None" STARTINCLINATION="788;42;"/>
|
||||
<arrowlink COLOR="#ff1125" DESTINATION="ID_774940151" ENDARROW="Default" ENDINCLINATION="681;34;" ID="Arrow_ID_1530530196" STARTARROW="None" STARTINCLINATION="1318;69;"/>
|
||||
</node>
|
||||
<node CREATED="1773941728897" ID="ID_1047888380" MODIFIED="1773941769804" TEXT="sollte im Data-Sink eine Stream-Type-ID unterbringen (können wollen)">
|
||||
<linktarget COLOR="#a35e64" DESTINATION="ID_1047888380" ENDARROW="Default" ENDINCLINATION="807;-31;" ID="Arrow_ID_1643361924" SOURCE="ID_1987838291" STARTARROW="None" STARTINCLINATION="861;0;"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1681347244544" ID="ID_444443795" MODIFIED="1681347486789" TEXT="Basis: Operational Control">
|
||||
<linktarget COLOR="#9c738a" DESTINATION="ID_444443795" ENDARROW="Default" ENDINCLINATION="-1256;-1009;" ID="Arrow_ID_1047384894" SOURCE="ID_594073373" STARTARROW="None" STARTINCLINATION="-902;35;"/>
|
||||
|
|
@ -140119,7 +140593,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1697740783336" ID="ID_509932054" MODIFIED="1702334910682" TEXT="TestChainLoad">
|
||||
<node COLOR="#338800" CREATED="1697740783336" FOLDED="true" ID="ID_509932054" MODIFIED="1702334910682" TEXT="TestChainLoad">
|
||||
<linktarget COLOR="#22709b" DESTINATION="ID_509932054" ENDARROW="Default" ENDINCLINATION="-374;-90;" ID="Arrow_ID_1082315358" SOURCE="ID_1899821736" STARTARROW="None" STARTINCLINATION="-1039;60;"/>
|
||||
<linktarget COLOR="#fcffac" DESTINATION="ID_509932054" ENDARROW="Default" ENDINCLINATION="44;-115;" ID="Arrow_ID_388403838" SOURCE="ID_1177697704" STARTARROW="None" STARTINCLINATION="-227;20;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
|
|
@ -159692,8 +160166,37 @@ std::cout << tmpl.render({"what", "World"}) << s
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1682040531781" ID="ID_913436563" MODIFIED="1682040539889" TEXT="offene Fragen">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1682040544603" ID="ID_1221736313" MODIFIED="1682040594240" TEXT="was steht tatsächlich in der PriQueue? Job-Deskriptor oder nur eine Activity?"/>
|
||||
<node CREATED="1682040603211" ID="ID_1088917301" MODIFIED="1682040621149" TEXT="wenn nicht in der Queue, wo werden Jobs dann gespeichert? und wieder freigegeben?"/>
|
||||
<node COLOR="#435e98" CREATED="1682040544603" ID="ID_1221736313" MODIFIED="1773960461882" TEXT="was steht tatsächlich in der PriQueue? Job-Deskriptor oder nur eine Activity?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1773960464782" ID="ID_1440259638" MODIFIED="1773960491429" TEXT="ein Activity-Term">
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1682040603211" ID="ID_1088917301" MODIFIED="1773963127722" TEXT="wenn nicht in der Queue, wo werden Jobs dann gespeichert? und wieder freigegeben?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1773960508375" ID="ID_437141465" MODIFIED="1773963138142" TEXT="Job-Records dienen der Definition / Job-Planung">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node CREATED="1773960521901" ID="ID_468797424" MODIFIED="1773963151116" TEXT="aus ihnen wird ein Acticity-Term konstruiert (Daten-Kopie)">
|
||||
<icon BUILTIN="forward"/>
|
||||
</node>
|
||||
<node CREATED="1773960536379" ID="ID_1295199071" MODIFIED="1773963143543" TEXT="die Daten hinter dem Term liegen im BlockFlow">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
das bedeutet, sie unterliegen einem Deadline-basierten Memory-Management und werden selbständig / automatisch weggeworfen, sobald ein Job laut Deatline <i>nicht mehr laufen kann.</i> Konsequenz: <b>einen Activity-Term mit abgelaufener Deadline darf man nicht mehr anfassen!!</b>  (der Scheduler berücksichtigt das ganz trickreich in seiner Implementierung)
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f1c98c" COLOR="#a50125" CREATED="1773962991267" ID="ID_1593586171" MODIFIED="1773963122806" TEXT="Achtung: Konzept »Job« hat sich unterwegs verändert bzw. aufgelöst">
|
||||
<arrowlink COLOR="#fd2e1b" DESTINATION="ID_1973724646" ENDARROW="Default" ENDINCLINATION="-1379;72;" ID="Arrow_ID_862194975" STARTARROW="None" STARTINCLINATION="1316;57;"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node CREATED="1682808411785" ID="ID_1713196934" MODIFIED="1682808633170" TEXT="welche Parameter müssen einer Invocation im allgemeinen mitgegeben werden">
|
||||
<linktarget COLOR="#b75269" DESTINATION="ID_1713196934" ENDARROW="Default" ENDINCLINATION="-871;-27;" ID="Arrow_ID_865176706" SOURCE="ID_782813898" STARTARROW="None" STARTINCLINATION="-1263;70;"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1682810738487" ID="ID_1493396541" MODIFIED="1682810875535" TEXT="#1295 draft job invocation parameter representation">
|
||||
|
|
@ -160687,7 +161190,7 @@ std::cout << tmpl.render({"what", "World"}) << s
|
|||
Dieser kann durch alltägliche Umstände verletzt werden
|
||||
</p>
|
||||
<p style="text-align: center">
|
||||
Dann ist ein spezielle Notzustand zu aktivieren
|
||||
Dann ist ein spezieller Notzustand zu aktivieren
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
|
|
@ -160904,7 +161407,7 @@ std::cout << tmpl.render({"what", "World"}) << s
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1512923629577" ID="ID_617347424" MODIFIED="1557498707237" TEXT="Backend">
|
||||
<node CREATED="1512923629577" ID="ID_617347424" MODIFIED="1773943936982" TEXT="Backend/Vault">
|
||||
<node CREATED="1680565608115" ID="ID_1114884704" MODIFIED="1680565612050" TEXT="Hilfsmittel">
|
||||
<node CREATED="1680565613038" ID="ID_1202060017" MODIFIED="1680565616857" TEXT="Content-Generator">
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1680565626147" ID="ID_460039330" MODIFIED="1697737436489" TEXT="Test-Content für Playback">
|
||||
|
|
@ -161041,6 +161544,34 @@ std::cout << tmpl.render({"what", "World"}) << s
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1773943941951" ID="ID_143825847" MODIFIED="1773943945165" TEXT="Output">
|
||||
<node CREATED="1773943954879" ID="ID_1770432678" MODIFIED="1773943963071" TEXT="Output Management"/>
|
||||
<node CREATED="1773943963893" ID="ID_1662508344" MODIFIED="1773943973917" TEXT="Interface: OutputSlot">
|
||||
<node CREATED="1773943815922" ID="ID_1994801177" MODIFIED="1773944340005" TEXT="Design schrittweise entwickelt">
|
||||
<linktarget COLOR="#7e1044" DESTINATION="ID_1994801177" ENDARROW="Default" ENDINCLINATION="-916;-101;" ID="Arrow_ID_1846104737" SOURCE="ID_804733574" STARTARROW="None" STARTINCLINATION="-1069;199;"/>
|
||||
<node CREATED="1773944091669" ID="ID_226569198" MODIFIED="1773944093952" TEXT="Historie">
|
||||
<node CREATED="1773944095012" ID="ID_1549993849" MODIFIED="1773944105815" TEXT="2011 / 2012 : erste Entwürfe"/>
|
||||
<node CREATED="1773944106611" ID="ID_446796907" MODIFIED="1773944129196" TEXT="2024/26 »Playback Vertical Slice«">
|
||||
<node CREATED="1773944143142" ID="ID_1057786773" MODIFIED="1773944316424" TEXT="erster Anlauf zu einer Gesamtintegration »plain play«">
|
||||
<arrowlink COLOR="#523364" DESTINATION="ID_580288207" ENDARROW="Default" ENDINCLINATION="-1850;513;" ID="Arrow_ID_420590547" STARTARROW="None" STARTINCLINATION="-3285;-3404;"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1773970935147" ID="ID_1484866387" LINK="https://issues.lumiera.org/ticket/878" MODIFIED="1773971010859" TEXT="Lifecycle und Locking überprüfen ⟹ #878">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1773943989131" ID="ID_465864547" MODIFIED="1773943999517" TEXT="konkrete Output-Mechanismen">
|
||||
<node CREATED="1773944001483" ID="ID_673165696" MODIFIED="1773944011756" TEXT="Video">
|
||||
<node CREATED="1773944013001" ID="ID_992691145" MODIFIED="1773944014643" TEXT="im GUI"/>
|
||||
<node CREATED="1773944015421" ID="ID_1354847789" MODIFIED="1773944047244" TEXT="dediziert"/>
|
||||
<node CREATED="1773944052125" ID="ID_1584352494" MODIFIED="1773944056669" TEXT="Hardware-Acceleration"/>
|
||||
</node>
|
||||
<node CREATED="1773944058913" ID="ID_308362687" MODIFIED="1773944061445" TEXT="Sound"/>
|
||||
<node CREATED="1773944073911" ID="ID_1249734675" MODIFIED="1773944076217" TEXT="Datei"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1720994187035" ID="ID_1817562586" MODIFIED="1720994190143" TEXT="Basis-Dienste"/>
|
||||
</node>
|
||||
<node CREATED="1720131181173" ID="ID_792463857" MODIFIED="1720131194751" TEXT="Extern">
|
||||
|
|
|
|||
Loading…
Reference in a new issue