Library: test coverage for lifecycle management
Add a complete demonstration for a setup akin to what we use for the Session thread: a threaded component which manages itself but also exposes an external interface, which is opened/closed alongside
This commit is contained in:
parent
7b25609896
commit
29b9126c26
5 changed files with 100 additions and 46 deletions
|
|
@ -225,6 +225,20 @@ namespace lib {
|
|||
void handle_begin_thread() { } ///< called immediately at start of thread
|
||||
void handle_after_thread() { } ///< called immediately before end of thread
|
||||
void handle_loose_thread() { } ///< called when destroying wrapper on still running thread
|
||||
|
||||
/**
|
||||
* allow to detach explicitly — independent from thread-function's state.
|
||||
* @warning this function is borderline dangerous; it might be acceptable
|
||||
* in a situation where the thread totally manages itself and the
|
||||
* thread object is maintained in a unique_ptr. You must ensure that
|
||||
* the thread function does not touch anything in the wrapper object
|
||||
* after that point and only uses storage within its own scope.
|
||||
*/
|
||||
void detach_thread_from_wrapper()
|
||||
{
|
||||
if (isLive())
|
||||
threadImpl_.detach();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -362,6 +376,7 @@ namespace lib {
|
|||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Policy-based configuration of thread lifecycle
|
||||
*/
|
||||
|
|
@ -456,6 +471,13 @@ namespace lib {
|
|||
: launch{buildLauncher (forward<FUN>(threadFunction), forward<ARGS>(args)...)}
|
||||
{ }
|
||||
|
||||
template<class TAR, typename...ARGS>
|
||||
Launch (RES (TAR::*memFun) (ARGS...), ARGS ...args) ///< ctor variant to bind a member function
|
||||
: Launch{move (memFun)
|
||||
,lib::meta::InstancePlaceholder<TAR>{}
|
||||
,forward<ARGS> (args)... }
|
||||
{ }
|
||||
|
||||
Launch&&
|
||||
threadID (string const& threadID)
|
||||
{
|
||||
|
|
@ -737,8 +759,7 @@ namespace lib {
|
|||
})
|
||||
.onOrphan([](thread::ThreadWrapper& wrapper)
|
||||
{
|
||||
if (wrapper.isLive())
|
||||
wrapper.threadImpl_.detach();
|
||||
wrapper.detach_thread_from_wrapper();
|
||||
})};
|
||||
// Note: allocation tossed on the heap deliberately
|
||||
} // The thread-function will pick up and manage *this
|
||||
|
|
|
|||
|
|
@ -231,6 +231,8 @@ namespace control {
|
|||
* any operation running in the Session thread is
|
||||
* started from here. When this loop terminates,
|
||||
* the »session subsystem« shuts down.
|
||||
* @note the callback \a notifyEnd is typically bound
|
||||
* to invoke SteamDispatcher::endRunningLoopState().
|
||||
*/
|
||||
void
|
||||
runSessionThread (Subsys::SigTerm notifyEnd)
|
||||
|
|
|
|||
|
|
@ -28,11 +28,10 @@
|
|||
#include "lib/test/run.hpp"
|
||||
#include "lib/meta/function.hpp"
|
||||
#include "lib/meta/tuple-helper.hpp"
|
||||
#include "lib/test/test-helper.hpp"
|
||||
#include "lib/test/testdummy.hpp"
|
||||
#include "lib/format-cout.hpp"
|
||||
#include "lib/format-util.hpp"
|
||||
#include "lib/test/diagnostic-output.hpp"
|
||||
#include "lib/rational.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <tuple>
|
||||
|
|
|
|||
|
|
@ -27,31 +27,27 @@
|
|||
|
||||
#include "lib/test/run.hpp"
|
||||
#include "lib/thread.hpp"
|
||||
#include "lib/iter-explorer.hpp"
|
||||
#include "lib/scoped-collection.hpp"
|
||||
#include "lib/test/microbenchmark.hpp"
|
||||
#include "lib/test/diagnostic-output.hpp"
|
||||
#include "lib/test/testdummy.hpp"
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
|
||||
using test::Test;
|
||||
using lib::explore;
|
||||
using lib::test::Dummy;
|
||||
using std::atomic_uint;
|
||||
using std::this_thread::yield;
|
||||
using std::this_thread::sleep_for;
|
||||
using namespace std::chrono_literals;
|
||||
using std::chrono::system_clock;
|
||||
using std::unique_ptr;
|
||||
|
||||
|
||||
namespace lib {
|
||||
namespace test{
|
||||
|
||||
namespace { // test parameters
|
||||
|
||||
const uint NUM_THREADS = 200;
|
||||
const uint REPETITIONS = 10;
|
||||
|
||||
namespace {
|
||||
using CLOCK_SCALE = std::micro; // Results are in µ-sec
|
||||
}
|
||||
|
||||
|
|
@ -96,11 +92,11 @@ namespace test{
|
|||
double offset = Dur{threadStart - afterCtor}.count();
|
||||
CHECK (offset > 0);
|
||||
} // Note: in practice we see here values > 100µs
|
||||
// but in theory the thread might even overtake the launcher
|
||||
// but in theory the thread might even overtake the launcher
|
||||
|
||||
|
||||
/**
|
||||
* @test attach user provided callback hooks to the thread lifecycle.
|
||||
|
||||
/** @test attach user provided callback hooks to the thread lifecycle.
|
||||
*/
|
||||
void
|
||||
verifyThreadLifecycleHooks()
|
||||
|
|
@ -124,29 +120,58 @@ namespace test{
|
|||
|
||||
|
||||
/**
|
||||
* @test verify a special setup to start a thread explicitly and to track
|
||||
* the thread's lifecycle state.
|
||||
* @test verify a special setup to start a thread explicitly
|
||||
* and to track the thread's lifecycle state.
|
||||
* - use a component to encapsulate the thread
|
||||
* - this TestThread component is managed in a `unique_ptr`
|
||||
* - thus it is explicitly possible to be _not_ in _running state_
|
||||
* - when starting the TestThread, a lifecycle callback is bound
|
||||
* - at termination this callback will clear the unique_ptr
|
||||
* - thus allocation and _running state_ is tied to the lifecycle
|
||||
*/
|
||||
void
|
||||
demonstrateExplicitThreadLifecycle()
|
||||
{
|
||||
UNIMPLEMENTED ("demonstrate state change");
|
||||
struct TestThread
|
||||
: Thread
|
||||
: ThreadHookable
|
||||
{
|
||||
using Thread::Thread;
|
||||
using ThreadHookable::ThreadHookable;
|
||||
|
||||
uint local{0};
|
||||
atomic_uint processVal{23};
|
||||
|
||||
void
|
||||
doIt (uint a, uint b) ///< the actual operation running in a separate thread
|
||||
doIt (uint haveFun)
|
||||
{
|
||||
uint sum = a + b;
|
||||
// sleep_for (microseconds{sum}); // Note: explicit random delay before local store
|
||||
local = sum;
|
||||
sleep_for (100us);
|
||||
processVal = haveFun;
|
||||
sleep_for (5ms);
|
||||
}
|
||||
};
|
||||
}
|
||||
// Note the Dummy member allows to watch instance lifecycle
|
||||
CHECK (0 == Dummy::checksum());
|
||||
|
||||
// the frontEnd allows to access the TestThread component
|
||||
// and also represents the running state
|
||||
unique_ptr<TestThread> frontEnd;
|
||||
CHECK (not frontEnd); // obviously not running yet
|
||||
|
||||
// start the thread and wire lifecycle callbacks
|
||||
frontEnd.reset (new TestThread{
|
||||
TestThread::Launch{&TestThread::doIt, 55u}
|
||||
.atExit([&]{ frontEnd.reset(); })
|
||||
.onOrphan([](thread::ThreadWrapper& wrapper)
|
||||
{ wrapper.detach_thread_from_wrapper(); })
|
||||
});
|
||||
|
||||
CHECK (frontEnd); // thread now marked as running
|
||||
|
||||
CHECK (23 == frontEnd->processVal); // this value was set by the ctor in this thread
|
||||
sleep_for (1ms); // wait for the thread function to become active
|
||||
CHECK (55 == frontEnd->processVal); // changed by thread function
|
||||
sleep_for (10ms);
|
||||
|
||||
CHECK (not frontEnd); // meanwhile thread has finished
|
||||
} // and also cleared the front-end from the `atExit`-hook
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -65009,9 +65009,9 @@
|
|||
<node COLOR="#338800" CREATED="1695597447169" ID="ID_35947260" MODIFIED="1695859231223" TEXT="Fehlerbehandlung">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1696468379848" ID="ID_1146069423" MODIFIED="1696541583707" TEXT="Ergänzung: autonomous Thread">
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1696468379848" ID="ID_1146069423" MODIFIED="1697054187170" TEXT="Ergänzung: autonomous Thread">
|
||||
<linktarget COLOR="#bc3562" DESTINATION="ID_1146069423" ENDARROW="Default" ENDINCLINATION="444;909;" ID="Arrow_ID_516910789" SOURCE="ID_137837629" STARTARROW="None" STARTINCLINATION="-1280;-32;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#435e98" CREATED="1696468398477" ID="ID_1775921981" MODIFIED="1696966299356" TEXT="neue Anforderung: komplett abgekoppelt">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1696468424018" ID="ID_1127252428" MODIFIED="1696468584146" TEXT="ergibt sich aus dem Protokoll der C++14 - Threads">
|
||||
|
|
@ -65045,7 +65045,7 @@
|
|||
<node CREATED="1696468151894" ID="ID_1613034704" MODIFIED="1696468650111" TEXT="der Thread-Funktor muß das Thread-Objekt als selbst halten"/>
|
||||
<node CREATED="1696468197640" ID="ID_1523718397" MODIFIED="1696468221818" TEXT="der Aufruf-context gibt jeden Bezug dazu auf"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1696522906584" ID="ID_1207549127" MODIFIED="1696525458994" TEXT="ist dieser Ansatz sinnvoll?">
|
||||
<node COLOR="#435e98" CREATED="1696522906584" FOLDED="true" ID="ID_1207549127" MODIFIED="1696525458994" TEXT="ist dieser Ansatz sinnvoll?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1696523014919" ID="ID_385522841" MODIFIED="1696523029472" TEXT="es ginge auch anders: optional<Thread>">
|
||||
<icon BUILTIN="idea"/>
|
||||
|
|
@ -65115,7 +65115,7 @@
|
|||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1696528863266" ID="ID_1924635467" MODIFIED="1696966145777" TEXT="soll aber sauberes Design sein">
|
||||
<node COLOR="#435e98" CREATED="1696528863266" FOLDED="true" ID="ID_1924635467" MODIFIED="1696966145777" TEXT="soll aber sauberes Design sein">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1696528894446" ID="ID_658666182" MODIFIED="1696528900161" TEXT="das heißt">
|
||||
<node CREATED="1696528900773" ID="ID_1777061932" MODIFIED="1696528909994" TEXT="in das Policy-Schema integriert"/>
|
||||
|
|
@ -65157,7 +65157,7 @@
|
|||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1696529335091" ID="ID_1772510094" MODIFIED="1696529606844" TEXT="Erweiterungspunkt in der Policy ausbauen">
|
||||
<node COLOR="#435e98" CREATED="1696529335091" FOLDED="true" ID="ID_1772510094" MODIFIED="1696529606844" TEXT="Erweiterungspunkt in der Policy ausbauen">
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1696529349169" ID="ID_722473249" MODIFIED="1696529353436" TEXT="und zwar den zum Thread-Ende">
|
||||
<node CREATED="1696529438893" ID="ID_842811550" MODIFIED="1696529439969" TEXT="handle_end_of_thread">
|
||||
|
|
@ -65211,7 +65211,7 @@
|
|||
<arrowlink COLOR="#fdfcc6" DESTINATION="ID_1004228427" ENDARROW="Default" ENDINCLINATION="-114;10;" ID="Arrow_ID_936715522" STARTARROW="None" STARTINCLINATION="116;8;"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1696529962087" ID="ID_683965677" MODIFIED="1696531663483" TEXT="ownership wird hier gekapert">
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1696529962087" FOLDED="true" ID="ID_683965677" MODIFIED="1696531663483" TEXT="ownership wird hier gekapert">
|
||||
<icon BUILTIN="clanbomber"/>
|
||||
<node CREATED="1696531683840" ID="ID_1453668397" MODIFIED="1696531729036" TEXT="würde zu schwer diagnostizierbaren Fehler führen, wenn Objekt anderweitig erzeugt wurde">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
|
|
@ -65268,7 +65268,7 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#5b280f" CREATED="1696897248135" ID="ID_433063268" MODIFIED="1696965815605" TEXT="Subklassen ermöglichen?">
|
||||
<node COLOR="#5b280f" CREATED="1696897248135" FOLDED="true" ID="ID_433063268" MODIFIED="1696965815605" TEXT="Subklassen ermöglichen?">
|
||||
<icon BUILTIN="help"/>
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1696897270002" ID="ID_944165024" MODIFIED="1696897420063">
|
||||
|
|
@ -65328,7 +65328,7 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1696965775488" ID="ID_1909867794" MODIFIED="1696965923694">
|
||||
<node COLOR="#338800" CREATED="1696965775488" FOLDED="true" ID="ID_1909867794" MODIFIED="1696965923694">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
|
|
@ -65348,7 +65348,7 @@
|
|||
</node>
|
||||
<node CREATED="1696965973496" ID="ID_1562329556" MODIFIED="1696965986393" TEXT="und eine sonderbare spezial-Policy fällt komplett weg"/>
|
||||
<node CREATED="1696965999636" ID="ID_1837122164" MODIFIED="1696966015867" TEXT="es gibt keine spezielle Thread-Klasse mehr, die man »nicht verwenden« soll"/>
|
||||
<node COLOR="#435e98" CREATED="1696976539898" ID="ID_57182560" MODIFIED="1697050703737" TEXT="ABER: kann mit diesem Design keine Member-Funktionen in den Thread binden">
|
||||
<node COLOR="#435e98" CREATED="1696976539898" FOLDED="true" ID="ID_57182560" MODIFIED="1697050703737" TEXT="ABER: kann mit diesem Design keine Member-Funktionen in den Thread binden">
|
||||
<linktarget COLOR="#5d6faa" DESTINATION="ID_57182560" ENDARROW="Default" ENDINCLINATION="-230;791;" ID="Arrow_ID_1090153547" SOURCE="ID_92765841" STARTARROW="None" STARTINCLINATION="772;-34;"/>
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1696976568054" ID="ID_1651696265" MODIFIED="1696976852099" TEXT="das macht abgeleitete Klassen effektiv sinnlos">
|
||||
|
|
@ -65475,7 +65475,7 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1696532404400" ID="ID_1917558827" MODIFIED="1696539443047" TEXT="Variante-2 : optional-Lifecycle">
|
||||
<node COLOR="#435e98" CREATED="1696532404400" ID="ID_1917558827" MODIFIED="1697054094884" TEXT="Variante-2 : optional-Lifecycle">
|
||||
<linktarget COLOR="#898bab" DESTINATION="ID_1917558827" ENDARROW="Default" ENDINCLINATION="-1027;99;" ID="Arrow_ID_1553665185" SOURCE="ID_104020495" STARTARROW="None" STARTINCLINATION="532;77;"/>
|
||||
<node CREATED="1696532578904" ID="ID_1181618773" MODIFIED="1696532615943" TEXT="erlaubt explizit einen noch nicht / nicht mehr laufenden Zustand"/>
|
||||
<node CREATED="1696532628426" ID="ID_295807620" MODIFIED="1696532638596" TEXT="in der Tat: das wird manchmal gebraucht"/>
|
||||
|
|
@ -65489,7 +65489,7 @@
|
|||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node COLOR="#5b280f" CREATED="1696532676404" ID="ID_91266848" MODIFIED="1696934197232" TEXT="Front-End">
|
||||
<node COLOR="#5b280f" CREATED="1696532676404" FOLDED="true" ID="ID_91266848" MODIFIED="1697054120642" TEXT="Front-End">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1696532680835" ID="ID_553798887" MODIFIED="1696536376316">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
|
|
@ -65546,7 +65546,7 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1696958202741" ID="ID_1577864867" MODIFIED="1696958412378" TEXT="diese bereits im Launch-config-builder adaptieren">
|
||||
<node COLOR="#338800" CREATED="1696958202741" FOLDED="true" ID="ID_1577864867" MODIFIED="1696958412378" TEXT="diese bereits im Launch-config-builder adaptieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1696958220491" ID="ID_1240123723" MODIFIED="1696958388855" TEXT="das löst das Problem mit dem downcast auf einen Subklassen-Typ">
|
||||
<linktarget COLOR="#3bacb8" DESTINATION="ID_1240123723" ENDARROW="Default" ENDINCLINATION="561;0;" ID="Arrow_ID_187329351" SOURCE="ID_1650867169" STARTARROW="None" STARTINCLINATION="386;18;"/>
|
||||
|
|
@ -65808,7 +65808,7 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1696533317806" ID="ID_641021700" MODIFIED="1696966141682" TEXT="Sicherheit">
|
||||
<node COLOR="#435e98" CREATED="1696533317806" FOLDED="true" ID="ID_641021700" MODIFIED="1696966141682" TEXT="Sicherheit">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1696533340931" ID="ID_1317798504" MODIFIED="1696533569753" TEXT="Manipulations-Schutz ⟹ wird auf vernünftige Nutzung zurückgeführt">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
|
|
@ -66208,7 +66208,7 @@
|
|||
<node CREATED="1696538713759" ID="ID_743139495" MODIFIED="1696538713759" TEXT="handle_after_thread"/>
|
||||
<node CREATED="1696961378726" ID="ID_1213403952" MODIFIED="1696961379986" TEXT="handle_loose_thread"/>
|
||||
</node>
|
||||
<node CREATED="1696538607372" ID="ID_479618351" MODIFIED="1696538611095" TEXT="für Variante-1">
|
||||
<node COLOR="#435e98" CREATED="1696538607372" FOLDED="true" ID="ID_479618351" MODIFIED="1697054175018" TEXT="für Variante-1">
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1696890808413" ID="ID_569216542" LINK="#ID_1183918146" MODIFIED="1696890916407" TEXT="es zeigt sich: ein smart-ptr löst das Problem gar nicht">
|
||||
<icon BUILTIN="stop-sign"/>
|
||||
</node>
|
||||
|
|
@ -66224,7 +66224,7 @@
|
|||
<node CREATED="1696966232300" ID="ID_607167636" MODIFIED="1696966249766" TEXT="nur spezielles front-End"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1696538612261" ID="ID_661367597" MODIFIED="1696538614839" TEXT="für Variante-2">
|
||||
<node COLOR="#435e98" CREATED="1696538612261" FOLDED="true" ID="ID_661367597" MODIFIED="1697054174113" TEXT="für Variante-2">
|
||||
<node CREATED="1696933810166" ID="ID_906750178" MODIFIED="1696933829261" TEXT="stelle Storage bereit als std::function"/>
|
||||
<node CREATED="1696529718984" ID="ID_1868637331" MODIFIED="1696934476853" TEXT="die schon definierten Hooks + zusätzlichen Erweiterungspunkt">
|
||||
<arrowlink COLOR="#fdfcc6" DESTINATION="ID_1153306127" ENDARROW="Default" ENDINCLINATION="-341;27;" ID="Arrow_ID_880044186" STARTARROW="None" STARTINCLINATION="263;12;"/>
|
||||
|
|
@ -66235,7 +66235,7 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1696690988844" ID="ID_480585061" MODIFIED="1696861459249" TEXT="das Race-Problem addressieren">
|
||||
<node COLOR="#338800" CREATED="1696690988844" FOLDED="true" ID="ID_480585061" MODIFIED="1696861459249" TEXT="das Race-Problem addressieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1696690998156" ID="ID_394310225" MODIFIED="1696691010645" TEXT="der Thread wird erst aus dem Konstruktor-Rumpf gestartet"/>
|
||||
<node CREATED="1696691012041" ID="ID_1592624785" MODIFIED="1696691021403" TEXT="dafür gibt es eine neue Policy-Funktion"/>
|
||||
|
|
@ -66303,7 +66303,8 @@
|
|||
<node CREATED="1696893059260" ID="ID_109825250" MODIFIED="1696893063103" TEXT="Variante-2"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1696538743210" ID="ID_1370366397" MODIFIED="1696538750437" TEXT="Tests ergänzen">
|
||||
<node COLOR="#338800" CREATED="1696538743210" ID="ID_1370366397" MODIFIED="1697054081393" TEXT="Tests ergänzen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1696538756712" ID="ID_1688404846" MODIFIED="1697050726434" TEXT="ThreadWrapperAutonomous_test">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1696539571988" ID="ID_791561993" MODIFIED="1696966349054" TEXT="demonstriert: einen Thread komplett abgekoppelt starten">
|
||||
|
|
@ -66322,13 +66323,19 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1696538825003" ID="ID_1787030725" MODIFIED="1696539451332" TEXT="ThreadWrapperLifecycle_test">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1696538825003" ID="ID_1787030725" MODIFIED="1697053977126" TEXT="ThreadWrapperLifecycle_test">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1696538968712" ID="ID_1296694941" MODIFIED="1696538983238" TEXT="sollte das Thema »Lifecycle« insgesamt beleuchten"/>
|
||||
<node CREATED="1696538984394" ID="ID_1424729205" MODIFIED="1696538993373" TEXT="die neue Variante ist dann nur ein Sonderfall"/>
|
||||
<node COLOR="#338800" CREATED="1696966333429" ID="ID_232799934" MODIFIED="1696966344964" TEXT="Lifecycle-Hooks in Einsatz zeigen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1697053980258" ID="ID_907514488" MODIFIED="1697054017174" TEXT="Interaktion mit der Umgebung">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1697054018477" ID="ID_714874853" MODIFIED="1697054032319" TEXT="das ist eine vereinfachte Demo für das Setup im Steam-Dispatcher"/>
|
||||
<node CREATED="1697054033897" ID="ID_265930418" MODIFIED="1697054078497" TEXT="die Komponente erbt vom Thread und bindet Lifecycle-Hooks"/>
|
||||
<node CREATED="1697054058064" ID="ID_1243838384" MODIFIED="1697054068656" TEXT="und schießt sich selbst am Ende weg"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue