OutputSlot: validate and complete redesign (see #1395)
''This is a breakthrough...'' Using the realigned implementation structure in `BufferProvider`, and especially the ability to establish an overarching context by passing an connection-ID through the `LocalTag` in the `BufferMetadata`, it was possible to resolve the longstanding mismatch buried deep within the `OutputSlot` implementation. Based on the new internal APIs in `BufferProvider`, it was thus possible to setup an `OututBufferProxy` that acts as a hub to connect the `DataSink` handles with the actual `OutputSlot::Connection` implementation. This change allowed to rectify the convoluted control structure in `OutputSlot` and finally to manage the Lifecycle properly. Furthermore, one level of unnecessary implementation-inheritance could be removed, so that it is no longer necessary to subclass `OutputSlot` in order to configure the link to a specific output backend. Using this redesigned internal structure, it was now fairly simple to re-implement a tracking `DiagnosticOutputSlot` and then to verify proper integration by passing the `OutputSlotProtocol_test` again.
This commit is contained in:
parent
a0d83b4fe8
commit
2c8ee05a23
9 changed files with 7644 additions and 5279 deletions
File diff suppressed because it is too large
Load diff
|
Before Width: | Height: | Size: 199 KiB After Width: | Height: | Size: 231 KiB |
|
|
@ -144,7 +144,7 @@ namespace meta{
|
|||
};
|
||||
|
||||
/** allow the Unit test to poke into internals */
|
||||
friend class FunInline_test;
|
||||
friend class test::FunInline_test;
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -14,20 +14,49 @@
|
|||
|
||||
/** @file diagnostic-output-slot.cpp
|
||||
** Internal implementation parts of a state-tracking dummy implementation
|
||||
** of the OutputSlot interface and framework.
|
||||
** of the OutputSlot interface and framework. This setup uses the standard
|
||||
** base implementation of OutputSlot and layers a diagnostic context on
|
||||
** top, using a _PImpl_ — which in this case is a shared-ptr to a heap
|
||||
** allocated OutputTracker object. Furthermore, the basic OutputSlot
|
||||
** was configured at construction time to create instances of
|
||||
** DummyConnection, which are wired internally to the OutputTracker.
|
||||
** When the client invokes one of the DataSink handles with a frame number,
|
||||
** this call is propagated through the default implementation of OutputSlot
|
||||
** and ends up as invocation of OutputSlot::Connection::claimBufferFor(FrameID).
|
||||
** The DummyConnection implements this call by retrieving a new buffer from the
|
||||
** default BufferProvider (which is always a Test setup, since the real Render
|
||||
** Engine uses a specifically configured BufferProvider, injected through the
|
||||
** steam::engine::EngineCtx). Notably, this (default) test implementation of
|
||||
** the BufferProvider framework will actually never discard any allocated
|
||||
** memory — which is an essential prerequisite for this DiagnosticOutputSlot
|
||||
** implementation, insofar it allows to access the buffer memory even after
|
||||
** it has been released, officially.
|
||||
**
|
||||
** The OutputTracker establishes a vault::out::diagn::FrameInfo record for each
|
||||
** distinct frame number encountered on each activated output feed. In this
|
||||
** diagnostic record, a timestamp is recorded for each of the three lifecycle
|
||||
** steps (lock, emit, release), together with the size and the actual memory
|
||||
** address of the data buffer handed out to the client. The OutputDiagnostic
|
||||
** wrapper adds some convenience access functions, allowing to query if (and when)
|
||||
** a frame went through some lifecycle step, and to traverse all recorded
|
||||
** FrameInfo records for each data feed.
|
||||
** @note \ref OutputSlotProtocol_test::verifyStandardCase() uses this setup
|
||||
** to walk through the standard stages of the _»Output Slot Protocol«_,
|
||||
** which also validates the default implementation of OutputSlot::AllocState.
|
||||
*/
|
||||
|
||||
|
||||
#include "lib/integral.hpp"
|
||||
#include "lib/nocopy.hpp"
|
||||
#include "vault/out/diagnostic-output-slot.hpp"
|
||||
//#include "vault/out/output-slot-connection.hpp"
|
||||
#include "vault/mem/buffhandle.hpp"
|
||||
#include "vault/out/output-slot-connection.hpp"
|
||||
#include "vault/mem/naive-buffer-setup.hpp"
|
||||
#include "vault/mem/buffhandle.hpp"
|
||||
#include "vault/real-clock.hpp"
|
||||
#include "lib/iter-explorer.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
//#include <vector>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
|
@ -36,8 +65,7 @@
|
|||
|
||||
using util::contains;
|
||||
using util::isSameAdr;
|
||||
// using std::vector;
|
||||
// using Config = DiagnosticOutputSlot::Config;
|
||||
using std::vector;
|
||||
using std::byte;
|
||||
using std::move;
|
||||
using std::make_unique;
|
||||
|
|
@ -62,6 +90,11 @@ namespace out {
|
|||
}
|
||||
}//(End)Impl details
|
||||
|
||||
|
||||
/**
|
||||
* @internal the diagnostic tracking PImpl
|
||||
* @remark this defines the _actual identity_ of an DiagnostricOutputSlot
|
||||
* and is also the place where all observed data is collected */
|
||||
class DiagnosticOutputSlot::OutputTracker
|
||||
: public Config
|
||||
, util::NonCopyable
|
||||
|
|
@ -95,13 +128,6 @@ namespace out {
|
|||
return bufferType_.lockBuffer();
|
||||
}
|
||||
|
||||
diagn::FeedLog const&
|
||||
getFeed (uint feedNr)
|
||||
{
|
||||
REQUIRE (feedNr < feed_.size());
|
||||
return feed_[feedNr];
|
||||
}
|
||||
|
||||
void
|
||||
recordClaim (uint feedNr, FrameID frame, Buff* buff)
|
||||
{
|
||||
|
|
@ -126,6 +152,25 @@ namespace out {
|
|||
REQUIRE (isSameAdr(frameInfo.storage, buff));
|
||||
frameInfo.released = currentTime();
|
||||
}
|
||||
|
||||
|
||||
/* ===== diagnostic functions ===== */
|
||||
|
||||
/** skim through all recorded FrameInfo, over all feeds */
|
||||
auto
|
||||
allBlocks() const
|
||||
{
|
||||
return lib::explore(feed_)
|
||||
.transform([](diagn::FeedLog const& feedLog){ return feedLog.allRecordedBlocks(); })
|
||||
.flatten();
|
||||
}
|
||||
|
||||
diagn::FeedLog const&
|
||||
getFeed (uint feedNr) const
|
||||
{
|
||||
REQUIRE (feedNr < feed_.size());
|
||||
return feed_[feedNr];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -141,8 +186,44 @@ namespace out {
|
|||
return lib::NullValue<diagn::FeedLog>::get();
|
||||
}
|
||||
|
||||
uint
|
||||
OutputDiagnostic::cntLocked()
|
||||
{
|
||||
return dos_.tracker_->allBlocks()
|
||||
.filter([](diagn::FrameInfo const& frame){ return frame.wasLocked(); })
|
||||
.count();
|
||||
}
|
||||
|
||||
uint
|
||||
OutputDiagnostic::cntEmitted()
|
||||
{
|
||||
return dos_.tracker_->allBlocks()
|
||||
.filter([](diagn::FrameInfo const& frame){ return frame.wasEmitted(); })
|
||||
.count();
|
||||
}
|
||||
|
||||
uint
|
||||
OutputDiagnostic::cntReleased()
|
||||
{
|
||||
return dos_.tracker_->allBlocks()
|
||||
.filter([](diagn::FrameInfo const& frame){ return frame.wasReleased(); })
|
||||
.count();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* An instrumented dummy data output connection.
|
||||
* By default, it supports an unlimited number of frames
|
||||
* and exposes a new buffer for each different frame requested.
|
||||
* @remark the implementation uses an index table to detect if
|
||||
* buffer memory address passed back from the client
|
||||
* was actually a buffer handed out by this connection,
|
||||
* and to retrieve the associated BuffHandle that was used
|
||||
* to get this buffer from a backing memory manager.
|
||||
*/
|
||||
class DiagnosticOutputSlot::DummyConnection
|
||||
: public OutputSlot::Connection
|
||||
{
|
||||
|
|
@ -200,7 +281,6 @@ namespace out {
|
|||
}
|
||||
|
||||
|
||||
|
||||
public:
|
||||
DummyConnection (OutputTracker& tracker, uint thisFeed)
|
||||
: tracker_{tracker}
|
||||
|
|
@ -210,6 +290,7 @@ namespace out {
|
|||
|
||||
|
||||
|
||||
|
||||
DiagnosticOutputSlot::~DiagnosticOutputSlot() { } // emit destructors for hidden implementation here....
|
||||
|
||||
DiagnosticOutputSlot::DiagnosticOutputSlot (Config config)
|
||||
|
|
@ -230,13 +311,19 @@ namespace out {
|
|||
* so that this contradiction can be circumvented by constructing it first, as a constructor
|
||||
* argument \a trackingSetup prepared through a chained constructor call. It is thus visible
|
||||
* in the complete scope of the constructor, so that we can pass it to the base class
|
||||
* constructor, and later then move it into the final location in the derived class.
|
||||
* constructor, and later then move it into the final location in the derived class.
|
||||
*
|
||||
* @note \ref setupTrackingConnections performs that kind of wiring,
|
||||
* that usually would be done within an OutputManager: it prepares a set of
|
||||
* OutputSlot::Connection objects, which however are implemented as DummyConnection here,
|
||||
* and back-wired internally to the OututTracker, so that it is possible to verify
|
||||
* the invocations that actually happened while using the DiagnosticOutputSlot.
|
||||
*/
|
||||
DiagnosticOutputSlot::DiagnosticOutputSlot (shared_ptr<OutputTracker> trackingSetup)
|
||||
: OutputSlot{setupTrackingConnections (*trackingSetup)}
|
||||
, tracker_{move(trackingSetup)}
|
||||
{ }
|
||||
|
||||
|
||||
shared_ptr<DiagnosticOutputSlot::OutputTracker>
|
||||
DiagnosticOutputSlot::setupOutputTracker (Config&& config)
|
||||
{
|
||||
|
|
@ -251,9 +338,20 @@ namespace out {
|
|||
|
||||
return make_unique<AllocState> (outputTracker.numDataFeeds
|
||||
,[&,i=0](ConStorage& storage) mutable { storage.create<DummyConnection> (outputTracker, i++); }
|
||||
);
|
||||
); // a »population functor« that creates a sequence of DummyConnections
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param timePoint reference to a "current" time point,
|
||||
* that can be manipulated from the test setup.
|
||||
*/
|
||||
void
|
||||
DiagnosticOutputSlot::fixCurrentTime (TimeVar const& timePoint)
|
||||
{
|
||||
REQUIRE (tracker_);
|
||||
tracker_->currentTime = [&timePoint] ->Time { return timePoint; };
|
||||
}
|
||||
|
||||
|
||||
}} // namespace vault::out
|
||||
|
|
|
|||
|
|
@ -13,8 +13,33 @@
|
|||
|
||||
/** @file diagnostic-output-slot.hpp
|
||||
** An facility for writing unit-tests against the OutputSlot interface.
|
||||
**
|
||||
** The setup of DiagnosticOutputSlot is layered, insofar it is foremost
|
||||
** a regular OutputSlot, yet has some kind of special _Output Manager_
|
||||
** layered on top. For context, in regular use, it is the task of some
|
||||
** specialised OutputManager to provide a suitably configured OutputSlot
|
||||
** so that the client can use a specific output facility, like e.g. a
|
||||
** video viewer in the UI, or the sound card output. Yet since this is
|
||||
** a test setup, DiagnosticOutputSlot is backed by a _fake implementation_
|
||||
** of the OutputSlot::Connection interface.
|
||||
**
|
||||
** This layered construction allows for a simple and straight-forward
|
||||
** usage, where the test can just create a DiagnosticOutputSlot instance,
|
||||
** possibly passing a configuration record. This is in contrast to the
|
||||
** real usage, where, as pointed out above, the OutputSlot must be
|
||||
** maintained and connected to a real output driver by the OutputManager.
|
||||
** By default, a configurable number of DataSink handles can be retrieved
|
||||
** from this setup, and each sink allows to allocate an unlimited number
|
||||
** of different frame buffers, in any order. Furthermore, the OutputSlot
|
||||
** can be copied (and thereby sliced) and passed to the code to be tested.
|
||||
** @todo 4/2026 the plan is to add the ability to define constraints and
|
||||
** limitations through the configuration passed at construction.
|
||||
**
|
||||
** After invoking the code under test, it is necessary to hold onto
|
||||
** one copy of DiagnostricOutputSlot, which maintains the internal
|
||||
** connection to the diagnostic information collected. Using the
|
||||
** `watch(slot)` syntax, this information can be investigated.
|
||||
** @see output-slot-protocol-test.cpp
|
||||
** @see output-slot.hpp
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -24,23 +49,14 @@
|
|||
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/nocopy.hpp"
|
||||
#include "include/logging.h"
|
||||
#include "vault/out/output-slot.hpp"
|
||||
#include "vault/out/output-slot-connection.hpp"
|
||||
#include "vault/mem/buffhandle.hpp"
|
||||
#include "vault/mem/naive-buffer-setup.hpp"
|
||||
#include "lib/time/timevalue.hpp"
|
||||
#include "lib/time/grid.hpp"
|
||||
#include "lib/p.hpp"
|
||||
#include "lib/null-value.hpp"
|
||||
#include "lib/iter-explorer.hpp"
|
||||
#include "lib/iter-source.hpp" /////////////OOO wech
|
||||
#include "lib/symbol.hpp"
|
||||
#include "lib/util.hpp"
|
||||
#include "vessel/advice.hpp"
|
||||
#include "test/test-frame.hpp"
|
||||
#include "lib/time/timevalue.hpp"
|
||||
#include "lib/iter-adapter-stl.hpp"
|
||||
#include "lib/iter-explorer.hpp"
|
||||
#include "lib/null-value.hpp"
|
||||
|
||||
#include "vault/out/output-slot.hpp"
|
||||
|
||||
#include <unordered_set>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
|
@ -50,24 +66,14 @@ namespace vault {
|
|||
namespace out {
|
||||
namespace err = lumiera::error;
|
||||
|
||||
using lib::Symbol;
|
||||
using lib::HashVal;
|
||||
using util::unConst;
|
||||
using util::contains;
|
||||
using test::TestFrame;
|
||||
using lib::time::FrameRate;
|
||||
//using lib::time::FrameRate; ///////TODO planned for time restrictions
|
||||
using lib::time::TimeVar;
|
||||
using lib::time::Time;
|
||||
using vault::mem::NaiveBufferSetup;
|
||||
using vault::mem::BuffHandle;
|
||||
using vault::mem::BuffDescr;
|
||||
|
||||
using std::as_const;
|
||||
using std::shared_ptr;
|
||||
using std::make_unique;
|
||||
|
||||
using PGrid = lib::P<lib::time::Grid>;
|
||||
|
||||
|
||||
namespace { // diagnostics & internals....
|
||||
|
||||
|
|
@ -79,6 +85,7 @@ namespace out {
|
|||
namespace diagn {
|
||||
using Buff = vault::mem::Buff;
|
||||
|
||||
/** diagnostic record from handling one data frame */
|
||||
struct FrameInfo
|
||||
{
|
||||
TimeVar locked{Time::NEVER};
|
||||
|
|
@ -86,8 +93,8 @@ namespace out {
|
|||
TimeVar released{Time::NEVER};
|
||||
|
||||
bool wasLocked() const { return locked != Time::NEVER; }
|
||||
bool wasEmitted() const { return locked != Time::NEVER; }
|
||||
bool wasReleased() const { return locked != Time::NEVER; }
|
||||
bool wasEmitted() const { return emitted != Time::NEVER; }
|
||||
bool wasReleased() const { return released != Time::NEVER; }
|
||||
|
||||
size_t buffSize{0};
|
||||
Buff* storage{nullptr};
|
||||
|
|
@ -100,6 +107,7 @@ namespace out {
|
|||
bool operator== (BU const&) const;
|
||||
};
|
||||
|
||||
/** diagnostic record of handled frames _in a single feed_ */
|
||||
struct FeedLog
|
||||
{
|
||||
std::map<uint, FrameInfo> recorded;
|
||||
|
|
@ -115,12 +123,18 @@ namespace out {
|
|||
}
|
||||
|
||||
auto
|
||||
blockIter(uint startFrame =0) const
|
||||
allBlocks(uint startFrame =0) const
|
||||
{
|
||||
return lib::explore (lib::NumIter{startFrame, std::numeric_limits<uint>::max()})
|
||||
.transform([this](uint idx){ return frame(idx); })
|
||||
;
|
||||
}
|
||||
|
||||
auto
|
||||
allRecordedBlocks() const
|
||||
{
|
||||
return lib::iter_stl::eachVal (recorded);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BU>
|
||||
|
|
@ -189,6 +203,14 @@ namespace out {
|
|||
static constexpr Config defaults() { return {}; }
|
||||
};
|
||||
|
||||
/** set the _running current time_ to be fixed to the given value.
|
||||
* @remark by default, without calling this function, each tracked invocation
|
||||
* is marked by the current system time; by calling this function
|
||||
* however, instead of a running time, fixed step stones will be
|
||||
* recorded, so that the test can basically define the time axis.
|
||||
*/
|
||||
void fixCurrentTime (TimeVar const&);
|
||||
|
||||
/**
|
||||
* Official (default) constructor to create a DiagnosticOutputSlot.
|
||||
* When invoked without argument, the default Config applies, otherwise
|
||||
|
|
@ -228,17 +250,17 @@ namespace out {
|
|||
: dos_{theSlot}
|
||||
{ }
|
||||
|
||||
uint cntLocked() { return 0; }
|
||||
uint cntEmitted() { return 0; }
|
||||
uint cntReleased() { return 0; }
|
||||
uint cntLocked();
|
||||
uint cntEmitted();
|
||||
uint cntReleased();
|
||||
|
||||
diagn::FeedLog const&
|
||||
feed (uint feedNr);
|
||||
|
||||
auto
|
||||
getFeed (uint feedNr)
|
||||
getFeed (uint feedNr, uint startFrame =0)
|
||||
{
|
||||
return feed(feedNr).blockIter();
|
||||
return feed(feedNr).allBlocks(startFrame);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@
|
|||
** 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. 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
|
||||
** is provided, configured and registered with an OutputManager, using a suitable implementation
|
||||
** for the kind of media data to be sent (sound, video), and also suitable for the desired kind of
|
||||
** 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
|
||||
|
|
@ -160,6 +160,7 @@ namespace out {
|
|||
|
||||
|
||||
protected:
|
||||
|
||||
/** @internal interface for the allocated state */
|
||||
class Allocation;
|
||||
using PAlloc = std::shared_ptr<Allocation>;
|
||||
|
|
|
|||
|
|
@ -20,12 +20,15 @@
|
|||
|
||||
#include "vault/out/diagnostic-output-slot.hpp"
|
||||
#include "vault/mem/buffhandle.hpp"
|
||||
#include "vault/real-clock.hpp"
|
||||
#include "test/test-frame.hpp"
|
||||
|
||||
|
||||
using test::TestFrame;
|
||||
using test::testData;
|
||||
using vault::RealClock;
|
||||
using vault::mem::BuffHandle;
|
||||
using lib::time::FSecs;
|
||||
|
||||
namespace vault{
|
||||
namespace out {
|
||||
|
|
@ -68,25 +71,34 @@ namespace test {
|
|||
DataSink sink0 = *sinks;
|
||||
DataSink sink1 = *++sinks;
|
||||
|
||||
// some test markers....
|
||||
const FrameCnt START = 123;
|
||||
TimeVar testTime = Time::ZERO;
|
||||
oSlot.fixCurrentTime(testTime);
|
||||
auto markTime = [&]{ return Time( testTime += FSecs(1) ); };
|
||||
|
||||
// within the frame-calculation "loop"
|
||||
// we perform a data exchange cycle
|
||||
FrameCnt frameNr = 123;
|
||||
BuffHandle buff00 = sink0(frameNr);
|
||||
BuffHandle buff10 = sink1(frameNr);
|
||||
auto MARK_0 = markTime();
|
||||
BuffHandle buff00 = sink0(START);
|
||||
BuffHandle buff10 = sink1(START);
|
||||
|
||||
// rendering process calculates content....
|
||||
buff00.emplace<TestFrame> (testData(0,0));
|
||||
|
||||
// while further frames might be processed in parallel
|
||||
BuffHandle buff11 = sink1(frameNr+1);
|
||||
auto MARK_1 = markTime();
|
||||
BuffHandle buff11 = sink1(START+1);
|
||||
buff11.emplace<TestFrame> (testData(1,1));
|
||||
buff10.emplace<TestFrame> (testData(1,0));
|
||||
|
||||
// Now it's time to emit the output
|
||||
auto MARK_2 = markTime();
|
||||
buff11.emit();
|
||||
buff00.emit();
|
||||
|
||||
// Buffers must be marked as released when done
|
||||
auto MARK_3 = markTime();
|
||||
buff00.release();
|
||||
buff10.release();
|
||||
buff11.release();
|
||||
|
|
@ -97,32 +109,49 @@ namespace test {
|
|||
CHECK (watch(oSlot).cntEmitted() == 2);
|
||||
CHECK (watch(oSlot).cntReleased() == 3);
|
||||
|
||||
CHECK ( watch(oSlot).feed(0).frame(123).wasLocked());
|
||||
CHECK (not watch(oSlot).feed(0).frame(124).wasLocked());
|
||||
CHECK ( watch(oSlot).feed(1).frame(123).wasLocked());
|
||||
CHECK ( watch(oSlot).feed(1).frame(124).wasLocked());
|
||||
CHECK ( watch(oSlot).feed(0).frame(START ).wasLocked());
|
||||
CHECK (not watch(oSlot).feed(0).frame(START+1).wasLocked());
|
||||
CHECK ( watch(oSlot).feed(1).frame(START ).wasLocked());
|
||||
CHECK ( watch(oSlot).feed(1).frame(START+1).wasLocked());
|
||||
|
||||
CHECK ( watch(oSlot).feed(0).frame(123).wasEmitted());
|
||||
CHECK (not watch(oSlot).feed(0).frame(124).wasEmitted());
|
||||
CHECK (not watch(oSlot).feed(1).frame(123).wasEmitted());
|
||||
CHECK ( watch(oSlot).feed(1).frame(124).wasEmitted());
|
||||
CHECK ( watch(oSlot).feed(0).frame(START ).wasEmitted());
|
||||
CHECK (not watch(oSlot).feed(0).frame(START+1).wasEmitted());
|
||||
CHECK (not watch(oSlot).feed(1).frame(START ).wasEmitted());
|
||||
CHECK ( watch(oSlot).feed(1).frame(START+1).wasEmitted());
|
||||
|
||||
CHECK ( watch(oSlot).feed(0).frame(123).wasReleased());
|
||||
CHECK (not watch(oSlot).feed(0).frame(124).wasReleased());
|
||||
CHECK ( watch(oSlot).feed(1).frame(123).wasReleased());
|
||||
CHECK ( watch(oSlot).feed(1).frame(124).wasReleased());
|
||||
CHECK ( watch(oSlot).feed(0).frame(START ).wasReleased());
|
||||
CHECK (not watch(oSlot).feed(0).frame(START+1).wasReleased());
|
||||
CHECK ( watch(oSlot).feed(1).frame(START ).wasReleased());
|
||||
CHECK ( watch(oSlot).feed(1).frame(START+1).wasReleased());
|
||||
|
||||
auto stream0 = watch(oSlot).getFeed(0);
|
||||
auto stream1 = watch(oSlot).getFeed(1);
|
||||
auto stream0 = watch(oSlot).getFeed(0, START);
|
||||
auto stream1 = watch(oSlot).getFeed(1, START);
|
||||
|
||||
CHECK ( stream0);
|
||||
CHECK (*stream0 == testData(0,0)); ++stream0;
|
||||
CHECK (!stream0);
|
||||
CHECK (not stream0->wasLocked());
|
||||
|
||||
CHECK ( stream1);
|
||||
CHECK (*stream1 == testData(1,0)); ++stream1;
|
||||
CHECK (*stream1 == testData(1,1)); ++stream1;
|
||||
CHECK (!stream1);
|
||||
CHECK (not stream1->wasLocked());
|
||||
|
||||
// Verify that recorded times match the »step stones« defined above...
|
||||
auto recordedTime_0 = watch(oSlot).feed(0).frame(START).locked; // Frame 0.0
|
||||
auto recordedTime_1 = watch(oSlot).feed(1).frame(START+1).locked; // Frame 1.1
|
||||
auto recordedTime_2 = watch(oSlot).feed(0).frame(START ).emitted; // Frame 0.0
|
||||
auto recordedTime_3 = watch(oSlot).feed(0).frame(START ).released; // Frame 0.0
|
||||
// ..while Frame#1 on Sink#0 was actually never requested...
|
||||
auto recordedTime_N = watch(oSlot).feed(0).frame(START+1).locked; // Frame 0.1
|
||||
|
||||
CHECK (recordedTime_0 < recordedTime_1);
|
||||
CHECK (recordedTime_1 < recordedTime_2);
|
||||
CHECK (recordedTime_2 < recordedTime_3);
|
||||
CHECK (recordedTime_0 == MARK_0);
|
||||
CHECK (recordedTime_1 == MARK_1);
|
||||
CHECK (recordedTime_2 == MARK_2);
|
||||
CHECK (recordedTime_3 == MARK_3);
|
||||
CHECK (Time::NEVER == recordedTime_N);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
258
uml/Lumiera.xmi
258
uml/Lumiera.xmi
|
|
@ -10,6 +10,7 @@
|
|||
<packagedElement xmi:type="uml:Stereotype" xmi:id="owns" name="owns"/>
|
||||
<packagedElement xmi:type="uml:Stereotype" xmi:id="interface" name="interface"/>
|
||||
<packagedElement xmi:type="uml:Stereotype" xmi:id="dataType" name="dataType"/>
|
||||
<packagedElement xmi:type="uml:Stereotype" xmi:id="smart_handle" name="smart_handle"/>
|
||||
<packagedElement xmi:type="uml:Model" xmi:id="Logical View" name="Logical View" stereotype="folder">
|
||||
<uml:Package xmi:id="Datatypes" name="Datatypes" stereotype="folder">
|
||||
<packagedElement xmi:type="uml:DataType" xmi:id="mhSdaAG81L4V" name="int" stereotype="datatype"/>
|
||||
|
|
@ -326,151 +327,179 @@
|
|||
<uml:Package xmi:id="uaFU4ZjLIJ8Uv" name="Output" stereotype="folder">
|
||||
<uml:Package xmi:id="ulZZQCq50aIbe" name="OutputSlot" stereotype="folder">
|
||||
<packagedElement xmi:type="uml:Class" xmi:id="uSdMfvm7i7gGI" name="OutputSlot">
|
||||
<ownedAttribute xmi:type="uml:Property" xmi:id="ucAptBFJopqZY" name="state_" visibility="protected" stereotype="owns" type="u7wTiAdmiAByJ"/>
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="uhMQiJD96kEuB" name="isFree">
|
||||
<ownedAttribute xmi:type="uml:Property" xmi:id="ucAptBFJopqZY" name="alloc_" visibility="protected" stereotype="owns" type="u7wTiAdmiAByJ"/>
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="uhMQiJD96kEuB" name="isActive">
|
||||
<ownedParameter xmi:type="uml:Parameter" xmi:id="uriSPYETtRMRE" type="c4Twqn0aUQB4" direction="return"/>
|
||||
</ownedOperation>
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="uQEgCpAllbbm3" name="allocate"/>
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="uD216HGDrEbGk" name="getTimings"/>
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="uQEgCpAllbbm3" name="getOpenedSinks"/>
|
||||
</packagedElement>
|
||||
<packagedElement xmi:type="uml:Class" xmi:id="uUqbRaeXT7fNx" name="SpecificOutputSlot" visibility="implementation">
|
||||
<generalization xmi:type="uml:Generalization" xmi:id="udcueEBAKYV7K" general="uSdMfvm7i7gGI"/>
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="umG1eERfGXLWz" name="buildState">
|
||||
<packagedElement xmi:type="uml:Class" xmi:id="uUqbRaeXT7fNx" name="OutputManager" visibility="implementation">
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="umG1eERfGXLWz" name="openOutput">
|
||||
<ownedParameter xmi:type="uml:Parameter" xmi:id="uGxE1HoewbWqs" type="u7wTiAdmiAByJ" direction="return"/>
|
||||
</ownedOperation>
|
||||
</packagedElement>
|
||||
<packagedElement xmi:type="uml:Class" xmi:id="uMC7JhfSjNmhE" name="SpecificConnection">
|
||||
<generalization xmi:type="uml:Generalization" xmi:id="uODH2gZMDssLC" general="uf10mauSZTRhO"/>
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="uzGwUeh1xLb5s" name="claimBufferFor"/>
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="ufYZEWmf1wJdB" name="publish"/>
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="upaNGeXC4Aln2" name="release"/>
|
||||
</packagedElement>
|
||||
<packagedElement xmi:type="uml:Class" xmi:id="uJTVhWsuR8ex1" name="DataSink">
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="uJfiV70CP586r" name="lockBufferFor">
|
||||
<ownedParameter xmi:type="uml:Parameter" xmi:id="uyXFRcOAi1M71" type="ubYkCE7vQXUGD" direction="return"/>
|
||||
</ownedOperation>
|
||||
<ownedAttribute xmi:type="uml:Property" xmi:id="u1SieHjkVDgZi" name="descriptor" visibility="private" type="uOkfPRYxUO0jc"/>
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="uZrCr4uZ0BV6z" name="invoke"/>
|
||||
</packagedElement>
|
||||
<packagedElement xmi:type="uml:Class" xmi:id="uf10mauSZTRhO" name="Connection">
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="uOnkCNjLPCxXk" name="getBufferSize"/>
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="ulXYOC6H67SU5" name="claimBufferFor" isVirtual="true">
|
||||
<ownedParameter xmi:type="uml:Parameter" xmi:id="ud48epbOGYFEA" name="frameID" visibility="private" type="" value=""/>
|
||||
</ownedOperation>
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="um1TPC4nISCjR" name="transfer" isVirtual="true"/>
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="um1TPC4nISCjR" name="publish" isVirtual="true"/>
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="uQdo4d1WDCUMA" name="release"/>
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="u0R3WQdQJmmUp" name="shutDown" isVirtual="true"/>
|
||||
</packagedElement>
|
||||
<packagedElement xmi:type="uml:Class" xmi:id="u5kuKJrlM1zly" name="AllocState">
|
||||
<ownedParameter xmi:type="uml:ClassifierTemplateParameter" xmi:id="u32wk8JJI3dUB" name="CON"/>
|
||||
<ownedParameter xmi:type="uml:ClassifierTemplateParameter" xmi:id="uCyAVPudYbQe3" name="CON"/>
|
||||
<generalization xmi:type="uml:Generalization" xmi:id="uNwZZVhJYJiUz" general="u7wTiAdmiAByJ"/>
|
||||
<generalization xmi:type="uml:Generalization" xmi:id="uoSTMEoei8G00" general="u7wTiAdmiAByJ"/>
|
||||
<generalization xmi:type="uml:Generalization" xmi:id="ued1fAoHx5qeL" general="ues4Riovaqpbr"/>
|
||||
<ownedAttribute xmi:type="uml:Property" xmi:id="u77HNh6ntNOnH" name="connections_" visibility="private" type="uMC7JhfSjNmhE"/>
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="usMJpb2kIIUEL" name="AllocState" stereotype="constructor"/>
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="uZN3PmvFPlSdS" name="connectOutputSink" visibility="private"/>
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="utgdUI6xmJ5NM" name="shutdownConnection" visibility="private"/>
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="uZN3PmvFPlSdS" name="connect" visibility="private"/>
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="utgdUI6xmJ5NM" name="release" visibility="private"/>
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="uzdgBeH9fii8b" name="getTimings"/>
|
||||
</packagedElement>
|
||||
<packagedElement xmi:type="uml:Class" xmi:id="ues4Riovaqpbr" name="Allocation">
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="u8TyH4bvyXlRO" name="getOpenedSinks" isVirtual="true"/>
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="uXc0jayqgvLcp" name="timingConstraints" isVirtual="true"/>
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="uDa0N0luC1hbz" name="isActive" isQuery="true" isVirtual="true"/>
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="u8TyH4bvyXlRO" name="connect" isVirtual="true"/>
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="upDZEVWFoEgrj" name="release"/>
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="uXc0jayqgvLcp" name="getTimings" isVirtual="true"/>
|
||||
</packagedElement>
|
||||
<xmi:Extension extender="umbrello">
|
||||
<diagrams>
|
||||
<diagram xmi.id="uCRIwrHyUI7XP" name="OutputSlot_components" type="1" documentation="" backgroundcolor="#f5e7c3" usebackgroundcolor="0" fillcolor="#ffffc0" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" griddotcolor="#e5d8b6" linecolor="#990000" linewidth="0" textcolor="#000000" usefillcolor="1" showattribassocs="1" showatts="1" showattsig="0" showops="1" showopsig="0" showpackage="0" showpubliconly="0" showscope="0" showstereotype="2" localid="-1" showgrid="1" snapgrid="1" snapcsgrid="1" snapx="5" snapy="5" zoom="100" canvasheight="800" canvaswidth="1200" isopen="1">
|
||||
<diagram xmi.id="uCRIwrHyUI7XP" name="OutputSlot_components" type="1" documentation="" backgroundcolor="#f5e7c3" usebackgroundcolor="0" fillcolor="#ffffc0" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" griddotcolor="#e5d8b6" linecolor="#990000" linewidth="0" textcolor="#000000" usefillcolor="1" showattribassocs="1" showatts="1" showattsig="0" showops="1" showopsig="0" showpackage="0" showpubliconly="0" showscope="0" showstereotype="2" localid="-1" showgrid="1" snapgrid="1" snapcsgrid="1" snapx="5" snapy="5" zoom="123" canvasheight="800" canvaswidth="1200" isopen="1">
|
||||
<widgets>
|
||||
<boxwidget xmi.id="uECVLPJkmZL35" localid="ue7ZT2RU9xzyt" textcolor="#000000" linecolor="#8284e2" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="0" x="195" y="335" width="470" height="255" isinstance="0" showstereotype="2"/>
|
||||
<boxwidget xmi.id="uECVLPJkmZL35" localid="ue7ZT2RU9xzyt" textcolor="#000000" linecolor="#8284e2" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="0" x="195" y="300" width="470" height="255" isinstance="0" showstereotype="2"/>
|
||||
<floatingtext xmi.id="uN6EBEjFuTSqY" localid="uGSlfBauL7HJT" textcolor="none" linecolor="#990000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" x="200" y="50" width="135" height="20" isinstance="0" showstereotype="2" text="Output Management" pretext="" posttext="" role="700"/>
|
||||
<notewidget xmi.id="uBGkF3KByNCSh" localid="uRx8T1AZUgRfC" textcolor="#000000" linecolor="#0055ff" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#aaffff" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="0" x="600" y="380" width="130" height="60" isinstance="0" showstereotype="2" text="Knowledge specific for this kind of output driver " noteType="0"/>
|
||||
<classwidget xmi.id="u5JicU0GNjitG" localid="uLNRPkNDdYJ4I" textcolor="#000000" linecolor="#990000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" x="270" y="530" width="130" height="50" isinstance="0" showstereotype="2" showoperations="1" showpubliconly="0" showopsigs="603" showpackage="0" showscope="0" showattributes="1" showattsigs="603"/>
|
||||
<classwidget xmi.id="ugZ3tw8emNmCk" localid="uZxZJpq9678xS" textcolor="#000000" linecolor="#990000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="0" x="595" y="600" width="140" height="50" isinstance="0" showstereotype="2" showoperations="1" showpubliconly="0" showopsigs="603" showpackage="0" showscope="0" showattributes="1" showattsigs="603"/>
|
||||
<floatingtext xmi.id="u6EvNoXxJUpd4" localid="uE8Px66JPPzQ8" textcolor="#000000" linecolor="#990000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="0" x="405" y="305" width="135" height="20" isinstance="0" showstereotype="2" text="Actual Output Driver" pretext="" posttext="" role="700"/>
|
||||
<classwidget xmi.id="u5JicU0GNjitG" localid="uLNRPkNDdYJ4I" textcolor="#000000" linecolor="#990000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="0" x="245" y="490" width="130" height="50" isinstance="0" showstereotype="2" showoperations="1" showpubliconly="0" showopsigs="603" showpackage="0" showscope="0" showattributes="1" showattsigs="603"/>
|
||||
<classwidget xmi.id="ugZ3tw8emNmCk" localid="uZxZJpq9678xS" textcolor="#000000" linecolor="#990000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="0" x="595" y="580" width="140" height="50" isinstance="0" showstereotype="2" showoperations="1" showpubliconly="0" showopsigs="603" showpackage="0" showscope="0" showattributes="1" showattsigs="603"/>
|
||||
<notewidget xmi.id="uxrjVPencXlRU" localid="uiPwuozqE0e72" textcolor="#000000" linecolor="#0055ff" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#aaffff" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="0" x="85" y="130" width="125" height="45" isinstance="0" showstereotype="2" text="Client front-end" noteType="0"/>
|
||||
<classwidget xmi.id="uUqbRaeXT7fNx" localid="uZQj2N5Q7D43J" textcolor="#000000" linecolor="#00557f" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#9bffd0" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="0" x="205" y="370" width="130" height="35" isinstance="0" showstereotype="2" showoperations="1" showpubliconly="0" showopsigs="603" showpackage="0" showscope="0" showattributes="1" showattsigs="603"/>
|
||||
<classwidget xmi.id="uMC7JhfSjNmhE" localid="uB0CKUWqZQqbu" textcolor="#000000" linecolor="#00557f" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#9bffd0" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="0" x="495" y="485" width="125" height="45" isinstance="0" showstereotype="2" showoperations="1" showpubliconly="0" showopsigs="603" showpackage="0" showscope="0" showattributes="1" showattsigs="603"/>
|
||||
<classwidget xmi.id="ubYkCE7vQXUGD" localid="uioySnLsOFP1b" textcolor="#000000" linecolor="#990000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="0" x="95" y="530" width="80" height="50" isinstance="0" showstereotype="2" showoperations="1" showpubliconly="0" showopsigs="603" showpackage="0" showscope="0" showattributes="1" showattsigs="603"/>
|
||||
<classwidget xmi.id="uf10mauSZTRhO" localid="uTLPu4PPbxsHQ" textcolor="#000000" linecolor="#990000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="0" x="500" y="230" width="115" height="65" isinstance="0" showstereotype="2" showoperations="1" showpubliconly="0" showopsigs="603" showpackage="0" showscope="0" showattributes="1" showattsigs="603"/>
|
||||
<classwidget xmi.id="uSdMfvm7i7gGI" localid="uk2QoQY3kWuYL" textcolor="#000000" linecolor="#990000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="0" x="225" y="80" width="90" height="60" isinstance="0" showstereotype="2" showoperations="1" showpubliconly="0" showopsigs="603" showpackage="0" showscope="0" showattributes="1" showattsigs="603"/>
|
||||
<classwidget xmi.id="uJTVhWsuR8ex1" localid="uTGTNRUFUOYII" textcolor="#000000" linecolor="#990000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="0" x="85" y="240" width="100" height="45" isinstance="0" showstereotype="2" showoperations="1" showpubliconly="0" showopsigs="603" showpackage="0" showscope="0" showattributes="1" showattsigs="603"/>
|
||||
<boxwidget xmi.id="uhFswWzqhhnkR" localid="uK8vrS3Ybe9uS" textcolor="#000000" linecolor="#8284e2" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="0" x="195" y="50" width="275" height="270" isinstance="0" showstereotype="2"/>
|
||||
<floatingtext xmi.id="u6EvNoXxJUpd4" localid="uE8Px66JPPzQ8" textcolor="#000000" linecolor="#990000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="0" x="225" y="335" width="135" height="20" isinstance="0" showstereotype="2" text="Actual Output Driver" pretext="" posttext="" role="700"/>
|
||||
<classwidget xmi.id="u5kuKJrlM1zly" localid="u1W5rrajsHSPA" textcolor="#000000" linecolor="#990000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="0" x="305" y="390" width="175" height="110" isinstance="0" showstereotype="2" showoperations="1" showpubliconly="0" showopsigs="603" showpackage="0" showscope="0" showattributes="1" showattsigs="603"/>
|
||||
<classwidget xmi.id="ues4Riovaqpbr" localid="u2JnqkR0vtvWR" textcolor="#000000" linecolor="#990000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="0" x="325" y="155" width="135" height="65" isinstance="0" showstereotype="2" showoperations="1" showpubliconly="0" showopsigs="603" showpackage="0" showscope="0" showattributes="1" showattsigs="603"/>
|
||||
<classwidget xmi.id="uUqbRaeXT7fNx" localid="uZQj2N5Q7D43J" textcolor="#000000" linecolor="#00557f" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#9bffd0" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="0" x="210" y="260" width="145" height="95" isinstance="0" showstereotype="2" showoperations="1" showpubliconly="0" showopsigs="603" showpackage="0" showscope="0" showattributes="1" showattsigs="603"/>
|
||||
<classwidget xmi.id="uMC7JhfSjNmhE" localid="uB0CKUWqZQqbu" textcolor="#000000" linecolor="#00557f" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#9bffd0" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="0" x="500" y="455" width="120" height="85" isinstance="0" showstereotype="2" showoperations="1" showpubliconly="0" showopsigs="603" showpackage="0" showscope="0" showattributes="1" showattsigs="603"/>
|
||||
<classwidget xmi.id="ubYkCE7vQXUGD" localid="uioySnLsOFP1b" textcolor="#000000" linecolor="#990000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="0" x="95" y="490" width="80" height="50" isinstance="0" showstereotype="2" showoperations="1" showpubliconly="0" showopsigs="603" showpackage="0" showscope="0" showattributes="1" showattsigs="603"/>
|
||||
<classwidget xmi.id="uf10mauSZTRhO" localid="uTLPu4PPbxsHQ" textcolor="#000000" linecolor="#990000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="0" x="500" y="165" width="120" height="95" isinstance="0" showstereotype="2" showoperations="1" showpubliconly="0" showopsigs="603" showpackage="0" showscope="0" showattributes="1" showattsigs="603"/>
|
||||
<classwidget xmi.id="uSdMfvm7i7gGI" localid="uk2QoQY3kWuYL" textcolor="#000000" linecolor="#990000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="0" x="225" y="80" width="120" height="70" isinstance="0" showstereotype="2" showoperations="1" showpubliconly="0" showopsigs="603" showpackage="0" showscope="0" showattributes="1" showattsigs="603"/>
|
||||
<classwidget xmi.id="uJTVhWsuR8ex1" localid="uTGTNRUFUOYII" textcolor="#000000" linecolor="#990000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="0" x="85" y="365" width="100" height="45" isinstance="0" showstereotype="2" showoperations="1" showpubliconly="0" showopsigs="603" showpackage="0" showscope="0" showattributes="1" showattsigs="603"/>
|
||||
<boxwidget xmi.id="uhFswWzqhhnkR" localid="uK8vrS3Ybe9uS" textcolor="#000000" linecolor="#8284e2" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="0" x="195" y="45" width="270" height="245" isinstance="0" showstereotype="2"/>
|
||||
<classwidget xmi.id="u5kuKJrlM1zly" localid="u1W5rrajsHSPA" textcolor="#000000" linecolor="#990000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="0" x="305" y="345" width="180" height="110" isinstance="0" showstereotype="2" showoperations="1" showpubliconly="0" showopsigs="603" showpackage="0" showscope="0" showattributes="1" showattsigs="603"/>
|
||||
<classwidget xmi.id="ues4Riovaqpbr" localid="u2JnqkR0vtvWR" textcolor="#000000" linecolor="#990000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="0" x="340" y="165" width="110" height="65" isinstance="0" showstereotype="2" showoperations="1" showpubliconly="0" showopsigs="603" showpackage="0" showscope="0" showattributes="1" showattsigs="603"/>
|
||||
<classwidget xmi.id="uOkfPRYxUO0jc" localid="u3DUTTN7ZB9pa" textcolor="#000000" linecolor="#990000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="0" x="115" y="430" width="70" height="35" isinstance="0" showstereotype="2" showoperations="1" showpubliconly="0" showopsigs="603" showpackage="0" showscope="0" showattributes="1" showattsigs="603"/>
|
||||
</widgets>
|
||||
<messages/>
|
||||
<associations>
|
||||
<assocwidget xmi.id="ukSmYbC86Fxba" localid="uBkCwBh9Hy1is" textcolor="none" linecolor="#00004f" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" seqnum="" type="501" widgetaid="ues4Riovaqpbr" widgetbid="uJTVhWsuR8ex1" indexa="0" totalcounta="0" indexb="0" totalcountb="0">
|
||||
<floatingtext xmi.id="ujGAfmzNg8CE0" localid="uLMRS7mEc8eOM" textcolor="none" linecolor="#00004f" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" x="130" y="185" width="125" height="20" isinstance="0" showstereotype="2" text="«for each channel»" pretext="" posttext="" role="703"/>
|
||||
<assocwidget xmi.id="uAyT0nHOoE7I4" localid="uq3EYJX6wjmi7" textcolor="none" linecolor="#990000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" seqnum="" type="501" widgetaid="u5JicU0GNjitG" widgetbid="ubYkCE7vQXUGD" indexa="0" totalcounta="0" indexb="0" totalcountb="0">
|
||||
<linepath layout="Direct">
|
||||
<startpoint startx="245" starty="515"/>
|
||||
<endpoint endx="175" endy="515"/>
|
||||
</linepath>
|
||||
</assocwidget>
|
||||
<assocwidget xmi.id="uIBSwutNPZPzq" localid="uj3ftBYSTnvMi" textcolor="none" linecolor="#00004f" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" seqnum="" type="512" widgetaid="uJTVhWsuR8ex1" widgetbid="ubYkCE7vQXUGD" indexa="0" totalcounta="0" indexb="0" totalcountb="0">
|
||||
<linepath layout="Polyline">
|
||||
<startpoint startx="325" starty="186.846"/>
|
||||
<endpoint endx="134.884" endy="240"/>
|
||||
<point x="134.6" y="185"/>
|
||||
<startpoint startx="120.279" starty="410"/>
|
||||
<endpoint endx="94.8719" endy="487.169"/>
|
||||
<point x="94.7054" y="449.087"/>
|
||||
</linepath>
|
||||
</assocwidget>
|
||||
<assocwidget xmi.id="uV8wVnvK7rh0p" localid="uWnvY8BFCnke7" textcolor="none" linecolor="#990000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" seqnum="" type="512" widgetaid="uJTVhWsuR8ex1" widgetbid="uf10mauSZTRhO" indexa="0" totalcounta="0" indexb="0" totalcountb="0">
|
||||
<floatingtext xmi.id="uH5mDhzwDGz1K" localid="uTiUWDrGK6uIA" textcolor="none" linecolor="#990000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" x="275" y="245" width="105" height="20" isinstance="0" showstereotype="2" text="«smart handle»" pretext="" posttext="" role="703"/>
|
||||
<assocwidget xmi.id="ucmzLq03OEnRk" localid="uluk1wIlUDu38" textcolor="none" linecolor="#5500ff" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" seqnum="" type="502" widgetaid="u5JicU0GNjitG" widgetbid="uMC7JhfSjNmhE" indexa="0" totalcounta="0" indexb="0" totalcountb="0">
|
||||
<linepath layout="Direct">
|
||||
<startpoint startx="185" starty="262.5"/>
|
||||
<endpoint endx="500" endy="262.5"/>
|
||||
<startpoint startx="375" starty="510.45"/>
|
||||
<endpoint endx="500" endy="501.7"/>
|
||||
</linepath>
|
||||
</assocwidget>
|
||||
<assocwidget xmi.id="uhwSQyeHwo1eG" localid="ueP7aJOEBEPjQ" textcolor="none" linecolor="#00004f" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" seqnum="" type="502" widgetaid="uJTVhWsuR8ex1" widgetbid="ubYkCE7vQXUGD" indexa="0" totalcounta="0" indexb="0" totalcountb="0">
|
||||
<assocwidget xmi.id="uKE8w2gdGdfg3" localid="uAyOBY2GXP3rm" textcolor="#000000" linecolor="#5500ff" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" seqnum="" type="502" widgetaid="uUqbRaeXT7fNx" widgetbid="uSdMfvm7i7gGI" indexa="0" totalcounta="0" indexb="0" totalcountb="0">
|
||||
<floatingtext xmi.id="uLJomqqOhASNU" localid="uNXv0m8dfVoFM" textcolor="none" linecolor="#990000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" x="225" y="235" width="50" height="20" isinstance="0" showstereotype="2" text="create" pretext="" posttext="" role="703"/>
|
||||
<linepath layout="Polyline">
|
||||
<startpoint startx="229.8" starty="256.4"/>
|
||||
<endpoint endx="230" endy="151.6"/>
|
||||
<point x="229.76" y="230.29"/>
|
||||
</linepath>
|
||||
</assocwidget>
|
||||
<assocwidget xmi.id="u0ISYTRGdeWSq" localid="uPOR18734UK7w" textcolor="#000000" linecolor="#5500ff" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" seqnum="" type="502" widgetaid="uOkfPRYxUO0jc" widgetbid="u5JicU0GNjitG" indexa="0" totalcounta="0" indexb="0" totalcountb="0">
|
||||
<linepath layout="Direct">
|
||||
<startpoint startx="135" starty="285"/>
|
||||
<endpoint endx="135" endy="530"/>
|
||||
<startpoint startx="185" starty="462.266"/>
|
||||
<endpoint endx="250.741" endy="490"/>
|
||||
</linepath>
|
||||
</assocwidget>
|
||||
<assocwidget xmi.id="ukSmYbC86Fxba" localid="uBkCwBh9Hy1is" textcolor="none" linecolor="#00004f" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" seqnum="" type="501" widgetaid="ues4Riovaqpbr" widgetbid="uJTVhWsuR8ex1" indexa="0" totalcounta="0" indexb="0" totalcountb="0">
|
||||
<floatingtext xmi.id="ujGAfmzNg8CE0" localid="uLMRS7mEc8eOM" textcolor="none" linecolor="#00004f" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" x="135" y="195" width="125" height="20" isinstance="0" showstereotype="2" text="«for each channel»" pretext="" posttext="" role="703"/>
|
||||
<linepath layout="Polyline">
|
||||
<startpoint startx="336" starty="195.8"/>
|
||||
<endpoint endx="134.964" endy="365"/>
|
||||
<point x="134.696" y="195.233"/>
|
||||
</linepath>
|
||||
</assocwidget>
|
||||
<assocwidget xmi.id="ued1fAoHx5qeL" localid="ux7NvdsYKHFge" textcolor="none" linecolor="#00004f" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" seqnum="" type="500" widgetaid="u5kuKJrlM1zly" widgetbid="ues4Riovaqpbr" indexa="0" totalcounta="0" indexb="0" totalcountb="0">
|
||||
<linepath layout="Direct">
|
||||
<startpoint startx="393.129" starty="389.4"/>
|
||||
<endpoint endx="392.601" endy="220"/>
|
||||
<startpoint startx="395" starty="345"/>
|
||||
<endpoint endx="395" endy="230"/>
|
||||
</linepath>
|
||||
</assocwidget>
|
||||
<assocwidget xmi.id="upaFpPZtwOB5Z" localid="uv5G2tk661sGY" textcolor="none" linecolor="#00004f" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" seqnum="" type="512" widgetaid="uMC7JhfSjNmhE" widgetbid="ugZ3tw8emNmCk" indexa="0" totalcounta="0" indexb="0" totalcountb="0">
|
||||
<linepath layout="Polyline">
|
||||
<startpoint startx="557.509" starty="530"/>
|
||||
<endpoint endx="595" endy="625.085"/>
|
||||
<point x="557.548" y="625.13"/>
|
||||
</linepath>
|
||||
</assocwidget>
|
||||
<assocwidget xmi.id="ukb26HOdytRIv" localid="uhhNLhWbZMYGX" textcolor="none" linecolor="#00004f" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" seqnum="" type="501" widgetaid="u5JicU0GNjitG" widgetbid="ubYkCE7vQXUGD" indexa="0" totalcounta="0" indexb="0" totalcountb="0">
|
||||
<linepath layout="Direct">
|
||||
<startpoint startx="270" starty="555"/>
|
||||
<endpoint endx="175" endy="555"/>
|
||||
<startpoint startx="559.806" starty="540"/>
|
||||
<endpoint endx="591.4" endy="625.2"/>
|
||||
<point x="559.418" y="625.014"/>
|
||||
</linepath>
|
||||
</assocwidget>
|
||||
<assocwidget xmi.id="uXEIG8zl9WWLt" localid="uhh1eZwm8OsbC" textcolor="#000000" linecolor="#00004f" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" seqnum="" type="509" visibilityA="0" visibilityB="0" changeabilityA="900" changeabilityB="900" roleAdoc="" roleBdoc="" documentation="" widgetaid="uSdMfvm7i7gGI" widgetbid="ues4Riovaqpbr" indexa="0" totalcounta="0" indexb="0" totalcountb="0">
|
||||
<floatingtext xmi.id="uFi1CQ7pdeXXq" localid="uwQN4VP8AXpmW" textcolor="none" linecolor="#00004f" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" x="375" y="135" width="20" height="20" isinstance="0" showstereotype="2" text="1" pretext="" posttext="" role="702"/>
|
||||
<floatingtext xmi.id="u6zSRYDZdlFcZ" localid="uGQ5MwHgGaff9" textcolor="none" linecolor="#00004f" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" x="330" y="80" width="60" height="20" isinstance="0" showstereotype="2" text="«active»" pretext="" posttext="" role="703"/>
|
||||
<floatingtext xmi.id="uFi1CQ7pdeXXq" localid="uwQN4VP8AXpmW" textcolor="none" linecolor="#00004f" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" x="400" y="140" width="20" height="20" isinstance="0" showstereotype="2" text="1" pretext="" posttext="" role="702"/>
|
||||
<floatingtext xmi.id="u6zSRYDZdlFcZ" localid="uGQ5MwHgGaff9" textcolor="none" linecolor="#00004f" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" x="355" y="80" width="60" height="20" isinstance="0" showstereotype="2" text="«active»" pretext="" posttext="" role="703"/>
|
||||
<linepath layout="Polyline">
|
||||
<startpoint startx="317.095" starty="99.705"/>
|
||||
<endpoint endx="392.54" endy="155"/>
|
||||
<point x="392.609" y="99.705"/>
|
||||
<startpoint startx="347.024" starty="99.7165"/>
|
||||
<endpoint endx="395" endy="165"/>
|
||||
<point x="395" y="99.6"/>
|
||||
</linepath>
|
||||
</assocwidget>
|
||||
<assocwidget xmi.id="ugY0hme28eLoX" localid="uPs7OVgxSFGNe" textcolor="none" linecolor="#00004f" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" seqnum="" type="512" widgetaid="u5kuKJrlM1zly" widgetbid="u5JicU0GNjitG" indexa="0" totalcounta="0" indexb="0" totalcountb="0">
|
||||
<linepath layout="Polyline">
|
||||
<startpoint startx="301.4" starty="460"/>
|
||||
<endpoint endx="270" endy="530"/>
|
||||
<point x="270" y="460"/>
|
||||
<startpoint startx="301.4" starty="414.8"/>
|
||||
<endpoint endx="255" endy="485.8"/>
|
||||
<point x="254.6" y="414.8"/>
|
||||
</linepath>
|
||||
</assocwidget>
|
||||
<assocwidget xmi.id="us0I4ZABNpTkX" localid="u46Fq9dcWhXRt" textcolor="none" linecolor="#00004f" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" seqnum="" type="512" widgetaid="uUqbRaeXT7fNx" widgetbid="u5kuKJrlM1zly" indexa="0" totalcounta="0" indexb="0" totalcountb="0">
|
||||
<assocwidget xmi.id="u6MH8AQ0OdTLm" localid="udPcy0NI9uCDE" textcolor="none" linecolor="#5500ff" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" seqnum="" type="502" widgetaid="uSdMfvm7i7gGI" widgetbid="ues4Riovaqpbr" indexa="0" totalcounta="0" indexb="0" totalcountb="0">
|
||||
<linepath layout="Polyline">
|
||||
<startpoint startx="269.938" starty="405"/>
|
||||
<endpoint endx="305.8" endy="444.258"/>
|
||||
<point x="269.8" y="444.2"/>
|
||||
</linepath>
|
||||
</assocwidget>
|
||||
<assocwidget xmi.id="udcueEBAKYV7K" localid="uXkpfmuXASyEA" textcolor="none" linecolor="#00004f" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" seqnum="" type="500" widgetaid="uUqbRaeXT7fNx" widgetbid="uSdMfvm7i7gGI" indexa="0" totalcounta="0" indexb="0" totalcountb="0">
|
||||
<linepath layout="Direct">
|
||||
<startpoint startx="270" starty="370"/>
|
||||
<endpoint endx="270" endy="140"/>
|
||||
<startpoint startx="269.8" starty="151.4"/>
|
||||
<endpoint endx="335.2" endy="174.8"/>
|
||||
<point x="269.8" y="174.8"/>
|
||||
</linepath>
|
||||
</assocwidget>
|
||||
<assocwidget xmi.id="u77HNh6ntNOnH" localid="ut1grPEWcxECX" textcolor="#000000" linecolor="#00004f" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" seqnum="" type="510" visibilityA="1" visibilityB="1" changeabilityA="900" changeabilityB="900" widgetaid="u5kuKJrlM1zly" widgetbid="uMC7JhfSjNmhE" indexa="0" totalcounta="0" indexb="0" totalcountb="0">
|
||||
<linepath layout="Polyline">
|
||||
<startpoint startx="480" starty="430"/>
|
||||
<endpoint endx="510.4" endy="481.8"/>
|
||||
<point x="510.221" y="429.813"/>
|
||||
<startpoint startx="482.4" starty="384.8"/>
|
||||
<endpoint endx="515" endy="451.4"/>
|
||||
<point x="514.887" y="384.431"/>
|
||||
</linepath>
|
||||
</assocwidget>
|
||||
<assocwidget xmi.id="uODH2gZMDssLC" localid="u2zJz8fxRNcIO" textcolor="none" linecolor="#00004f" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" seqnum="" type="500" widgetaid="uMC7JhfSjNmhE" widgetbid="uf10mauSZTRhO" indexa="0" totalcounta="0" indexb="0" totalcountb="0">
|
||||
<linepath layout="Direct">
|
||||
<startpoint startx="557.5" starty="485"/>
|
||||
<endpoint endx="557.5" endy="295"/>
|
||||
<startpoint startx="560" starty="455"/>
|
||||
<endpoint endx="560" endy="260"/>
|
||||
</linepath>
|
||||
</assocwidget>
|
||||
<assocwidget xmi.id="uSvN1AP4EnTEm" localid="ujwrjkUwU6feu" textcolor="#000000" linecolor="#00004f" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" seqnum="" type="503" widgetaid="uJTVhWsuR8ex1" widgetbid="uOkfPRYxUO0jc" indexa="0" totalcounta="0" indexb="0" totalcountb="0">
|
||||
<linepath layout="Direct">
|
||||
<startpoint startx="145.625" starty="430"/>
|
||||
<endpoint endx="140.625" endy="410"/>
|
||||
</linepath>
|
||||
</assocwidget>
|
||||
<assocwidget xmi.id="uvBlhtMwNghlF" localid="u3nS7klvTtE5W" textcolor="#000000" linecolor="#ff0000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" seqnum="" type="512" widgetaid="uJTVhWsuR8ex1" widgetbid="u5kuKJrlM1zly" indexa="0" totalcounta="0" indexb="0" totalcountb="0">
|
||||
<floatingtext xmi.id="u1iK2yMS9k0ju" localid="uKXo3hhGai4u9" textcolor="none" linecolor="#ff0000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="1" usesdiagramusefillcolor="1" fillcolor="none" font="DejaVu Sans Condensed,9,-1,5,50,0,0,0,0,0,Book" autoresize="1" x="180" y="365" width="105" height="20" isinstance="0" showstereotype="2" text="«smart_handle»" pretext="" posttext="" role="703"/>
|
||||
<linepath layout="Polyline">
|
||||
<startpoint startx="185" starty="365"/>
|
||||
<endpoint endx="301.6" endy="364.4"/>
|
||||
<point x="250" y="364.6"/>
|
||||
</linepath>
|
||||
</assocwidget>
|
||||
</associations>
|
||||
|
|
@ -490,8 +519,10 @@
|
|||
<ownedOperation xmi:type="uml:Operation" xmi:id="uBzHrBd7C8T8g" name="release"/>
|
||||
</packagedElement>
|
||||
<packagedElement xmi:type="uml:Class" xmi:id="u5JicU0GNjitG" name="BufferProxyAdaptor">
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="u46jLezHhgh92" name="buildDescriptor"/>
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="uHhwZne8Q0U4Y" name="lockBuffer"/>
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="u46jLezHhgh92" name="getDescriptor"/>
|
||||
</packagedElement>
|
||||
<packagedElement xmi:type="uml:Class" xmi:id="uOkfPRYxUO0jc" name="BuffDescr">
|
||||
<ownedOperation xmi:type="uml:Operation" xmi:id="uhbJbAu3EfO85" name="lock"/>
|
||||
</packagedElement>
|
||||
</uml:Package>
|
||||
</uml:Package>
|
||||
|
|
@ -636,9 +667,33 @@
|
|||
<ownedEnd xmi:type="uml:AssociationEnd" xmi:id="u99o4ZgCcsYkJ" name="" type="ues4Riovaqpbr" aggregation="aggregate" isNavigable="true" changeability="changeable"/>
|
||||
<ownedEnd xmi:type="uml:AssociationEnd" xmi:id="uURGNslgDPjuh" name="" type="uJTVhWsuR8ex1" aggregation="none" isNavigable="true" changeability="changeable"/>
|
||||
</packagedElement>
|
||||
<packagedElement xmi:type="uml:Association" xmi:id="uSvN1AP4EnTEm" name="">
|
||||
<ownedEnd xmi:type="uml:AssociationEnd" xmi:id="ucwqD7oPcqY2u" name="" type="uJTVhWsuR8ex1" aggregation="none" isNavigable="true" changeability="changeable"/>
|
||||
<ownedEnd xmi:type="uml:AssociationEnd" xmi:id="uhS1tp2rHNkXq" name="" type="uOkfPRYxUO0jc" aggregation="none" isNavigable="true" changeability="changeable"/>
|
||||
</packagedElement>
|
||||
<packagedElement xmi:type="uml:Dependency" xmi:id="u0ISYTRGdeWSq" name="" client="uOkfPRYxUO0jc" supplier="u5JicU0GNjitG"/>
|
||||
<packagedElement xmi:type="uml:Association" xmi:id="u3nkqhEUW4avt" name="">
|
||||
<ownedEnd xmi:type="uml:AssociationEnd" xmi:id="uSFm7lEgaREvF" name="" type="uOkfPRYxUO0jc" aggregation="none" isNavigable="false" changeability="changeable"/>
|
||||
<ownedEnd xmi:type="uml:AssociationEnd" xmi:id="uPFLM6RpCw2As" name="" type="ubYkCE7vQXUGD" aggregation="none" isNavigable="true" changeability="changeable"/>
|
||||
</packagedElement>
|
||||
<packagedElement xmi:type="uml:Association" xmi:id="uvBlhtMwNghlF" name="" stereotype="smart_handle">
|
||||
<ownedEnd xmi:type="uml:AssociationEnd" xmi:id="uRRxZgAmQGiHw" name="" type="uJTVhWsuR8ex1" aggregation="none" isNavigable="false" changeability="changeable"/>
|
||||
<ownedEnd xmi:type="uml:AssociationEnd" xmi:id="uPmYH2059z5Ru" name="" type="u5kuKJrlM1zly" aggregation="none" isNavigable="true" changeability="changeable"/>
|
||||
</packagedElement>
|
||||
<packagedElement xmi:type="uml:Dependency" xmi:id="u6MH8AQ0OdTLm" name="" client="uSdMfvm7i7gGI" supplier="ues4Riovaqpbr"/>
|
||||
<packagedElement xmi:type="uml:Dependency" xmi:id="uKE8w2gdGdfg3" name="create" client="uUqbRaeXT7fNx" supplier="uSdMfvm7i7gGI"/>
|
||||
<packagedElement xmi:type="uml:Dependency" xmi:id="ucmzLq03OEnRk" name="" client="u5JicU0GNjitG" supplier="uMC7JhfSjNmhE"/>
|
||||
<packagedElement xmi:type="uml:Association" xmi:id="uIBSwutNPZPzq" name="">
|
||||
<ownedEnd xmi:type="uml:AssociationEnd" xmi:id="uthBrUA377Q8p" name="" type="uJTVhWsuR8ex1" aggregation="none" isNavigable="false" changeability="changeable"/>
|
||||
<ownedEnd xmi:type="uml:AssociationEnd" xmi:id="uEubLqtr4Pc0v" name="" type="ubYkCE7vQXUGD" aggregation="none" isNavigable="true" changeability="changeable"/>
|
||||
</packagedElement>
|
||||
<packagedElement xmi:type="uml:Association" xmi:id="uAyT0nHOoE7I4" name="">
|
||||
<ownedEnd xmi:type="uml:AssociationEnd" xmi:id="udAyJLtoaGSuh" name="" type="u5JicU0GNjitG" aggregation="aggregate" isNavigable="true" changeability="changeable"/>
|
||||
<ownedEnd xmi:type="uml:AssociationEnd" xmi:id="uadFmUGzHMRee" name="" type="ubYkCE7vQXUGD" aggregation="none" isNavigable="true" changeability="changeable"/>
|
||||
</packagedElement>
|
||||
<xmi:Extension extender="umbrello">
|
||||
<diagrams>
|
||||
<diagram xmi.id="IIIwYfFi2Hzy" name="clip_display" type="1" documentation="" backgroundcolor="#f5e7c3" usebackgroundcolor="0" fillcolor="#ffffc0" font="DejaVu Sans,9,-1,5,50,0,0,0,0,0,Book" griddotcolor="#e5d8b6" linecolor="#990000" linewidth="0" textcolor="#000000" usefillcolor="1" showattribassocs="1" showatts="1" showattsig="0" showops="1" showopsig="0" showpackage="0" showpubliconly="0" showscope="0" showstereotype="2" localid="-1" showgrid="1" snapgrid="1" snapcsgrid="1" snapx="10" snapy="10" zoom="100" canvasheight="410" canvaswidth="560" isopen="1">
|
||||
<diagram xmi.id="IIIwYfFi2Hzy" name="clip_display" type="1" documentation="" backgroundcolor="#f5e7c3" usebackgroundcolor="0" fillcolor="#ffffc0" font="DejaVu Sans,9,-1,5,50,0,0,0,0,0,Book" griddotcolor="#e5d8b6" linecolor="#990000" linewidth="0" textcolor="#000000" usefillcolor="1" showattribassocs="1" showatts="1" showattsig="1" showops="1" showopsig="1" showpackage="1" showpubliconly="0" showscope="1" showstereotype="2" localid="-1" showgrid="1" snapgrid="1" snapcsgrid="1" snapx="10" snapy="10" zoom="100" canvasheight="410" canvaswidth="560" isopen="1">
|
||||
<widgets>
|
||||
<classwidget xmi.id="YML3K4y9h5tE" localid="h5idAOxedsSi" textcolor="#000000" linecolor="#3e0f00" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="DejaVu Sans,8,-1,0,50,0,0,0,0,0" autoresize="1" x="200" y="260" width="100" height="30" isinstance="0" showstereotype="1" showoperations="1" showpubliconly="1" showopsigs="601" showpackage="0" showscope="1" showattributes="1" showattsigs="601"/>
|
||||
<classwidget xmi.id="TxRGe5zBPLEk" localid="NAt4DnJss1W0" textcolor="#000000" linecolor="#3e0f00" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="DejaVu Sans,8,-1,0,50,0,0,0,0,0" autoresize="1" x="340" y="310" width="90" height="30" isinstance="0" showstereotype="1" showoperations="1" showpubliconly="1" showopsigs="601" showpackage="0" showscope="1" showattributes="1" showattsigs="601"/>
|
||||
|
|
@ -727,7 +782,7 @@
|
|||
</assocwidget>
|
||||
</associations>
|
||||
</diagram>
|
||||
<diagram xmi.id="C5tERlQ98tP3" name="CommandAccess" type="1" documentation="" backgroundcolor="#f5e7c3" usebackgroundcolor="0" fillcolor="#ffffc0" font="DejaVu Sans,9,-1,5,50,0,0,0,0,0,Book" griddotcolor="#e5d8b6" linecolor="#990000" linewidth="0" textcolor="#000000" usefillcolor="1" showattribassocs="1" showatts="1" showattsig="0" showops="1" showopsig="0" showpackage="0" showpubliconly="0" showscope="0" showstereotype="2" localid="-1" showgrid="1" snapgrid="1" snapcsgrid="0" snapx="5" snapy="5" zoom="110" canvasheight="379.364" canvaswidth="617.152" isopen="0">
|
||||
<diagram xmi.id="C5tERlQ98tP3" name="CommandAccess" type="1" documentation="" backgroundcolor="#f5e7c3" usebackgroundcolor="0" fillcolor="#ffffc0" font="DejaVu Sans,9,-1,5,50,0,0,0,0,0,Book" griddotcolor="#e5d8b6" linecolor="#990000" linewidth="0" textcolor="#000000" usefillcolor="1" showattribassocs="1" showatts="1" showattsig="1" showops="1" showopsig="1" showpackage="1" showpubliconly="0" showscope="1" showstereotype="2" localid="-1" showgrid="1" snapgrid="1" snapcsgrid="0" snapx="5" snapy="5" zoom="110" canvasheight="379.364" canvaswidth="617.152" isopen="0">
|
||||
<widgets>
|
||||
<floatingtext xmi.id="wpmINPF0EHuA" localid="U5feokOwe3sT" textcolor="#000000" linecolor="#3e0f00" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="DejaVu Sans,8,-1,5,50,0,0,0,0,0,Oblique" autoresize="1" x="255" y="355" width="30" height="18" isinstance="0" showstereotype="1" text="GUI" pretext="" posttext="" role="700"/>
|
||||
<floatingtext xmi.id="kZZOaRpWFbmc" localid="iL564mOWs2Ae" textcolor="#000000" linecolor="#3e0f00" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="DejaVu Sans,8,-1,5,50,0,0,0,0,0,Oblique" autoresize="1" x="395" y="345" width="84" height="18" isinstance="0" showstereotype="1" text="Steam-Layer" pretext="" posttext="" role="700"/>
|
||||
|
|
@ -893,7 +948,7 @@
|
|||
</packagedElement>
|
||||
<xmi:Extension extender="umbrello">
|
||||
<diagrams>
|
||||
<diagram xmi.id="Q1qEMiNK0mHL" name="CommandUsage" type="2" documentation="" backgroundcolor="#f5e7c3" usebackgroundcolor="0" fillcolor="#ffffc0" font="DejaVu Sans,9,-1,5,50,0,0,0,0,0,Book" griddotcolor="#e5d8b6" linecolor="#990000" linewidth="0" textcolor="#000000" usefillcolor="1" showattribassocs="1" showatts="1" showattsig="0" showops="1" showopsig="0" showpackage="0" showpubliconly="0" showscope="0" showstereotype="2" localid="-1" showgrid="0" snapgrid="0" snapcsgrid="0" snapx="25" snapy="25" zoom="100" canvasheight="488.96" canvaswidth="468" isopen="1">
|
||||
<diagram xmi.id="Q1qEMiNK0mHL" name="CommandUsage" type="2" documentation="" backgroundcolor="#f5e7c3" usebackgroundcolor="0" fillcolor="#ffffc0" font="DejaVu Sans,9,-1,5,50,0,0,0,0,0,Book" griddotcolor="#e5d8b6" linecolor="#990000" linewidth="0" textcolor="#000000" usefillcolor="1" showattribassocs="1" showatts="1" showattsig="1" showops="1" showopsig="1" showpackage="1" showpubliconly="0" showscope="1" showstereotype="2" localid="-1" showgrid="0" snapgrid="0" snapcsgrid="0" snapx="25" snapy="25" zoom="100" canvasheight="488.96" canvaswidth="468" isopen="1">
|
||||
<widgets>
|
||||
<boxwidget xmi.id="wMW5l9TCAHOW" localid="bJB4Uoi9qGKs" textcolor="#000000" linecolor="#000000" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="DejaVu Sans,8,-1,0,50,0,0,0,0,0" autoresize="1" x="200" y="126" width="277" height="377" isinstance="0" showstereotype="1"/>
|
||||
<actorwidget xmi.id="zlqyX5J6PSBr" localid="Et047Kv3eR6O" textcolor="#000000" linecolor="#3e0f00" linewidth="0" usefillcolor="1" usesdiagramfillcolor="0" usesdiagramusefillcolor="0" fillcolor="#ffffc0" font="DejaVu Sans,8,-1,0,50,0,0,0,0,0" autoresize="1" x="383" y="50" width="85" height="58.6905" isinstance="0" showstereotype="1"/>
|
||||
|
|
@ -955,7 +1010,7 @@
|
|||
<packagedElement xmi:type="uml:Model" xmi:id="Entity Relationship Model" name="Entity Relationship Model" stereotype="folder"/>
|
||||
</uml:Model>
|
||||
<xmi:Extension extender="umbrello">
|
||||
<docsettings viewid="uCRIwrHyUI7XP" documentation="" uniqueid="uQ5Ee8BdelIuu"/>
|
||||
<docsettings viewid="uCRIwrHyUI7XP" documentation="" uniqueid="un9oDNMzFHs17"/>
|
||||
<listview>
|
||||
<listitem id="Views" type="800" open="1">
|
||||
<listitem id="Component View" type="821" open="1"/>
|
||||
|
|
@ -982,7 +1037,7 @@
|
|||
<listitem id="uI4uVfXWHwlj8" type="829" open="0"/>
|
||||
<listitem id="unGP2JF0ACOa5" type="829" open="0"/>
|
||||
</listitem>
|
||||
<listitem id="dzlPCiVfMhDw" type="803" open="0">
|
||||
<listitem id="dzlPCiVfMhDw" type="803" open="1">
|
||||
<listitem id="AP2Jw6O9SyPl" type="803" open="0">
|
||||
<listitem id="YVUu5DY24gSv" type="813" open="0"/>
|
||||
<listitem id="lqjWPWP1VmdU" type="817" open="0"/>
|
||||
|
|
@ -1065,13 +1120,15 @@
|
|||
</listitem>
|
||||
<listitem id="nCXlkkbOjNnt" type="803" open="1">
|
||||
<listitem id="uyGoZr5GquPiE" type="803" open="1">
|
||||
<listitem id="uOkfPRYxUO0jc" type="813" open="1">
|
||||
<listitem id="uhbJbAu3EfO85" type="815" open="0"/>
|
||||
</listitem>
|
||||
<listitem id="ugZ3tw8emNmCk" type="813" open="1">
|
||||
<listitem id="uThSQBmQlR9RI" type="815" open="0"/>
|
||||
<listitem id="uAwKDrIyLYPlM" type="815" open="0"/>
|
||||
</listitem>
|
||||
<listitem id="u5JicU0GNjitG" type="813" open="1">
|
||||
<listitem id="u46jLezHhgh92" type="815" open="0"/>
|
||||
<listitem id="uHhwZne8Q0U4Y" type="815" open="0"/>
|
||||
</listitem>
|
||||
<listitem id="ubYkCE7vQXUGD" type="813" open="1">
|
||||
<listitem id="u0MVfw1jTGLqj" type="815" open="0"/>
|
||||
|
|
@ -1082,34 +1139,43 @@
|
|||
<listitem id="ulZZQCq50aIbe" type="803" open="1">
|
||||
<listitem id="ues4Riovaqpbr" type="813" open="1">
|
||||
<listitem id="u8TyH4bvyXlRO" type="815" open="0"/>
|
||||
<listitem id="uDa0N0luC1hbz" type="815" open="0"/>
|
||||
<listitem id="uXc0jayqgvLcp" type="815" open="0"/>
|
||||
<listitem id="upDZEVWFoEgrj" type="815" open="0"/>
|
||||
</listitem>
|
||||
<listitem id="u5kuKJrlM1zly" type="813" open="1">
|
||||
<listitem id="usMJpb2kIIUEL" type="815" open="0"/>
|
||||
<listitem id="u32wk8JJI3dUB" type="816" open="0"/>
|
||||
<listitem id="u77HNh6ntNOnH" type="814" open="0"/>
|
||||
<listitem id="uCyAVPudYbQe3" type="816" open="0"/>
|
||||
<listitem id="uZN3PmvFPlSdS" type="815" open="0"/>
|
||||
<listitem id="u77HNh6ntNOnH" type="814" open="0"/>
|
||||
<listitem id="uzdgBeH9fii8b" type="815" open="0"/>
|
||||
<listitem id="utgdUI6xmJ5NM" type="815" open="0"/>
|
||||
</listitem>
|
||||
<listitem id="uf10mauSZTRhO" type="813" open="1">
|
||||
<listitem id="ulXYOC6H67SU5" type="815" open="0"/>
|
||||
<listitem id="u0R3WQdQJmmUp" type="815" open="0"/>
|
||||
<listitem id="uOnkCNjLPCxXk" type="815" open="0"/>
|
||||
<listitem id="um1TPC4nISCjR" type="815" open="0"/>
|
||||
<listitem id="uQdo4d1WDCUMA" type="815" open="0"/>
|
||||
<listitem id="u0R3WQdQJmmUp" type="815" open="0"/>
|
||||
</listitem>
|
||||
<listitem id="uJTVhWsuR8ex1" type="813" open="1">
|
||||
<listitem id="uJfiV70CP586r" type="815" open="0"/>
|
||||
<listitem id="u1SieHjkVDgZi" type="814" open="0"/>
|
||||
<listitem id="uZrCr4uZ0BV6z" type="815" open="0"/>
|
||||
</listitem>
|
||||
<listitem id="uSdMfvm7i7gGI" type="813" open="1">
|
||||
<listitem id="uQEgCpAllbbm3" type="815" open="0"/>
|
||||
<listitem id="uhMQiJD96kEuB" type="815" open="0"/>
|
||||
<listitem id="ucAptBFJopqZY" type="814" open="0"/>
|
||||
</listitem>
|
||||
<listitem id="uCRIwrHyUI7XP" type="807" label="OutputSlot_components" open="0"/>
|
||||
<listitem id="uMC7JhfSjNmhE" type="813" open="1"/>
|
||||
<listitem id="uUqbRaeXT7fNx" type="813" open="1">
|
||||
<listitem id="umG1eERfGXLWz" type="815" open="0"/>
|
||||
</listitem>
|
||||
<listitem id="uSdMfvm7i7gGI" type="813" open="1">
|
||||
<listitem id="ucAptBFJopqZY" type="814" open="0"/>
|
||||
<listitem id="uQEgCpAllbbm3" type="815" open="0"/>
|
||||
<listitem id="uD216HGDrEbGk" type="815" open="0"/>
|
||||
<listitem id="uhMQiJD96kEuB" type="815" open="0"/>
|
||||
</listitem>
|
||||
<listitem id="uCRIwrHyUI7XP" type="807" label="OutputSlot_components" open="0"/>
|
||||
<listitem id="uMC7JhfSjNmhE" type="813" open="1">
|
||||
<listitem id="uzGwUeh1xLb5s" type="815" open="0"/>
|
||||
<listitem id="ufYZEWmf1wJdB" type="815" open="0"/>
|
||||
<listitem id="upaNGeXC4Aln2" type="815" open="0"/>
|
||||
</listitem>
|
||||
</listitem>
|
||||
<listitem id="ui70cK4M2XGd9" type="813" open="1"/>
|
||||
</listitem>
|
||||
|
|
|
|||
|
|
@ -5157,7 +5157,7 @@ Thus the mapping is a copyable value object, using an associative array. It may
|
|||
First and foremost, mapping can be seen as a //functional abstraction.// As it's used at implementation level, encapsulation of detail types in't the primary concern, so it's a candidate for generic programming: For each of those use cases outlined above, a distinct mapping type is created by instantiating the {{{OutputMapping<DEF>}}} template with a specifically tailored definition context ({{{DEF}}}), which takes on the role of a strategy. Individual instances of this concrete mapping type may be default created and copied freely. This instantiation process includes picking up the concrete result type and building a functor object for resolving on the fly. Thus, in the way typical for generic programming, the more involved special details are moved out of sight, while being still in scope for the purpose of inlining. But there //is// a concern better to be encapsulated and concealed at the usage site, namely accessing the rules system. Thus mapping leads itself to the frequently used implementation pattern where there is a generic frontend as header, calling into opaque functions embedded within a separate compilation unit.
|
||||
</pre>
|
||||
</div>
|
||||
<div title="OutputSlot" modifier="Ichthyostega" created="201106162339" modified="202603220010" tags="def Concepts Player spec img" changecount="26">
|
||||
<div title="OutputSlot" modifier="Ichthyostega" created="201106162339" modified="202604110029" tags="def Concepts Player spec img" changecount="29">
|
||||
<pre>Within the Lumiera player and output subsystem, actually sending data to an external output requires to allocate an ''output slot''
|
||||
This is the central metaphor for the organisation of actual (system level) outputs; using this concept allows to separate and abstract the data calculation and the organisation of playback and rendering from the specifics of the actual output sink. Actual output possibilities (video in GUI window, video fullscreen, using a beamer, sound, Jack, rendering to file) can be added and removed dynamically from various components (Vault, Stage), all using the same resolution and mapping mechanisms (&rarr; OutputManagement)
|
||||
|
||||
|
|
@ -5170,7 +5170,7 @@ Once the client retrieves the OutputSlot for some desired output capability, the
|
|||
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 ''data sink 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, which includes to obtain 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 StreamType and further metadata has been validated or configured suitably at a higher level. However, the OutputSlot exposes a definition of [[timing constraints|Timings]] 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.
|
||||
|
||||
!!!usage and implementation
|
||||
Clients retrieve a reference to an output slot by asking a suitable OutputManager for an output possibility that supports some specific media and format. Usually, they just "claim" this slot by invoking {{{allocate()}}}, which causes actual output connections to be built and data handover mechanisms to be established, behind the scenes. For each such connection -- corresponding to a single distinct data feed within the media format handled by this ~OutputSlot -- the client gets a smart-handle {{{DataSink}}}. The feed may, or may not correspond to a nominal channel in the media format, since some output interfaces require to deliver the data in separate buffers per channel, while others require data to be interleaved. Generally speaking, the concrete ~OutputSlot implementation performs operations rather specific to the kind of output and external interface in question -- thereby calling directly into a specific connection implementation. The »''Output Slot Protocol''« however is designed in a way to abstract from all those technical details.
|
||||
Clients retrieve an OutputSlot (≙handle) by asking a suitable OutputManager for an output possibility that supports the desired media and output mode. When this setup succeeds, the underlying output channel has been //allocated// exclusively to this client, so that actual output connections are built and data handover mechanisms were established behind the scenes. All these allocated resources will remain active as long as any of the connected handles is alive. Depending on the actual output technology and the kind of data stream to send to output, a single OutputSlot can manage several active data streams processed in parallel, like e.g. a 3D video output that involves sending two video feeds to separate beamers. For each such connection -- corresponding to a single distinct data feed within the media format handled by this ~OutputSlot -- the client gets a smart-handle {{{DataSink}}}. The feed may, or may not correspond to a nominal channel in the media format, since some output interfaces require to deliver the data in separate buffers per channel, while others require data to be interleaved. Generally speaking, the concrete ~OutputSlot implementation performs operations rather specific to the kind of output and external interface in question -- thereby calling directly into a specific connection implementation. The »''Output Slot Protocol''« however is designed in a way to abstract from all those technical details. Obviously, the Render Node Network must have been prepared in a way that matches the number of connections and the kind of data expected at the output interface. By design choice, there is no further automatic adaptation or translation layer -- whenever something must be converted, preprocessed or adapted, the corresponding computations are managed within the Render Engine itself.
|
||||
|
||||
!!!timing expectations
|
||||
Besides the sink handles, allocation of an output slot defines some timing constraints, to which the client must comply. These [[Timings]] are detailed and explicit, including a grid of deadlines for each frame to deliver, plus a fixed //latency.// Within this context, &raquo;latency&laquo; implies a requirement to be ahead of the nominal time by a certain amount, to compensate for the processing time that is necessary to propagate the media to the physical output pin. The output slot implementation itself is bound by external constraints to deliver data at a fixed framerate and aligned to an externally defined timing grid, and furthermore the data needs to be handed over ahead of these time points by an time amount given by the latency. Depending on the data exchange model, additional timing constraints may be imposed to further limit the time window when the buffer must be provided, transferred and released.
|
||||
|
|
@ -5178,13 +5178,14 @@ Besides the sink handles, allocation of an output slot defines some timing const
|
|||
Within this setup, the assumption is for the client to have elaborate timing capabilities at his disposal. More specifically, the „client“ is assumed to be a //job// running within the engine scheduler and thus can be configured to run //after// some other job has finished, and to run within certain time limits. Thus the client is able to run within a //window of current nominal time// -- which is suitably close to the actual system time. On the other hand, the [[Timings]] linked to each {{{DataSink}}} are likewise aligned with the current system time. This enables the output slot implementation to work out from the current system time is a call is timely or overdue -- and to react accordingly.
|
||||
|
||||
!!!output modes
|
||||
some concrete output connections and drivers embody a specific operation mode (e.g. sample rate or number of channels). The decision and setup of these operational configuration is initiated together with the [[resolution|OutputMapping]] of an OutputDesignation within the OutputManager, finally leading to an output slot (reference), which can be assumed to be suitably configured, before the client allocates this slot for active use. Moreover, an individual output sink (corresponding to some data feed) may just remain unused -- generally speaking, any output channel will just feature silence or remain black, unless or until until there is an {{{emit()}}} call and a successful data handover took place.
|
||||
some concrete output connections and drivers embody a specific operation mode (e.g. sample rate or number of channels). The decision and setup of these operational configuration is initiated together with the [[resolution|OutputMapping]] of an OutputDesignation within the OutputManager, finally leading to an output slot (copyable handle), which can be assumed to be suitably configured for this output action, and has already been //allocated// to this specific client for exclusive use. Moreover, an individual output sink (corresponding to some data feed) may just remain unused -- generally speaking, any output channel will just feature silence or remain black, unless or until until there is an {{{emit()}}} call and a successful data handover took place.
|
||||
|
||||
As an aside, it is acknowledged that there are some output systems with additional flexibility, e.g. ~Jack-Audio, that allow to generate an arbitrary number of output pins -- Lumiera will support this flexibility by allowing to set up additional output slots and attach this information to the current session &rarr; SessionConfigurationAttachment
|
||||
|
||||
!!!Lifecycle and storage
|
||||
The concrete OutputSlot implementation is owned and managed by the facility that actually provides the output capability in question. Once such an output facility becomes usable within Lumiera, it will register this implementation through a suitable OutputManager. For example, the GUI provides several video viewer widgets, while some sound output backend provides sound ports. The associated OutputSlot implementation object is required to stay alive as long as it's registered with an OutputManager. It needs to be de-registered explicitly prior to destruction -- and this deregistration may block until all clients using this slot did terminate. Beyond that, an output slot implementation is responsible to handle all kinds of failures gracefully -- preferably by just emitting a signal (callback functor).
|
||||
{{red{TODO 7/11: Deregistration is an unsolved problem....}}}
|
||||
Any OutputSlot instance handed out to the client is actually backed by a concrete implementation of the interface {{{OutputSlot::Connection}}}. This is where the handling of actual data output is implemented, using functionality of the facility that actually provides the output capability in question. Once such an output facility becomes usable within Lumiera, it will register this implementation through a suitable OutputManager. For example, the GUI provides several video viewer widgets, while some sound output backend provides sound ports. It is assumed that this backing low-level implementation remains available as long as the Lumiera application holds onto opened connection.
|
||||
|
||||
The OutputSlot object handed out to the Render Engine code embeds ref-counting handles, so that the {{{Connection}}} objects remain alive as long as some render or playback process is active and holding a copy of either the OutputSlot or a {{{DataSink}}} handle. Beyond that, a {{{Connection}}} implementation is responsible to handle all kinds of failures gracefully.
|
||||
|
||||
!!!unified data exchange cycle
|
||||
The planned delivery time of a frame is used as an ID throughout that cycle
|
||||
|
|
@ -5214,7 +5215,7 @@ Thus there are two serious problem situations
|
|||
&rarr; OutputSlotImpl
|
||||
</pre>
|
||||
</div>
|
||||
<div title="OutputSlotDesign" modifier="Ichthyostega" created="201112190322" modified="202603212136" tags="design decision" changecount="12">
|
||||
<div title="OutputSlotDesign" modifier="Ichthyostega" created="201112190322" modified="202604102358" tags="design decision" changecount="13">
|
||||
<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
|
||||
|
|
@ -5245,12 +5246,12 @@ Besides the sink handles, allocation of an output slot defines some timing const
|
|||
!!relation to buffer management
|
||||
{{red{WIP 11/11}}} meanwhile I have worked out the BufferProvider interface in detail, including an explicit buffer handover protocol that is is backed by a tiny state engine to track the BufferMetadata. This mechanism provides an additional transition to {{{BLOCKED}}} state when order or timing constraints are being violated. Yet how to detect and resolve such a floundered state from the engine point of view still remains to be addressed.
|
||||
|
||||
{{red{//At this point,//}}} the initial design draft from 2012 became bogged down in a thicket of confused implementation. Based on, and driven by a placeholder implementation at that time, a {{{BufferProvider}}}, that was first utilised to simplify building the test setup, was then conflated with the //interface// exposed towards prospective clients. Notably the prototype implementation relied on passing a BuffHandle from a backing BufferProvider directly to the client. Yet only the BuffHandle itself can be considered part of the protocol, and acts as client interface, necessitating a mechanism that propagates the //lifecycle events// (locking, emitting, releasing) into a state coordinator within the opened OutputSlot.
|
||||
|
||||
{{red{WIP 3/2026}}} after a long break, we are now facing the problem how to make BufferProvider and OutputSlot work together. Both define a protocol and data exchange models -- and both exhibit a weakness regarding the releasing of buffers. At which time is it safe to release a buffer, when the handover didn't happen? This is similar to the problem of closing a network connection, i.e. the problem is generally unsolvable, but can be handled pragmatically within certain limits.
|
||||
* For handles in the Render Engine we can generally assume that the regular call path is always completed, which ensures that every handle gets released. Exceptions may happen, but are //not handled// -- rather the Engine will be shut down in such a case, which could be arranged to discard all buffer memory unconditionally
|
||||
* Regarding the »Output Slot Protocol« it is not clear yet which part will be responsible for checking the [[timing constraints|Timings]]; the actual {{{Connection}}} implementation looks like a plausible candidate. Furthermore, it is not clear yet {{red{3/26}}} where precisely an underlying buffer provider will be integrated, and if doing so is mandatory
|
||||
|
||||
At this point, the initial design draft from 2012 became bogged down in a thicket of confused implementation. Based on, and driven by a placeholder implementation at that time, a {{{BufferProvider}}} utilised to simplify building the test setup was conflated with the //interface// exposed towards prospective clients. Notably the prototype implementation relied on passing a BuffHandle from a backing BufferProvider directly to the client. Yet only the BuffHandle itself can be considered part of the protocol, and acts as client interface, necessitating a mechanism that propagates the //lifecycle events// (locking, emitting, releasing) into a state coordinator within the opened OutputSlot.
|
||||
|
||||
-----
|
||||
!Implementation / design problems
|
||||
How to handle the selection of those two data exchange models!
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue