diff --git a/src/lib/luid.c b/src/lib/luid.c index 86b965dcf..25a50ead7 100644 --- a/src/lib/luid.c +++ b/src/lib/luid.c @@ -47,7 +47,7 @@ lumiera_uid_set_ptr (lumiera_uid* luid, void* ptr) void* -lumiera_uid_ptr_get (lumiera_uid* luid) +lumiera_uid_ptr_get (const lumiera_uid* luid) { return *(void**)luid; } @@ -103,13 +103,13 @@ lumiera_uid_copy (lumiera_uid* dest, lumiera_uid* src) int -lumiera_uid_eq (lumiera_uid* luida, lumiera_uid* luidb) +lumiera_uid_eq (const lumiera_uid* luida, const lumiera_uid* luidb) { return !memcmp (luida, luidb, 16); } size_t -lumiera_uid_hash (lumiera_uid* luid) +lumiera_uid_hash (const lumiera_uid* luid) { return *(size_t*)luid; } diff --git a/src/lib/luid.h b/src/lib/luid.h index 020d0883e..ffcd105dc 100644 --- a/src/lib/luid.h +++ b/src/lib/luid.h @@ -100,7 +100,7 @@ * Retrieve a generic pointer stored in a luid */ void* -lumiera_uid_ptr_get (lumiera_uid* luid); +lumiera_uid_ptr_get (const lumiera_uid* luid); /** * Generate a new luid @@ -126,13 +126,13 @@ lumiera_uid_copy (lumiera_uid* dest, lumiera_uid* src); * Test 2 luid's for equality */ int -lumiera_uid_eq (lumiera_uid* luida, lumiera_uid* luidb); +lumiera_uid_eq (const lumiera_uid* luida, const lumiera_uid* luidb); /** * Generate a hash sum over an luid */ size_t -lumiera_uid_hash (lumiera_uid* luid); +lumiera_uid_hash (const lumiera_uid* luid); #endif /*LIB_LUID_H*/ diff --git a/src/steam/engine/job-ticket.cpp b/src/steam/engine/job-ticket.cpp index 65783b028..3ed1e9552 100644 --- a/src/steam/engine/job-ticket.cpp +++ b/src/steam/engine/job-ticket.cpp @@ -31,22 +31,27 @@ #include "steam/engine/job-ticket.hpp" +#include "vault/engine/nop-job-functor.hpp" +#include "lib/depend.hpp" +#include "lib/util.hpp" namespace steam { namespace engine { namespace { // Details... - + lib::Depend nopFunctor; } // (END) Details... // using mobject::Placement; // using mobject::session::Effect; -using vault::engine::JobParameter; -using vault::engine::JobClosure; + using vault::engine::JobParameter; + using vault::engine::JobClosure; -using lib::HashVal; + using lib::HashVal; + + using lib::unConst; class FrameJobClosure @@ -104,21 +109,29 @@ using lib::HashVal; const JobTicket JobTicket::NOP{}; //////////////////////////////////////////////////////////////TICKET #725 : do we actually need that for the final data structure? - /** */ + /** + * Generate a render job to invoke the render network configuration + * as defined and backing this JobTicket. The generated job descriptor record + * will include a specific InvocationInstanceID, which factors in the nominal + * frame time, but also the specific backing render configuration. + * The actual implementation of the job functionality will be delegated + * to the JobClosure, which was set up for this Segment and JobTiket + * after the last Builder run created this part of the render network. + */ Job - JobTicket::createJobFor (FrameCoord coordinates) + JobTicket::createJobFor (FrameCoord coordinates) const { + Time nominalTime = coordinates.absoluteNominalTime; if (isnil (provision_)) - { - + { //////////////////////////////////////////////////////////////////////////////////TICKET #1296 : can we get away just with a do-nothing functor? + return Job(nopFunctor(), InvocationInstanceID(), nominalTime); } else { REQUIRE (this->isValid(), "Attempt to generate render job for incomplete or unspecified render plan."); REQUIRE (coordinates.channelNr < provision_.size(), "Inconsistent Job planning; channel beyond provision"); - Provision& provision = provision_[coordinates.channelNr]; - JobClosure& functor = static_cast (provision.jobFunctor); /////////////////////////TICKET #1295 : fix actual interface down to JobFunctor (after removing C structs) - Time nominalTime = coordinates.absoluteNominalTime; + Provision const& provision = provision_[coordinates.channelNr]; + JobClosure& functor = static_cast (unConst(provision.jobFunctor)); ////////////////TICKET #1295 : fix actual interface down to JobFunctor (after removing C structs) InvocationInstanceID invoKey{timeHash (nominalTime, provision.invocationSeed)}; return Job(functor, invoKey, nominalTime); diff --git a/src/steam/engine/job-ticket.hpp b/src/steam/engine/job-ticket.hpp index 11057f149..92f8b2520 100644 --- a/src/steam/engine/job-ticket.hpp +++ b/src/steam/engine/job-ticket.hpp @@ -147,7 +147,7 @@ using lib::LUID; ExplorationState startExploration() const; ExplorationState discoverPrerequisites (uint channelNr =0) const; - Job createJobFor (FrameCoord coordinates); + Job createJobFor (FrameCoord coordinates) const; bool diff --git a/src/vault/engine/job.cpp b/src/vault/engine/job.cpp index 5fafe6790..6ca7fba97 100644 --- a/src/vault/engine/job.cpp +++ b/src/vault/engine/job.cpp @@ -34,6 +34,7 @@ #include "vault/engine/job.h" +#include "vault/engine/nop-job-functor.hpp" #include "lib/util.hpp" #include @@ -69,6 +70,7 @@ namespace engine { JobFunctor::~JobFunctor() { } JobClosure::~JobClosure() { } ///< @deprecated 4/23 refactoring to retract C-structs from the Scheduler interface + NopJobFunctor::NopJobFunctor() { } diff --git a/src/vault/engine/job.h b/src/vault/engine/job.h index 61137a989..0fddb35f3 100644 --- a/src/vault/engine/job.h +++ b/src/vault/engine/job.h @@ -53,7 +53,7 @@ #include "lib/llist.h" -#include "lib/hash-value.h" +#include "lib/luid.h" #include "lib/time.h" @@ -126,6 +126,18 @@ union InvocationInstanceID struct { int32_t a,b; int64_t t; } part; + + friend bool + operator== (InvocationInstanceID const& l, InvocationInstanceID const& r) + { + return lumiera_uid_eq (&l.luid, &r.luid); + } + + friend bool + operator!= (InvocationInstanceID const& l, InvocationInstanceID const& r) + { + return not (l == r); + } }; diff --git a/src/vault/engine/nop-job-functor.hpp b/src/vault/engine/nop-job-functor.hpp new file mode 100644 index 000000000..ea6602dee --- /dev/null +++ b/src/vault/engine/nop-job-functor.hpp @@ -0,0 +1,107 @@ +/* + NOP-JOB-FUNCTOR.hpp - a render job to do nothing + + Copyright (C) Lumiera.org + 2023, Hermann Vosseler + + This program 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + +/** @file nop-job-functor.hpp + ** Generic implementation of a JobFunctor to perform no calculations. + ** Shall be used whenever playback or rendering must be implemented + ** over a part of the effective timeline with no model at all. + ** @todo WIP draft for the »Playback Vertical Slice« 4/2023 + ** @warning not clear if this solution is feasible ///////////////////////////////////////////////////////TICKET #1296 : do we need to produce "empty output" explicitly? + ** + */ + + +#ifndef VAULT_ENGINE_NOP_JOB_FUNCTOR_H +#define VAULT_ENGINE_NOP_JOB_FUNCTOR_H + + + +#include "lib/hash-standard.hpp" +#include "vault/engine/job.h" +#include "lib/time/timevalue.hpp" + + +namespace vault { +namespace engine{ + + using lib::time::Time; + using lib::HashVal; + + + /** + * Stub implementation of the JobFunctor interface + * for a render job _to do nothing at all_ + * @todo WIP as of 4/2023 + */ + class NopJobFunctor + : public JobClosure + { + + /* === JobFunctor Interface === */ + + JobKind + getJobKind() const + { + return META_JOB; + } + + bool + verify (Time, InvocationInstanceID) const + { + return true; // always happy + } + + InvocationInstanceID + buildInstanceID (HashVal) const override + { + return InvocationInstanceID(); + } + + size_t + hashOfInstance (InvocationInstanceID invoKey) const override + { + std::hash hashr; + HashVal res = hashr (invoKey.frameNumber); + lib::hash::combine (res, hashr (invoKey.part.t)); + return res; + } + + void + invokeJobOperation (JobParameter) override + { + /* NOP */ + } + + void + signalFailure (JobParameter, JobFailureReason) override + { + ///////////TODO do we ever need to notify anyone? can this even happen? + } + + public: + NopJobFunctor(); + }; + + +}} // namespace vault::engine +#endif /*VAULT_ENGINE_NOP_JOB_FUNCTOR_H*/ diff --git a/tests/core/steam/engine/mock-support-test.cpp b/tests/core/steam/engine/mock-support-test.cpp index dad38eb9f..2efb20c4c 100644 --- a/tests/core/steam/engine/mock-support-test.cpp +++ b/tests/core/steam/engine/mock-support-test.cpp @@ -30,6 +30,7 @@ #include "steam/engine/mock-dispatcher.hpp" #include "vault/engine/dummy-job.hpp" #include "lib/util.hpp" +#include "vault/engine/nop-job-functor.hpp" #include "lib/format-cout.hpp"///////////////////////TODO @@ -115,9 +116,18 @@ namespace test { void verify_MockJobTicket() { + FrameCoord coord; + coord.absoluteNominalTime = lib::test::randTime(); + + // build a render job to do nothing.... + Job nopJob = JobTicket::NOP.createJobFor(coord); + CHECK (INSTANCEOF (vault::engine::NopJobFunctor, static_cast (nopJob.jobClosure))); //////////TICKET #1295 : fix actual interface down to JobFunctor (after removing C structs) + CHECK (nopJob.parameter.nominalTime == coord.absoluteNominalTime); + CHECK (nopJob.parameter.invoKey == InvocationInstanceID()); + MockJobTicket mockTicket; CHECK (mockTicket.discoverPrerequisites().empty()); - Job mockJob = mockTicket.createJobFor (FrameCoord{}); + Job mockJob = mockTicket.createJobFor (coord); CHECK (mockTicket.verify_associated (mockJob)); TODO ("cover details of MockJobTicket"); } diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 38291bfe4..b52483778 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -69824,8 +69824,8 @@ - - + + @@ -69859,6 +69859,17 @@ + + + + + + + + + + + @@ -70357,6 +70368,19 @@ + + + + + + + + + + + + + @@ -70791,6 +70815,59 @@ + + + + + + + + +

+ welcher Teil muß wirklich flexibel sein? +

+ +
+ +
+ + + + + + + + + + +

+ ...denn von den grundsätzlichen Abhängigkeiten her weiß nicht einmal ein JobTicket, in welchem Segment es hängt; auch ProcNodes könnten theoretisch sogar in mehreren Segmenten hängen ⟹ es schreint mehr als fragwürdig, ob ein JobFunktor überhaupt im Stande ist, eine inhaltlich sinnvolle verifikation zu machen (über das Prüfen auf null-Pointer hinaus) +

+ +
+ +
+
+ + + + + +
+ + + + + + + + + + + + + +
@@ -70801,6 +70878,7 @@ +