OutputSlot: complete connection of redesigned implementation (see #1415)
After resolving the inner tensions in the old prototype from 2012, it was now possible to resolve all issues in a single strike * `DataSink` becomes a functor, yet embeds a shared ref-count * in the λ-closure a ''specific Buffer Descriptor'' is prepared for each feed * building upon the prototyping work, a dedicated `OutputBufferProxy` exposes a `BuffHandle` to the client, with `emit()` and `release()` calls * the implementation ''delegates directly'' to the `OutputSlot::Connection` * an this is where all actual output technology is encapsulated
This commit is contained in:
parent
f29ec44fda
commit
c87bc7fe27
8 changed files with 324 additions and 197 deletions
|
|
@ -153,21 +153,8 @@ namespace out {
|
|||
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : (end) disabled code
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
isTimely (FrameID frameNr, TimeValue currentTime) override
|
||||
{
|
||||
TRACE (test, "Con=%p : timely? frame-#%lu"
|
||||
, this, frameNr);
|
||||
|
||||
if (Time::ANYTIME == currentTime)
|
||||
return true;
|
||||
else
|
||||
return currentTime < deadlineFor (frameNr);
|
||||
}
|
||||
|
||||
void
|
||||
transfer (Buff* filledBuffer) override
|
||||
publish (Buff* filledBuffer) override
|
||||
{
|
||||
#if false //////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : disabled code due to OutputSlot refactoring
|
||||
TRACE (test, "Con=%p : transfer buffer %zu"
|
||||
|
|
@ -179,7 +166,7 @@ namespace out {
|
|||
}
|
||||
|
||||
void
|
||||
pushout (Buff* data4output) override
|
||||
release (Buff* data4output) override
|
||||
{
|
||||
#if false //////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : disabled code due to OutputSlot refactoring
|
||||
REQUIRE (!closed_);
|
||||
|
|
@ -188,15 +175,6 @@ namespace out {
|
|||
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : (end) disabled code
|
||||
}
|
||||
|
||||
void
|
||||
discard (Buff* superseededData) override
|
||||
{
|
||||
#if false //////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : disabled code due to OutputSlot refactoring
|
||||
REQUIRE (!closed_);
|
||||
buffProvider_.releaseBuffer (superseededData);
|
||||
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1410 : (end) disabled code
|
||||
}
|
||||
|
||||
void
|
||||
shutDown() override
|
||||
{
|
||||
|
|
|
|||
|
|
@ -100,13 +100,15 @@ namespace out {
|
|||
void
|
||||
mark_emitted (HashVal, BuffAlloc storageSlot) override
|
||||
{
|
||||
TODO ("delegate buffer emit");
|
||||
auto& [buffer,siz,targetMarker] = storageSlot;
|
||||
asTarget(targetMarker).publish (buffer);
|
||||
}
|
||||
|
||||
void
|
||||
detachBuffer (HashVal, BuffAlloc storageSlot) override
|
||||
{
|
||||
TODO ("delegate buffer release");
|
||||
auto& [buffer,siz,targetMarker] = storageSlot;
|
||||
asTarget(targetMarker).release (buffer);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -13,16 +13,42 @@
|
|||
|
||||
/** @file output-slot-connection.hpp
|
||||
** Interface for concrete output implementations to talk to the OutputSlot frontend.
|
||||
** The OutputSlot concept helps to decouple the render engine implementation from the details
|
||||
** of handling external output connections. For this to work, a concrete implementation of such
|
||||
** an external output needs to integrate with the generic OutputSlot frontend, as used by the
|
||||
** engine. This generic frontend uses a PImpl, pointing to a AllocState object, which embodies
|
||||
** the actual implementation. Moreover, this actual implementation is free to use specifically crafted
|
||||
** OutputSlot::Connection elements to handle the ongoing output for individual channels. The latter
|
||||
** thus becomes the central implementation side API for providing actual output capabilities.
|
||||
**
|
||||
** This setup with an OutputSlot concept helps to decouple the render engine implementation
|
||||
** from the details of handling any kind of external output connection. The act of data output
|
||||
** is reduced to the operations described by the OutputSlot::Connection interface.
|
||||
**
|
||||
** # Interplay of parts involved into an actual implementation
|
||||
**
|
||||
** Each distinct output capability must be registered through an OutputManager (and this is another
|
||||
** topic beyond the scope of the interaction described here). When a client wants to output data,
|
||||
** it obtains a suitable OutputSlot through the OutputDirector. This OutputSlot is created and
|
||||
** initialised properly for this single use by the OutputManager in charge for that kind of
|
||||
** output capability; notably it must be outfitted with an actual implementation of the
|
||||
** OutputSlot::Allocation interface, and typically OutputSlot::AllocState<CON> will be
|
||||
** used for that purpose.
|
||||
**
|
||||
** This allocation state is linked at implementation level to some specific implementation of the
|
||||
** OutputSlot::Connection interface, represented as template parameter \a CON. An instance will be
|
||||
** created for each distinct data feed (which applies only if the media stream type in question
|
||||
** comprises several data feeds running in parallel). In many typical cases, only one data feed
|
||||
** and thus only a single Connection instance is required. The client can then retrieve a DataSink
|
||||
** handle for each data feed. Notably, each DataSink participates in the ref-count and thus keeps
|
||||
** the OutputSlot and the Connection(s) alive. Furthermore, [timing constraints](\ref vault::out::Timings)
|
||||
** must be defined, to instruct the client when to deliver the data for each prospective frame. Obviously,
|
||||
** details depend on the underlying technology. In some cases, the client might prepare several buffers
|
||||
** full of data in advance, while for another technology, that, for example, relies on _double buffering_,
|
||||
** the client gets only a single precisely limited time window immediately prior to each _buffer flip_.
|
||||
**
|
||||
** The client code interacts with the output data buffer through a BuffHandle as front-end. This access
|
||||
** scheme is similar to what is used by the generic vault::mem::BufferProvider within the Render Engine.
|
||||
** To enable this setup, the OutputSlot::AllocState embeds a _proxy BufferProvider_ and uses a preconfigured
|
||||
** [buffer (type) descriptor](\ref vault::mem::BuffDescr) for each connection, which also includes information
|
||||
** about the size of the buffer, which is obtained [from the connection](\ref OutputSlot::Connection::getBufferSize)
|
||||
** To start work on a new frame, the client invokes DataSink, which actually is a functor. This call delegates
|
||||
** through the proxy BufferProvider — see \ref OutputBufferProxy::provideBuffer() and thus ends up calling
|
||||
** into Connection::claimBufferFor(frameNr).
|
||||
**
|
||||
** @see OutputSlotProtocol_test
|
||||
** @see diagnostic-output-slot.hpp ////TODO
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -32,77 +58,64 @@
|
|||
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/nocopy.hpp"
|
||||
#include "vault/mem/buffhandle.hpp"
|
||||
#include "vault/out/output-slot.hpp"
|
||||
#include "vault/out/output-buffer-proxy.hpp"
|
||||
#include "lib/scoped-collection.hpp"
|
||||
#include "lib/iter-explorer.hpp"
|
||||
#include "lib/iter-source.hpp"
|
||||
#include "lib/handle.hpp"
|
||||
#include "lib/time/timevalue.hpp"
|
||||
//#include "steam/engine/buffer-provider.hpp"
|
||||
//#include "steam/play/timings.hpp"
|
||||
//#include "lib/sync.hpp"
|
||||
#include "vault/mem/buffer-provider.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
//#include <string>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
//#include <vector>
|
||||
//#include <memory>
|
||||
|
||||
|
||||
namespace vault {
|
||||
namespace out {
|
||||
|
||||
|
||||
using vault::mem::Buff;
|
||||
using vault::mem::BuffHandle;
|
||||
using vault::mem::BufferProvider;
|
||||
using lib::time::TimeValue; /////////////////OOO Rly?
|
||||
//using std::string;
|
||||
using util::unConst;
|
||||
|
||||
//using std::placeholders::_1;
|
||||
//using std::bind;
|
||||
using std::vector;
|
||||
//using std::shared_ptr;
|
||||
|
||||
|
||||
|
||||
|
||||
/** @internal represents the \em active
|
||||
* point in each of the per-channel connections
|
||||
* used when this OutputSlot is operational.
|
||||
/**
|
||||
* # OutputSlot core implementation API
|
||||
*
|
||||
* # 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
|
||||
* to implementing this interface and providing a AllocState.
|
||||
* - `lock()` announces this FrameID and the corresponding buffer
|
||||
* to be in exclusive use by the client from now on
|
||||
* - `transfer()` ends the client sided processing and initiates
|
||||
* the outputting of the data found in the corresponding buffer.
|
||||
* - `pushout()` actually pushes the denoted buffer to the output.
|
||||
* Typically, `pushout()` is called from the `transfer()`
|
||||
* implementation; yet it may as well be called from a separate
|
||||
* service thread or some kind of callback.
|
||||
* This interface describes the operations used by OutputSlot to interact
|
||||
* with the actual output technology. Essentially, the task of providing
|
||||
* a specific OutputSlot consists primarily of implementing and integrating
|
||||
* this Connection interface: for each individual data feed, an instance will
|
||||
* be established as part of the [allocation state](\ref OutputSlot::AllocState).
|
||||
* The general assumption is that some _data buffer_ will be handed-over in a
|
||||
* timely fashion for each data frame. The interface methods thus reflect the
|
||||
* stages of the »Output Slot Protocol« and will be used in sequence for each frame:
|
||||
* - `claimBufferFor(FrameID)` announces a FrameID and exposes a data buffer of suitable
|
||||
* size for exclusive use by the client.
|
||||
* - `publish(buffer)` marks the end of client sided processing and passes the
|
||||
* data in the buffer to the output mechanism for publication.
|
||||
* - `release(buffer)` indicates that the client will not touch this buffer any more,
|
||||
* so that it can be repurposed for outputting another frame.
|
||||
* @remark _by convention_ the client is required to invoke `release()` reliably,
|
||||
* even in cases where `publish()` is skipped (and thus no actual data was provided.
|
||||
* However, invoking `publish()` also transfers ownership, and thus it can be assumed
|
||||
* that the client will not touch the buffer after this point, so the invocation of
|
||||
* `release()` can be ignored after `publish()`. In addition to this sequence,
|
||||
* the client is also bound by the [timing constraints](\ref Timings), yet timing
|
||||
* glitches and missed deadlines can not be precluded; the Connection is expected
|
||||
* to check current time and handle a frame as failure transparently, when
|
||||
* `publish()` is invoked too late, but must keep the buffer in locked / exclusive
|
||||
* state, since the client might still be writing data, even after the deadline.
|
||||
* @note the meaning of FrameID is implementation defined.
|
||||
* @note typically the concrete connection is non-copyable
|
||||
*/
|
||||
class OutputSlot::Connection
|
||||
: util::NonCopyable
|
||||
{
|
||||
public:
|
||||
virtual ~Connection();
|
||||
|
||||
virtual size_t getBufferSize() const =0;
|
||||
virtual Buff* claimBufferFor(FrameID) =0;
|
||||
virtual bool isTimely (FrameID, TimeValue) =0;
|
||||
virtual void transfer (Buff*) =0;
|
||||
virtual void pushout (Buff*) =0;
|
||||
virtual void discard (Buff*) =0;
|
||||
virtual void shutDown () =0;
|
||||
virtual size_t getBufferSize() const =0;
|
||||
virtual Buff* claimBufferFor(FrameID) =0;
|
||||
virtual void publish (Buff*) =0;
|
||||
virtual void release (Buff*) =0;
|
||||
virtual void shutDown () =0;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -120,9 +133,7 @@ namespace out {
|
|||
* to the client code and allows to mark the state transitions.
|
||||
* Theses smart-handles are ref counting and thus the individual
|
||||
* Connection object is kept alive as long as at least one DataSink
|
||||
* handle is retained. The deleter function #shutdownConnection is
|
||||
* is invoked for each abandoned connection; once all connections
|
||||
* are defunct, the AllocState itself can be deconfigured.
|
||||
* handle is retained.
|
||||
*/
|
||||
template<class CON>
|
||||
class OutputSlot::AllocState
|
||||
|
|
@ -141,7 +152,8 @@ namespace out {
|
|||
void
|
||||
release() override
|
||||
{
|
||||
TODO ("propagate closing of output");
|
||||
for (Connection& con : connections_)
|
||||
con.shutDown();
|
||||
}
|
||||
|
||||
Timings
|
||||
|
|
@ -150,62 +162,54 @@ namespace out {
|
|||
UNIMPLEMENTED ("a lot regarding the Timings is still not clear..."); //////////////////////////TICKET #831
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an iterator pipeline over the #connections_,
|
||||
* where each element is a DataSink functor that uses this connection
|
||||
* to start an output cycle by locking a buffer by invoking Connection::claimBufferFor(FrameID)
|
||||
* @param lifecycleManager the ref-counting shared_ptr which controls the lifecycle of this Allocation
|
||||
* @note two statefull objects are embedded into the DataSink functor
|
||||
* - a BuffDescr preconfigured to point into this connection, using the proper buffer size
|
||||
* - the \a lifecycleManager, so that the DataSink participates in the ref-count
|
||||
*/
|
||||
OpenedSinks
|
||||
connect (PAlloc& lifecycleManager) override
|
||||
{
|
||||
auto buildDataSink = [&](CON& connection)
|
||||
{ // setup functor to lock a buffer using this output connection
|
||||
return DataSink{[bufferDescriptor = bufferProxy_.getDescriptorFor (connection)
|
||||
,lifecycleManager
|
||||
]
|
||||
(FrameID frame) mutable -> BuffHandle
|
||||
{
|
||||
return bufferDescriptor.lockBuffer (frame);
|
||||
}};
|
||||
};
|
||||
|
||||
return lib::explore (connections_)
|
||||
.transform([&](CON& connection) -> DataSink
|
||||
{ // setup the DataSink functor
|
||||
return [bufferDescriptor = bufferProxy_.getDescriptorFor (connection)
|
||||
,lifecycleManager ]
|
||||
(FrameID frame) mutable -> BuffHandle
|
||||
{
|
||||
return bufferDescriptor.lockBuffer (frame);
|
||||
};
|
||||
})
|
||||
.transform(buildDataSink)
|
||||
.asIterSource();
|
||||
}
|
||||
|
||||
|
||||
/* == Callback API for BufferProxy == */
|
||||
|
||||
|
||||
|
||||
protected: /* == API for OutputSlot-Impl == */
|
||||
|
||||
using ConnectionStorage = Connections::ElementHolder;
|
||||
|
||||
public:
|
||||
/**
|
||||
* The actual implementation of OutputSlot::buildState() needs to build
|
||||
* an AllocState<CON> instance, and has to provide a _population functor_
|
||||
* to setup the actual \a CON (Connection implementation) instances.
|
||||
* OutputSlot is built with an activated Allocation that engages a specific implementation
|
||||
* of the Connection interface. A _populator functor_ is passed, that will emplace instances
|
||||
* of this connection implementation into the provided storage, one for each expected data feed.
|
||||
* After the AllocState is created, the client will invoke OutputSlot::getOpenedSinks(), which
|
||||
* uses AllocState::connect() to configure a DataSink handle for each feed.
|
||||
* @see ScopedCollection_test::building_RAII_Style()
|
||||
* @see OutputBufferProxy::OutputBufferStore::provideBuffer()
|
||||
*/
|
||||
template<class CTOR>
|
||||
AllocState(uint numChannels, CTOR&& populator)
|
||||
: connections_(numChannels, std::forward<CTOR>(populator))
|
||||
AllocState(uint numDataFeeds, CTOR&& populator)
|
||||
: connections_(numDataFeeds, std::forward<CTOR>(populator))
|
||||
, bufferProxy_{}
|
||||
{ }
|
||||
|
||||
|
||||
private: /* === Implementation details === */
|
||||
|
||||
static DataSink
|
||||
connectOutputSink (CON& connection)
|
||||
{
|
||||
TRACE (test, "activating Con=%p", &connection );
|
||||
|
||||
// DataSink newSink;
|
||||
// newSink.activate(&connection, shutdownConnection);
|
||||
// return newSink;
|
||||
}
|
||||
|
||||
static void
|
||||
shutdownConnection (OutputSlot::Connection* toClose)
|
||||
{
|
||||
REQUIRE (toClose);
|
||||
toClose->shutDown();
|
||||
}
|
||||
|
||||
/** interface used by the populator functor to emplace connection objects */
|
||||
using ConnectionStorage = Connections::ElementHolder;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -21,18 +21,11 @@
|
|||
#include "vault/out/output-slot.hpp"
|
||||
#include "vault/out/output-slot-connection.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace vault {
|
||||
namespace out {
|
||||
namespace err = lumiera::error;
|
||||
|
||||
using std::vector;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// emit VTables here....
|
||||
OutputSlot::Allocation::~Allocation() { }
|
||||
|
|
@ -59,7 +52,6 @@ namespace out {
|
|||
delete allo;
|
||||
}};
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -87,10 +79,4 @@ namespace out {
|
|||
}
|
||||
|
||||
|
||||
|
||||
/* === DataSink frontend === */
|
||||
|
||||
|
||||
|
||||
|
||||
}} // namespace vault::out
|
||||
|
|
|
|||
|
|
@ -69,15 +69,14 @@
|
|||
|
||||
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/handle.hpp"
|
||||
#include "vault/mem/buffhandle.hpp"
|
||||
#include "vault/out/timings.hpp"
|
||||
#include "lib/iter-source.hpp"
|
||||
#include "lib/nocopy.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace vault {
|
||||
|
|
@ -171,6 +170,7 @@ namespace out {
|
|||
PAlloc alloc_;
|
||||
|
||||
class Allocation
|
||||
: util::NonCopyable
|
||||
{
|
||||
public:
|
||||
virtual ~Allocation(); ///< this is an interface
|
||||
|
|
|
|||
|
|
@ -80,13 +80,11 @@ namespace test {
|
|||
class UnimplementedConnection
|
||||
: public vault::out::OutputSlot::Connection
|
||||
{
|
||||
size_t getBufferSize() const override { UNIMPLEMENTED ("getBufferSize()"); }
|
||||
size_t getBufferSize() const override { UNIMPLEMENTED ("getBufferSize()"); }
|
||||
Buff* claimBufferFor (FrameID) override;
|
||||
bool isTimely (FrameID, TimeValue) override { return true; }
|
||||
void transfer (Buff*) override { UNIMPLEMENTED ("transfer (BuffHandle const&)"); }
|
||||
void pushout (Buff*) override { UNIMPLEMENTED ("pushout (BuffHandle const&)"); }
|
||||
void discard (Buff*) override { UNIMPLEMENTED ("discard (BuffHandle const&)"); }
|
||||
void shutDown () override { UNIMPLEMENTED ("shutDown() Connection"); }
|
||||
void publish (Buff*) override { UNIMPLEMENTED ("publish buffer content"); }
|
||||
void release (Buff*) override { UNIMPLEMENTED ("complete buffer cycle"); }
|
||||
void shutDown () override { UNIMPLEMENTED ("shutDown() Connection"); }
|
||||
|
||||
public:
|
||||
~UnimplementedConnection();
|
||||
|
|
|
|||
|
|
@ -5305,25 +5305,32 @@ And this raises another intricate question of design: //shall {{{Connection}}} b
|
|||
This would be a very elegant, and modern solution, offering much flexibility for the Implementer of said {{{Connection}}}. The {{{OutputBufferProxy}}} could be templated to that {{{Connection}}} type and thus allow the optimiser to inline and reduce the callback functionality. However -- C++ concepts are a rather new and arcane feature, as they rely on very special syntax and semantics that still requires some time in practical use to catch on and prove its viability. A further objection that can be raised is the fact that compliance to a concept leaves no traces within the implementation -- quite contrary to a classical ~OO-style interface, where the implementation is very obviously marked as such. These considerations bring me to the decision to //reject the use of a concept// here, and to rely on a conventional interface for {{{Connection}}}. Notably it can be expected that new kinds of connection will be added frequently, and so the task for a developer not familiar with all fine points of this design should be reasonably straight forward: „You have to implement the {{{Connection}}} interface“
|
||||
</pre>
|
||||
</div>
|
||||
<div title="OutputSlotImpl" modifier="Ichthyostega" created="201107102343" modified="201109232235" tags="spec operational">
|
||||
<pre>OutputSlot is an abstraction, allowing unified treatment of various physical output connections from within the render jobs. The actual output slot is a subclass object, created and managed from the "driver code" for a specific output connection. Moreover, each output slot will be outfitted with a concrete BufferProvider to reflect the actual buffer handling policy applicable for this specific output connection. Some output connections might e.g. require delivery of the media data into a buffer residing on external hardware, while others work just fine when pointed to some arbitrary memory block holding generated data.
|
||||
<div title="OutputSlotImpl" modifier="Ichthyostega" created="201107102343" modified="202603222343" tags="spec operational" changecount="5">
|
||||
<pre>OutputSlot is an abstraction, allowing unified treatment of various physical output connections from within the render jobs.
|
||||
|
||||
Each distinct output capability must be registered through an OutputManager. When a client wants to output data, it obtains a suitable OutputSlot through the OutputDirector. This OutputSlot is created and initialised properly for this single use by the {{{OutputManager}}} in charge for that kind of output capability; notably it must be outfitted with an actual implementation of the {{{OutputSlot::Allocation}}} interface, and typically {{{OutputSlot::AllocState<CON>}}} will be used for that purpose.
|
||||
So actual knowledge regarding the underlying technology is confined to the »driver code« and encapsulated as implementation of the interface {{{OutputSlot::Connection}}}. This interface is deliberately kept rather narrow, working from the assumption that »output« can be described as //hand-over of a buffer filled with data.// Furthermore, some [[timing constraints|Timings]] must be defined, to instruct the client when to deliver the data for each prospective frame. Obviously, details depend on the underlying technology. In some cases, the client might prepare several buffers full of data in advance, while for another technology, that, for example, relies on //double buffering,// the client gets only a single precisely limited time window immediately prior to each //buffer flip//.
|
||||
|
||||
The client code interacts with the output data buffer through a BuffHandle as front-end. This access scheme is similar to what is used by the generic BufferProvider within the Render Engine. To enable this setup, the OutputSlot embeds a //proxy {{{BufferProvider}}}// and uses a preconfigured buffer (type) descriptor for each connection, which also includes information about the size of the buffer. To start work on a new frame, the client invokes the {{{DataSink}}}, which actually is a functor, with a signature {{{BuffHandle(FrameID)}}}. This call delegates through the proxy {{{BufferProvider}}} ends up calling into {{{Connection::claimBufferFor(frameNr)}}}.
|
||||
|
||||
!operation steps
|
||||
[>img[Sequenz of output data exchange steps|uml/fig145157.png]]The OutputSlot class defines some standard operations as protected virtual functions. These represent the actual steps in the data exchange protocol corresponding to this output slot.
|
||||
;lock()
|
||||
:claims the specified buffer for exclusive use.
|
||||
:Client may now dispose output data
|
||||
;transfer()
|
||||
[>img[Sequenz of output data exchange steps|uml/fig145157.png]]As mentioned, the OutputSlot defines a nested ''interface {{{Connection}}}'', with standard operations defined as virtual functions. Each connection technology is expected somehow to support a sequence of actual steps in a ''data exchange protocol''.
|
||||
;claimBufferFor()
|
||||
:claims the specified buffer for exclusive use by the client.
|
||||
:Client may now generate output data into that buffer.
|
||||
;publish(buffer)
|
||||
:transfers control from the client to the actual output connection for feeding data.
|
||||
:Triggered by the client invoking {{{emit()}}}
|
||||
;pushout()
|
||||
:request the actual implementation to push the data to output.
|
||||
:Usually invoked from the {{{transfer()}}} implementation, alternatively from a separate thread.
|
||||
;release(buffer)
|
||||
:indicates that the client code will not touch the buffer henceforth.
|
||||
:effectively redundant after the client has invoked {{{emit()}}} -- but the client may choose not to do so (when it is foreseeable that the deadline can not reasonably be met); in such cases, the {{{release()}}} call is the only state indication the {{{Connection}}} implementation gets.
|
||||
:Triggered by the client invoking {{{release()}}}
|
||||
|
||||
{{red{WARNING 3/2026 this UML drawing above is outdated}}}
|
||||
|
||||
!buffer states
|
||||
While the BufferProvider abstracts away the actual access to the output buffers and just hands out a ''buffer handle'', the server side (here the concrete output slot) is allowed to associate and maintain a ''state flag'' with each buffer. The general assumption is that writing this state flag is atomic, and that other facilities will care for the necessary memory barriers (that is: the output slot and the buffer provider will just access this state flag without much ado). The generic part of the output slot implementation utilises this buffer state flag to implement a state machine, which -- together with the timing constraints established with the [[help of the scheduler|SchedulerRequirements]] -- ensures sane access to the buffer without collisions.
|
||||
| !state||>| !lock() |>| !transfer() |>| !pushout() |
|
||||
While the BufferProvider, used as front-end for the client, abstracts away the actual access to the output buffers and just hands out a [[buffer handle|BuffHandle]], the server side (which here is the concrete output slot and the backing output technology) is allowed to associate and maintain a ''state flag'' with each buffer. The general assumption is that each output cycle for a single frame originates from a single RenderJob and thus happens from a single thread; moreover, a memory barrier can be assumed prior to invoking the next job. This implies that state transitions regarding the BufferMetadata can be mapped to states as seen from the perspective of the {{{Connection}}} implementation:
|
||||
| !state||>| !claim() |>| !publish() |>| !release() |
|
||||
| {{{NIL}}}||↯| · |↯| | ↯ | |
|
||||
| {{{FREE}}}||✔|↷ locked |✔|· (ignore) | · | · |
|
||||
| {{{LOCKED}}}||↯|↷ emitted |✔|↷ emitted | · |↷ free |
|
||||
|
|
|
|||
|
|
@ -138020,7 +138020,8 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
</node>
|
||||
</node>
|
||||
<node CREATED="1773354410472" ID="ID_1743624174" MODIFIED="1773354422590" TEXT="bestehende Implementierung überprüfen">
|
||||
<node CREATED="1773366196992" ID="ID_1171528228" MODIFIED="1773366221964" TEXT="die dreistufige Vererbung ist zweifelhaft">
|
||||
<node COLOR="#5b280f" CREATED="1773366196992" FOLDED="true" ID="ID_1171528228" MODIFIED="1774223759898" TEXT="die dreistufige Vererbung ist zweifelhaft">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node CREATED="1773366223189" ID="ID_1366861589" MODIFIED="1773366246027" TEXT="Kennzeichen: mir fallen keine drei schlüssigen Klassennamen ein">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
|
|
@ -138100,7 +138101,9 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1773369169156" ID="ID_214225108" MODIFIED="1773369180790" TEXT="Verbesserungsversuch....">
|
||||
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1773369169156" ID="ID_214225108" MODIFIED="1774224646822" TEXT="Verbesserungsversuch starten....">
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1773369183338" ID="ID_1251387186" MODIFIED="1773369195156" TEXT="der PImpl könnte direkt eine Allocation halten"/>
|
||||
<node CREATED="1773369240283" ID="ID_1908925521" MODIFIED="1773369252845" TEXT="dann wäre bereits AllocState getemplated">
|
||||
<node CREATED="1773369255863" ID="ID_650591769" MODIFIED="1773369272046" TEXT="und hätte nur die Aufgabe, die einzelnen Connections zu managen"/>
|
||||
|
|
@ -138134,8 +138137,10 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<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!">
|
||||
<node BACKGROUND_COLOR="#483354" COLOR="#fee898" CREATED="1773423115479" ID="ID_1275456830" MODIFIED="1774224627641" TEXT="Probleme / Hürden / Redesign">
|
||||
<linktarget COLOR="#7c2e4f" DESTINATION="ID_1275456830" ENDARROW="Default" ENDINCLINATION="-171;377;" ID="Arrow_ID_465227693" SOURCE="ID_78273441" STARTARROW="None" STARTINCLINATION="301;22;"/>
|
||||
<font BOLD="true" NAME="SansSerif" SIZE="14"/>
|
||||
<node COLOR="#435e98" CREATED="1773423124811" ID="ID_1029911055" MODIFIED="1774224570116" TEXT="die Deallokation soll automatisch sein!">
|
||||
<icon BUILTIN="yes"/>
|
||||
<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;"/>
|
||||
|
|
@ -138161,17 +138166,93 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1774223795956" ID="ID_1349320422" MODIFIED="1774223880166" TEXT="nach Umbau wird alles über einen shared-count gesteuert">
|
||||
<linktarget COLOR="#269cc5" DESTINATION="ID_1349320422" ENDARROW="Default" ENDINCLINATION="-544;26;" ID="Arrow_ID_1535498158" SOURCE="ID_1359350896" STARTARROW="None" STARTINCLINATION="-218;26;"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1773423131415" ID="ID_1566753229" MODIFIED="1773423147739" TEXT="wer muß wen konkret getypt sehen?">
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1773423131415" ID="ID_1566753229" MODIFIED="1774223966437" TEXT="wer muß wen konkret getypt sehen?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1774223897454" ID="ID_278951543" MODIFIED="1774223927739" TEXT="hat sich auf dem Weg des Refactorings (für den Lebenszyklus) geklärt">
|
||||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1773699216800" ID="ID_49953306" MODIFIED="1773700514964" TEXT="wirft sofort das Problem auf wie man die Proxy-Callbacks implementiert">
|
||||
<node COLOR="#435e98" CREATED="1774223929315" ID="ID_1944099107" MODIFIED="1774223959282" TEXT="ist immer ein gutes Zeichen wenn sich daneben liegene Probelme ebenfalls fügen">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1774223969365" ID="ID_1782289710" MODIFIED="1774224564250" TEXT="Fazit">
|
||||
<linktarget COLOR="#2129bf" DESTINATION="ID_1782289710" ENDARROW="Default" ENDINCLINATION="-514;144;" ID="Arrow_ID_1760765205" SOURCE="ID_580276809" STARTARROW="None" STARTINCLINATION="470;-797;"/>
|
||||
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1774223981433" ID="ID_737292723" MODIFIED="1774224003908" TEXT="OutputSlot wird jetzt direkt erstellt — hier kein Sub-Typing mehr!"/>
|
||||
<node CREATED="1774224007056" ID="ID_1607982980" MODIFIED="1774224037099">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
er bekommt nur in den Konstruktor einen konkreten <font face="Monospaced" color="#6e3f3f">AllocState<CON></font>
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1774224046618" ID="ID_1967238540" MODIFIED="1774224070787">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
ab dem Punkt passiert für den OutputSlot bereits <b>Type-Erasure</b>
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1774224073211" ID="ID_1528777937" MODIFIED="1774224111715">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
die connect()-Funktion liefert eine <font face="Monospaced" color="#6b4f4f">IterSource<DataSink></font>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1774224118247" ID="ID_616159623" MODIFIED="1774224145909" TEXT="die Bindings / Verschaltung passiert opaque in einer λ-closure"/>
|
||||
<node CREATED="1774224151137" ID="ID_1221018251" MODIFIED="1774224182116" TEXT="Hier ist sichtbar">
|
||||
<node CREATED="1774224182996" ID="ID_305687317" MODIFIED="1774224210667">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
der konkrete <font color="#6e3f3f" face="Monospaced">AllocState<CON></font>
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1774224212863" ID="ID_607573548" MODIFIED="1774224226501" TEXT="der OutputBufferProxy (konkret)"/>
|
||||
<node CREATED="1774224233033" ID="ID_85951581" MODIFIED="1774224240749" TEXT="NICHT: der konkrete Connection-Typ"/>
|
||||
</node>
|
||||
<node CREATED="1774224247007" ID="ID_1819525216" MODIFIED="1774224272837">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
die <font face="Monospaced" color="#6b3e3e">Connection</font>-Implementierung bleibt <b>überall abstrakt</b>
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<node COLOR="#435e98" CREATED="1774224283050" ID="ID_539669364" MODIFIED="1774224312592" TEXT="NUR der erzeugende OutputManager kennt sie"/>
|
||||
<node BACKGROUND_COLOR="#dedaae" COLOR="#3c358a" CREATED="1774224299320" ID="ID_208057035" MODIFIED="1774224335649" TEXT="vielleicht nicht mal der ... man wird sehen">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1773699216800" ID="ID_49953306" MODIFIED="1774223687539" TEXT="wirft sofort das Problem auf wie man die Proxy-Callbacks implementiert">
|
||||
<arrowlink COLOR="#1c07d0" DESTINATION="ID_200162330" ENDARROW="Default" ENDINCLINATION="-77;817;" ID="Arrow_ID_1474651143" STARTARROW="None" STARTINCLINATION="1030;40;"/>
|
||||
<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="1774041144417" TEXT="muß BufferProxyAdaptor in OutputSlot::AllocState integrieren" VSHIFT="33">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1773703618287" HGAP="62" ID="ID_914494536" MODIFIED="1774223609209" TEXT="muß BufferProxyAdaptor in OutputSlot::AllocState integrieren" VSHIFT="33">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1773703751137" ID="ID_340628735" MODIFIED="1773703998020" TEXT="Überlegung am Rande: längerfristig wollen wir einen globalen Metadaten-Store">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
|
|
@ -138183,7 +138264,8 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
</html></richcontent>
|
||||
<arrowlink COLOR="#76516c" DESTINATION="ID_1415408255" ENDARROW="Default" ENDINCLINATION="779;39;" ID="Arrow_ID_1408352744" STARTARROW="None" STARTINCLINATION="468;17;"/>
|
||||
</node>
|
||||
<node CREATED="1773704083017" ID="ID_446456909" MODIFIED="1773704096521" TEXT="Anordnung und Zugriffe sind problematisch in der bestehenden Architektur">
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1773704083017" FOLDED="true" ID="ID_446456909" MODIFIED="1774223593951" TEXT="Anordnung und Zugriffe sind problematisch in der bestehenden Architektur">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node CREATED="1773704097997" ID="ID_1516975322" MODIFIED="1773704108791" TEXT="man will nur einen einzigen BufferProxyAdaptor"/>
|
||||
<node CREATED="1773704125817" ID="ID_1780250199" MODIFIED="1773704161930" TEXT="aber die »Typ«-Einträge werden in der Connection konfiguriert"/>
|
||||
<node CREATED="1773704176910" ID="ID_1110317988" MODIFIED="1773704206640">
|
||||
|
|
@ -138213,7 +138295,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
<node CREATED="1773704486520" ID="ID_1324797839" MODIFIED="1773704500571" TEXT="sie haben nur den Buffer-Ptr, nicht die dazugehörige Connection"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1773797100647" ID="ID_425446315" MODIFIED="1773888697408" TEXT="Überlegung: wie könnt man das Problem überhaupt »knacken«">
|
||||
<node COLOR="#435e98" CREATED="1773797100647" FOLDED="true" ID="ID_425446315" MODIFIED="1774223579568" TEXT="Überlegung: wie könnt man das Problem überhaupt »knacken«">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1773797120055" ID="ID_1455782398" MODIFIED="1773797126986" TEXT="mit Gewalt?">
|
||||
<node CREATED="1773797138856" ID="ID_1366418982" MODIFIED="1773797219006" TEXT="jede DataSink bekommt auch einen Basis-Descriptor(⟼backlink)"/>
|
||||
|
|
@ -138312,8 +138394,8 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
<node CREATED="1773888426603" ID="ID_888618711" MODIFIED="1773888441501" TEXT="diese enhält einen »delegating-BufferStore«"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1773888677730" ID="ID_370790574" MODIFIED="1773888690633" TEXT="dieses neue Verschaltungs-Konzept implementieren">
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
<node COLOR="#338800" CREATED="1773888677730" ID="ID_370790574" MODIFIED="1774219474051" TEXT="dieses neue Verschaltungs-Konzept implementieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1773888784963" ID="ID_1753071442" MODIFIED="1773888798826" TEXT="Struktur eines Proxy-BufferProvider anlegen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1773888800028" ID="ID_756667017" MODIFIED="1773888814028" TEXT="geht ganz einfach: von BufferProxyAdapter ausgehen"/>
|
||||
|
|
@ -138325,8 +138407,9 @@ 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 COLOR="#338800" CREATED="1773934250649" ID="ID_1023733837" MODIFIED="1774219522013" TEXT="Umstellen der DataSink">
|
||||
<arrowlink COLOR="#2f56b3" DESTINATION="ID_848279587" ENDARROW="Default" ENDINCLINATION="-42;-865;" ID="Arrow_ID_998347051" STARTARROW="Default" STARTINCLINATION="-663;70;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<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«"/>
|
||||
|
|
@ -138411,7 +138494,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1774041166497" ID="ID_1405169811" MODIFIED="1774041789004" TEXT="Design nochmal überdenken">
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1774041166497" ID="ID_1405169811" MODIFIED="1774219476741" 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....">
|
||||
|
|
@ -138468,11 +138551,16 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
<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 BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1774223553705" ID="ID_1056437663" MODIFIED="1774223564933" TEXT="fühlt sich jetzt alles viel besser an">
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
</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>
|
||||
<node COLOR="#435e98" CREATED="1773954149241" ID="ID_203883845" MODIFIED="1774219466189" TEXT="Allocation / Lebenszyklus in den Griff bekommen">
|
||||
<arrowlink COLOR="#4236b1" DESTINATION="ID_671153651" ENDARROW="Default" ENDINCLINATION="-3;-427;" ID="Arrow_ID_1331623727" STARTARROW="Default" STARTINCLINATION="-756;0;"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
<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="1774116830612" TEXT="Problem: diesen erzeugen und verdrahten">
|
||||
<node COLOR="#435e98" CREATED="1773973038119" ID="ID_322920487" MODIFIED="1774219483768" TEXT="Problem: diesen erzeugen und verdrahten">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node CREATED="1773973059692" ID="ID_1788170271" MODIFIED="1773973087364" TEXT="muß eine Deleter-Funktion einbinden"/>
|
||||
<node BACKGROUND_COLOR="#e5cca9" COLOR="#a50167" CREATED="1773973088177" ID="ID_534312365" MODIFIED="1774116812214" TEXT="muß aber diesen Pointer auch im AllocState selber zugänglich machen">
|
||||
|
|
@ -138492,7 +138580,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
<node COLOR="#5b280f" CREATED="1774041751196" ID="ID_1946395022" MODIFIED="1774116705999" TEXT="nun könnte man eine Factory bauen, und ein leere Handle überall hin durchschieben">
|
||||
<icon BUILTIN="stop-sign"/>
|
||||
</node>
|
||||
<node CREATED="1774041103709" ID="ID_1695581190" MODIFIED="1774041789004" TEXT="das ist alles so kompliziert ⟹ etwas mit dem Design stimmt nicht">
|
||||
<node COLOR="#b1000c" CREATED="1774041103709" ID="ID_1695581190" MODIFIED="1774223544563" 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>
|
||||
|
|
@ -138514,7 +138602,8 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
<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 CREATED="1774117870539" ID="ID_160673186" MODIFIED="1774117879102" TEXT="Callbacks für das Buffer-Handling einfädeln">
|
||||
<node COLOR="#338800" CREATED="1774117870539" ID="ID_160673186" MODIFIED="1774219444172" TEXT="Callbacks für das Buffer-Handling einfädeln">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1774117886873" ID="ID_1363452049" MODIFIED="1774117892476" TEXT="der Funktor in DataSink">
|
||||
<node CREATED="1774117905798" ID="ID_3491981" MODIFIED="1774119797698" TEXT="verwendet einen Slave-shared-ptr">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
|
|
@ -138551,7 +138640,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
</node>
|
||||
<node CREATED="1774122219137" ID="ID_656953886" MODIFIED="1774122240553" TEXT="⟹ alle weiteren Protokollschritte erfolgen direkt von dort"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1774122365597" ID="ID_292817548" MODIFIED="1774131392789" TEXT="Abwägung: wohin delegieren die Proxy-Callbacks?">
|
||||
<node COLOR="#435e98" CREATED="1774122365597" FOLDED="true" ID="ID_292817548" MODIFIED="1774131392789" TEXT="Abwägung: wohin delegieren die Proxy-Callbacks?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1774122388349" ID="ID_1459974960" MODIFIED="1774122391728" TEXT="möglich wäre...">
|
||||
<node CREATED="1774122410671" ID="ID_1178347692" MODIFIED="1774124507440" TEXT="an eine Connection (Interface)">
|
||||
|
|
@ -138661,13 +138750,11 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1774124656373" ID="ID_1252354115" MODIFIED="1774127022008" TEXT="also binden in die Funktor-Closure">
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1774124656373" ID="ID_1252354115" MODIFIED="1774219424401" TEXT="also binden in die Funktor-Closure">
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1774124694439" ID="ID_775305943" MODIFIED="1774197102402">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
ein shared-ptr <strike>mit <font color="#673c22">Alias auf die jeweilige Connection</font></strike>
|
||||
|
|
@ -138718,7 +138805,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
<node CREATED="1774126881885" ID="ID_899991315" MODIFIED="1774197139349" TEXT="der Proxy-BufferProvider (⟶ implizit im Buffer-Descriptor)"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1774132649643" ID="ID_1759796259" MODIFIED="1774190645402" TEXT="Problem übersehen: die Frame-Nummer">
|
||||
<node COLOR="#435e98" CREATED="1774132649643" FOLDED="true" ID="ID_1759796259" MODIFIED="1774190645402" TEXT="Problem übersehen: die Frame-Nummer">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1774132731585" ID="ID_396286799" MODIFIED="1774190638918">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
|
|
@ -138820,11 +138907,26 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
</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;"/>
|
||||
<node COLOR="#338800" CREATED="1774223630666" ID="ID_654626526" MODIFIED="1774223674292" TEXT="ist jetzt implementiert ...">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1774223648227" ID="ID_1705010271" MODIFIED="1774223676743" TEXT="sieht gut aus...."/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1774223652431" ID="ID_1340307534" MODIFIED="1774223668700">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
aber wurde <b>noch nie irgendwo verwendet</b>
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1773935662405" ID="ID_921042105" MODIFIED="1773954217403" TEXT="ehrlich gesagt: diese Aufgabe war bisher gar nicht richtig gelöst">
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1773935649392" ID="ID_671153651" MODIFIED="1774223505859" TEXT="Steuern des Allocation-Lebenszyklus">
|
||||
<linktarget COLOR="#4236b1" 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="1774223839010" TEXT="ehrlich gesagt: diese Aufgabe war bisher gar nicht richtig gelöst">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
|
|
@ -138835,7 +138937,8 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
</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="1773936076352" FOLDED="true" ID="ID_1795427929" MODIFIED="1774223469372" TEXT="mögliche Alternativen">
|
||||
<icon BUILTIN="list"/>
|
||||
<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«">
|
||||
|
|
@ -138938,7 +139041,8 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1773957264534" ID="ID_969840903" MODIFIED="1773957275425" TEXT="Kontext für die Entscheidung">
|
||||
<node CREATED="1773957264534" FOLDED="true" ID="ID_969840903" MODIFIED="1774223474330" TEXT="Kontext für die Entscheidung">
|
||||
<icon BUILTIN="info"/>
|
||||
<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"/>
|
||||
|
|
@ -138996,7 +139100,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
<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">
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1773969731041" FOLDED="true" ID="ID_1083742526" MODIFIED="1774223480927" 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"/>
|
||||
|
|
@ -139033,6 +139137,10 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
<icon BUILTIN="bell"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#008860" CREATED="1774223482742" ID="ID_1359350896" MODIFIED="1774223880166" TEXT="(scheint bisher aufzugehen)">
|
||||
<arrowlink COLOR="#269cc5" DESTINATION="ID_1349320422" ENDARROW="Default" ENDINCLINATION="-544;26;" ID="Arrow_ID_1535498158" STARTARROW="None" STARTINCLINATION="-218;26;"/>
|
||||
<font NAME="SansSerif" SIZE="10"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1773456815562" ID="ID_1123444875" MODIFIED="1773589752521" TEXT="Doku">
|
||||
|
|
@ -139060,7 +139168,44 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
<icon BUILTIN="smiley-angry"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1774223250995" ID="ID_1704442443" MODIFIED="1774223271232" TEXT="Nach Refactoring nochmal komplett zu überarbeiten">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node CREATED="1774223280705" ID="ID_235268548" MODIFIED="1774223287071" TEXT="tja">
|
||||
<icon BUILTIN="smily_bad"/>
|
||||
</node>
|
||||
<node CREATED="1774223288608" ID="ID_1829993438" MODIFIED="1774223305353">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
dabei bleibt die <i>konzeptionelle</i> Struktur gleich
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1774223306438" ID="ID_1996401851" MODIFIED="1774223427932" TEXT="das zeigt erneut die Grenzen von UML auf">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
UML ist in vielerlei hinsicht <i>zu konkret</i> — letztlich beruht es auf dem Traum, daß man nur eine Spezifikation schafft, die „sich dann von selbst implementiert“ ... das ist ja sooo 70ies .... heute soll sich die „AI“ gleich auch noch die Anforderungen für uns ausdenken, und natürlich auch implementieren und die Tests organisieren
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1774223704747" ID="ID_638158996" MODIFIED="1774223726691" TEXT="zur Bewährung: muß nun den DiagnosticOutputSlot neu implementieren">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1774224369655" ID="ID_78273441" MODIFIED="1774224586895" TEXT="das ist jetzt ein Re-Design geworden">
|
||||
<arrowlink COLOR="#7c2e4f" DESTINATION="ID_1275456830" ENDARROW="Default" ENDINCLINATION="-171;377;" ID="Arrow_ID_465227693" STARTARROW="None" STARTINCLINATION="301;22;"/>
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
<node COLOR="#574398" CREATED="1774224680125" HGAP="29" ID="ID_1120744588" MODIFIED="1774224701191" TEXT="(finde das Ergebnis richtig schön)" VSHIFT="30">
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="11"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -139069,10 +139214,12 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
<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">
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1773943137275" ID="ID_848279587" MODIFIED="1774219532157" TEXT="sehe DataSink als kritischen Verknüpfungspunkt">
|
||||
<linktarget COLOR="#2f56b3" DESTINATION="ID_848279587" ENDARROW="Default" ENDINCLINATION="-42;-865;" ID="Arrow_ID_998347051" SOURCE="ID_1023733837" STARTARROW="Default" STARTINCLINATION="-663;70;"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1773940626128" ID="ID_1007087496" MODIFIED="1774223239553" 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;"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</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;"/>
|
||||
|
|
@ -139082,6 +139229,11 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
<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 BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1774224466595" ID="ID_580276809" MODIFIED="1774224564250" STYLE="fork" TEXT="dadurch ist eine sehr schöne Typ/Sichtbarkeits-Hierarchie entstanden">
|
||||
<edge COLOR="#808080" STYLE="bezier" WIDTH="thin"/>
|
||||
<arrowlink COLOR="#2129bf" DESTINATION="ID_1782289710" ENDARROW="Default" ENDINCLINATION="-514;144;" ID="Arrow_ID_1760765205" STARTARROW="None" STARTINCLINATION="470;-797;"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1681347244544" ID="ID_444443795" MODIFIED="1681347486789" TEXT="Basis: Operational Control">
|
||||
|
|
|
|||
Loading…
Reference in a new issue