lumiera_documentation/tests/vault/out/output-slot-protocol-test.cpp
Ichthyostega 473299fb5a OutputSlot: attempt to address deeply rooted structural problems
This changeset attempts to breach into the implementation design of OutputSlot
(while largely retaining the API and the »Output Slot Protocol«).

While the actual problem that brought me to this point can be traced back to some
rather obvious mistake, namely to conflate the `BufferProvider` used as
backing implementation with a `BufferProvider` used as front-end API,
creating the new connections to use an `OutputBufferProxy` unveils some
further long-standing structural mismatch; notably this leads to the
difficulties to get the lifecylce management of `OutputSlot` and `DataSink`
under control.

So I remove one entire level from the implementation,
in a bold move to realign the design with the prospective usage pattern.

Obviously, this breaks a lot of further code, and I need to rewire
the Allocation implementation altogether, and provide a new functor based
implementation for `DataSink`
2026-03-21 00:51:40 +01:00

135 lines
4.6 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
OutputSlotProtocol(Test) - covering the basic usage cycle of an output slot
Copyright (C)
2011, Hermann Vosseler <Ichthyostega@web.de>
  **Lumiera** is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the
  Free Software Foundation; either version 2 of the License, or (at your
  option) any later version. See the file COPYING for further details.
* *****************************************************************/
/** @file output-slot-protocol-test.cpp
** unit test \ref OutputSlotProtocol_test
*/
#include "test/run.hpp"
#include "vault/out/diagnostic-output-slot.hpp"
#include "vault/mem/buffhandle.hpp"
#include "test/test-frame.hpp"
using test::TestFrame;
using test::testData;
using vault::mem::BuffHandle;
namespace vault{
namespace out {
namespace test {
/***************************************************************//**
* @test verify the OutputSlot interface and base implementation
* by performing full data exchange cycle. This is a
* kind of "dry run" for documentation purposes,
* both the actual OutputSlot implementation
* as the client using this slot are Mocks.
*/
class OutputSlotProtocol_test : public Test
{
virtual void
run (Arg)
{
verifyStandardCase();
}
void
verifyStandardCase()
{
// Create Test fixture.
// In real usage, the OutputSlot will be preconfigured
// (Media format, number of channels, physical connections)
// and then registered with / retrieved from an OutputManager
DiagnosticOutputSlot oSlot;
// Note: an OutputSlot is automatically activated / allocated
// for exclusive use by this client.
// Now the client is able to prepare
// "calculation streams" for the individual
// Channels to be output through this slot.
OutputSlot::OpenedSinks sinks = oSlot.getOpenedSinks();
DataSink sink0 = *sinks;
DataSink sink1 = *++sinks;
// within the frame-calculation "loop"
// we perform a data exchange cycle
FrameCnt frameNr = 123;
BuffHandle buff00 = sink0(frameNr);
BuffHandle buff10 = sink1(frameNr);
// rendering process calculates content....
buff00.accessAs<TestFrame>() = testData(0,0);
// while further frames might be processed in parallel
BuffHandle buff11 = sink1(frameNr+1);
buff11.accessAs<TestFrame>() = testData(1,1);
buff10.accessAs<TestFrame>() = testData(1,0);
// Now it's time to emit the output
buff11.emit();
buff00.emit();
// Buffers must be marked as released when done
buff00.release();
buff10.release();
buff11.release();
// that's all for the client
// Verify sane operation....
CHECK (watch(oSlot).cntLocked() == 3);
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(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(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());
auto stream0 = watch(oSlot).getFeed(0);
auto stream1 = watch(oSlot).getFeed(1);
CHECK ( stream0);
CHECK (*stream0 == testData(0,0)); ++stream0;
CHECK (!stream0);
CHECK ( stream1);
CHECK (*stream1 == testData(1,0)); ++stream1;
CHECK (*stream1 == testData(1,1)); ++stream1;
CHECK (!stream1);
}
};
/** Register this test class... */
LAUNCHER (OutputSlotProtocol_test, "unit play");
}}} // namespace vault::out::test