diff --git a/tests/core/steam/engine/testframe.cpp b/tests/core/steam/engine/testframe.cpp index 8a6a3fe35..64e76d194 100644 --- a/tests/core/steam/engine/testframe.cpp +++ b/tests/core/steam/engine/testframe.cpp @@ -2,7 +2,7 @@ TestFrame - test data frame (stub) for checking Render engine functionality Copyright (C) - 2011, Hermann Vosseler + 2011, 2024 Hermann Vosseler   **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 @@ -41,7 +41,7 @@ #include #include -#include +#include @@ -50,15 +50,13 @@ namespace engine{ namespace test { namespace err = lumiera::error; + using std::deque; using util::unConst; - using std::vector; /** @note using a random-congruential engine to generate the payload data */ using PseudoRandom = lib::RandomSequencer; - namespace error = lumiera::error; - namespace { // hidden local support facilities.... /** @@ -103,16 +101,17 @@ namespace test { : public lib::SeedNucleus , util::MoveOnly { - uint64_t const& fixPoint_; + uint64_t const& distinction_; + public: DistinctNucleus(uint64_t const& anchor) - : fixPoint_{anchor} + : distinction_{anchor} { } uint64_t getSeed() override { - return fixPoint_; + return distinction_; } }; @@ -142,76 +141,43 @@ namespace test { } - /** - * @internal table to hold test data frames. + /* ======= static TestFrame repository ======= */ + + /** @internal table to hold test data frames in heap memory. * These frames are built on demand, but retained thereafter. * Some tests might rely on the actual memory locations, using the * test frames to simulate a real input frame data stream. - * @param CHA the maximum number of channels to expect - * @param FRA the maximum number of frames to expect per channel - * @warning choose the maximum number parameters wisely. - * We're allocating memory to hold a table of test frames - * e.g. sizeof(TestFrame) * 20channels * 100frames ≈ 2 MiB - * The table uses vectors, and thus will grow on demand, - * but this might cause existing frames to be relocated in memory; - * some tests might rely on fixed memory locations. Just be cautious! + * @note \ref TestFrame::reseed() also discards this storage, which + * otherwise is retained at stable location until process end. */ - template struct TestFrameTable - : vector> + : deque> { - typedef vector> VECT; - - TestFrameTable() - : VECT(CHA) - { - for (uint i=0; i= this->size()) - { - WARN (test, "Growing table of test frames to %d channels, " - "which is > the default (%d)", chanNr, CHA); resize(chanNr+1); - } ENSURE (chanNr < this->size()); - vector& channel = at(chanNr); + deque& channel = at(chanNr); if (seqNr >= channel.size()) { - WARN_IF (seqNr >= FRA, test, - "Growing channel #%d of test frames to %d elements, " - "which is > the default (%d)", chanNr, seqNr, FRA); - for (uint i=channel.size(); i<=seqNr; ++i) - channel.push_back (TestFrame (i,chanNr)); + INFO (test, "Growing channel #%d of test frames %d -> %d elements." + , chanNr, channel.size(), seqNr+1); + for (uint nr=channel.size(); nr<=seqNr; ++nr) + channel.emplace_back (nr, chanNr); } ENSURE (seqNr < channel.size()); - return channel[seqNr]; } }; - - const uint INITIAL_CHAN = 20; - const uint INITIAL_FRAMES = 100; - - typedef TestFrameTable TestFrames; - - std::unique_ptr testFrames; - - - TestFrame& - accessTestFrame (uint seqNr, uint chanNr) - { - if (!testFrames) testFrames.reset (new TestFrames); - - return testFrames->getFrame(seqNr,chanNr); - } - - } // (End) hidden impl details + // + std::unique_ptr testFrames; + // + }// (End) hidden impl details @@ -219,11 +185,12 @@ namespace test { TestFrame& testData (uint seqNr, uint chanNr) { - return accessTestFrame (seqNr,chanNr); + if (not testFrames) + testFrames = std::make_unique(); + return testFrames->getFrame (seqNr, chanNr); } - /** * @remark this function should be invoked at the start of any test * which requires reproducible data values in the TestFrame. @@ -236,14 +203,15 @@ namespace test { void TestFrame::reseed() { - testFrames.reset(); + testFrames.reset(); // discard existing test data repository dataSeed = drawSeed (lib::defaultGen); } - /* ===== TestFrame class ===== */ + + /* ======= TestFrame class ======= */ TestFrame::Meta::Meta (uint seq, uint family) : _MARK_{stampHeader()} @@ -267,7 +235,6 @@ namespace test { ENSURE (isPristine()); } - TestFrame::TestFrame (TestFrame const& o) : header_{o.header_} { @@ -294,11 +261,11 @@ namespace test { * Sanity check on the metadata header. * @remark Relevant to detect memory corruption or when accessing some * arbitrary memory location, which may or may not actually hold a TestFrame. - * Based on the assumption that it is unlikely that some random memory location - * just happens to hold our [marker word](\ref stampHeader()). + * Based on the assumption that it is unlikely that any given memory location + * just happens to hold our [marker word](\ref stampHeader()) by accident. * @note this is only the base level of verification, because in addition * \ref isValid verifies the checksum and \ref isPristine additionally - * recomputes the data generation to see if it matches the Meta::distinction + * recomputes the data generation to see if it matches the Meta::distinction. */ bool TestFrame::Meta::isPlausible() const @@ -327,14 +294,6 @@ namespace test { : DISCARDED; } - bool - TestFrame::operator== (void* memLocation) const - { - TestFrame& candidate (accessAsTestFrame (memLocation)); - return candidate.isSane() - && candidate == *this; - } - bool TestFrame::Meta::operator== (Meta const&o) const { @@ -343,6 +302,14 @@ namespace test { and checksum == o.checksum and distinction == o.distinction; } + + bool + TestFrame::operator== (void* memLocation) const + { + TestFrame& candidate (accessAsTestFrame (memLocation)); + return candidate.isSane() + && candidate == *this; + } bool TestFrame::contentEquals (TestFrame const& o) const @@ -371,8 +338,7 @@ namespace test { /** verify the current data was not touched since initialisation * @remark implemented by regenerating the data sequence deterministically, - * based on the Meta::distinction mark recorded in the metadata. - */ + * based on the Meta::distinction mark recorded in the metadata. */ bool TestFrame::matchDistinction() const { @@ -462,5 +428,4 @@ namespace test { } - }}} // namespace steam::engine::test diff --git a/tests/core/steam/engine/testframe.hpp b/tests/core/steam/engine/testframe.hpp index 31d2756c2..b20c0c048 100644 --- a/tests/core/steam/engine/testframe.hpp +++ b/tests/core/steam/engine/testframe.hpp @@ -2,7 +2,7 @@ TESTFRAME.hpp - test data frame (stub) for checking Render engine functionality Copyright (C) - 2011, Hermann Vosseler + 2011, 2024 Hermann Vosseler   **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 @@ -20,13 +20,13 @@ ** and stores a lifecycle phase and a data checksum. ** ** The contents of each TestFrame are filled on creation with pseudo-random data, - ** which is created from a _discriminator seed,_ based on a »family« and a »frame-nr« - ** within the family. Due to the deterministic nature of these computations, the - ** _pristine state_ of any frame can be determined. But the payload data is accessible + ** which is created from a _discriminator seed,_ based on a »family« and a »frameNr« + ** within each family(≙channel). Due to the deterministic nature of these computations, + ** the _pristine state_ of any frame can be determined. But the payload data is accessible ** and can be manipulated, and a new [checksum can be recorded](\ref TestFrame::markChecksum). ** - ** For ease of testing, a static store of TestFrame instances is maintained internally, - ** and an arbitrary memory location can be treated as TestFrame. + ** For ease of testing, a static [store of TestFrame instances](\ref #testData) is built and + ** retained in heap memory, and an arbitrary memory location can be treated as TestFrame. */ @@ -132,14 +132,14 @@ namespace test { _Arr const& data() const { return * std::launder (reinterpret_cast<_Arr const*> (&buffer_)); } private: - bool contentEquals (TestFrame const& o) const; - bool matchDistinction() const; void buildData(); - Meta& accessHeader(); + Meta& accessHeader(); Meta const& accessHeader() const; - StageOfLife currStage() const; - HashVal computeChecksum() const; - bool hasValidChecksum() const; + bool contentEquals (TestFrame const& o) const; + bool matchDistinction() const; + StageOfLife currStage() const; + HashVal computeChecksum() const; + bool hasValidChecksum() const; }; @@ -147,12 +147,12 @@ namespace test { /** Helper to access a specific frame of test data at a fixed memory location. * The series of test frames is generated on demand, but remains in memory thereafter, * similar to real data accessible from some kind of source stream. Each of these generated - * test frames filled with different yet reproducible pseudo random data. + * test frames is filled with different yet reproducible pseudo random data. * Client code is free to access and corrupt this data. + * @note TestFrame::reseed() discards this data and draws a new base seed from `defaultGen` */ TestFrame& testData (uint seqNr =0, uint chanNr =0); - }}} // namespace steam::engine::test #endif diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 607ee0ec8..8c023d4df 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -18037,9 +18037,7 @@ - - - +

Eintrag in einer Liste oder Asset in einer Sammlung; @@ -18878,9 +18876,7 @@ - - - +

BEDINUNG: cH > aktuelleHöhe @@ -19130,9 +19126,7 @@ - - - +

das heißt, wenn das Label schon eingeblendet ist, aber nun zusätzlicher Platz verfügbar wird; deshalb dürfen wir hier bei einem bereits eingeblendeten Label nicht pauschal aussteigen, sondern müssen jedesmal die ganze Prüfung machen @@ -19642,9 +19636,7 @@ - - - +

und zwar wegen der Separation of Concerns @@ -20487,9 +20479,7 @@ - - - +

unser InteractionControl ist eine Zwischenschicht @@ -22115,9 +22105,7 @@ - - - +

denn vernünftigerweise muß man davon ausgehen, daß der Canvas (oder wo auch immer das element platziert wird) sich einen Pointer speichert, und diesen später auch aktiv verwenden wird @@ -25463,9 +25451,7 @@ - - - +

...dafür bräuchte ich aber einen Diff-Listener für alle strukturellen Änderungen incl sub-Scope. Das ist nicht trivial zu implementieren, weil die sub-Scopes ja beliebig tief verschachtelt sein können, und alle rekursiv delegiert werden @@ -39076,9 +39062,7 @@ - - - +

das time::Control lebt dann wohl im Observer, und dieser muß eine Schnittstelle haben, über die das time::Control auf das eigentliche Zielfeld gesetzt wird...

...das klingt alles gefährlich indirekt... @@ -41358,9 +41342,7 @@ - - - +

Ansatz mit Unbekannten @@ -43050,9 +43032,7 @@ - - - +

  • @@ -43938,9 +43918,7 @@ - - - +

    damit kann ich stets so genau wie möglich rechnen @@ -45681,9 +45659,7 @@ - - - +

    ...nämlich diejenigen, die selber Modell-Elemente sind. @@ -45959,9 +45935,7 @@ - - - +

    (GlobalCtx)->InteractionDirector->ViewLocator @@ -46157,9 +46131,7 @@ - - - +

    heißt: Element registriert sich am UI-Bus @@ -56710,10 +56682,10 @@ - - - - + + + + @@ -56736,7 +56708,7 @@

- +
@@ -56749,7 +56721,7 @@ - + @@ -56758,6 +56730,7 @@

+
@@ -56809,6 +56782,9 @@ + + + @@ -56942,13 +56918,23 @@ GnaGnaGna

- - +
+ + + + +

+ ...essentielle Vorraussetzung für reproduzierbare Tests: Es gibt einen statischen Basis-Hash, auf dem dann die einzelnen Frame-Serien aufbauen (indem sie ihn jeweils in den Schritt-Spread einarbeiten; dadurch haben benachbarte Frames ähnliche, aber sicher unterschiedliche Diskriminator-Seeds, aus denen ein Linear-Congruential-PRNG gebaut wird, um jeweils die Daten für einen Frame zu befüllen. Der Basis-Seed ist zwar initial komplett zufällig (Entropie), wird aber durch TestFrame::reseed() aus dem aktuellen defaultGen neu gezogen. Und der defaultGen ist für Tests seit #1378 deterministisch pseudo-zufällig und reproduzierbar +

+ +
+ +
@@ -92262,11 +92248,13 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + - + - + + + @@ -92299,8 +92287,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + @@ -92318,7 +92306,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -92333,7 +92321,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + + @@ -92379,10 +92369,16 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + + + - + + + + + @@ -92485,8 +92481,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + @@ -92884,12 +92880,12 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - + + + - + @@ -92903,7 +92899,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -92912,8 +92908,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200

+
- + @@ -92922,6 +92919,10 @@ Date:   Thu Apr 20 18:53:17 2023 +0200

+ +
+ +