diff --git a/src/lib/frameid.hpp b/src/lib/frameid.hpp index da1270b5e..06a001382 100644 --- a/src/lib/frameid.hpp +++ b/src/lib/frameid.hpp @@ -41,6 +41,10 @@ namespace lumiera { * * @todo currently (10/08) this is a dummy implementation. We'll find out * what is needed once the outline of the render engine is complete. + * @todo 5/2025 meanwhile a new effort to define the processing nodes was successful, + * but it is still not clear if the »Render Nodes« will expose any runtime logic + * beyond the mere ability to be invoked. + * ** This is a placeholder** — we are using ProcID instead */ struct NodeID { diff --git a/src/lib/meta/configflags.hpp b/src/lib/meta/configflags.hpp deleted file mode 100644 index f0c1aa1ea..000000000 --- a/src/lib/meta/configflags.hpp +++ /dev/null @@ -1,194 +0,0 @@ -/* - CONFIGFLAGS.hpp - Building classes based on configuration cases - - Copyright (C) - 2008, 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 -  Free Software Foundation; either version 2 of the License, or (at your -  option) any later version. See the file COPYING for further details. - -*/ - - -/** @file configflags.hpp - ** Under some circumstances it is necessary to assemble functionality - ** out of elementary building blocks. Especially, this assembly can be - ** expressed as template specialisations directed by a configuration type. - ** Thus, the purpose of this header is to encode flag-like configurations - ** as distinct types, which can be used to select such specialisations. - ** Each possible configuration can be encoded as a list of flags, which allows - ** to generate, filter and process those configurations. The final goal is to - ** automatically generate a factory which is able to deliver objects - ** configured according to the situation encoded in the flags. - ** - ** @note currently there is an inherent limitation to configurations defined by - ** a maximum of 5 independent flags. While it is easy to increase this limit, - ** you should consider that the final goal is to generate template instantiations, - ** which would lead to more and more code bloat with growing number of possible - ** combinations. - ** - ** @see steam::engine::config::Strategy usage example - ** @see steam::engine::config::ConfigSelector - ** @see typelist.hpp - ** - */ - - -#ifndef LIB_META_CONFIGFLAGS_H -#define LIB_META_CONFIGFLAGS_H - - -#include "lib/meta/typelist.hpp" - - -namespace lib { -namespace meta{ - - const size_t CONFIG_FLAGS_MAX = 5; - - - template struct Flag { typedef Flag ID; }; - template<> struct Flag<0> { typedef NullType ID; }; - - - template< uint f1=0 - , uint f2=0 - , uint f3=0 - , uint f4=0 - , uint f5=0 - > - struct Flags - { - typedef typename Types< typename Flag::ID - , typename Flag::ID - , typename Flag::ID - , typename Flag::ID - , typename Flag::ID - >::List - Tuple; - typedef Tuple List; - }; - - - template< uint f1=0 - , uint f2=0 - , uint f3=0 - , uint f4=0 - , uint f5=0 - > - struct Config ///< distinct type representing a configuration - { - typedef typename Flags::Tuple Flags; - typedef Flags List; - }; - - - - template - struct ConfigSetFlag; ///< set (prepend) the Flag to the given config - - template< uint Fl - , uint f1 - , uint f2 - , uint f3 - , uint f4 - , uint IGN - > - struct ConfigSetFlag> - { - typedef lib::meta::Config Config; - }; - - - - /** build a configuration type from a list-of-flags */ - template > - struct BuildConfigFromFlags - { - typedef CONF Config; - typedef Config Type; - }; - template - struct BuildConfigFromFlags< Node,FLAGS>, CONF> - { - typedef typename ConfigSetFlag< Fl - , typename BuildConfigFromFlags::Config - >::Config Config; - typedef Config Type; - }; - - /** create a configuration type for the given list-of-flags */ - template - struct DefineConfigByFlags : BuildConfigFromFlags { }; - - - namespace { - /** helper comparing enum values and flags */ - template - struct maxC - { - enum{ VAL = ii < jj? jj : ii }; - }; - } - - - /** - * Helper for calculating values and for - * invoking runtime code based on a given FlagTuple. - * Can also be used on a Typelist of several Configs. - * The latter case is typically used to invoke an operation - * while enumerating all Flag-Configurations defined in Code. - * An example would be to build (at runtime) an dispatcher table. - * Explanation: For the Case covering a List of Configs, we provide - * a templated visitation function, which can accept a functor object - * to be invoked on each Configuration. - */ - template - struct FlagInfo; - - template - struct FlagInfo, FLAGS>> - { - enum{ BITS = maxC< ff, FlagInfo::BITS> ::VAL - , CODE = (1<::CODE - }; - }; - - template<> - struct FlagInfo - { - enum{ BITS = 0 - , CODE = 0 - }; - - template - static typename FUNC::Ret - accept (FUNC& functor) - { - return functor.done(); - } - }; - - template - struct FlagInfo> - { - typedef typename CONF::Flags ThisFlags; - enum{ - BITS = maxC< FlagInfo::BITS, FlagInfo::BITS > ::VAL - }; - - template - static typename FUNC::Ret - accept (FUNC& functor) - { - functor.template visit(FlagInfo::CODE); - return FlagInfo::accept (functor); - } - }; - - - -}} // namespace lib::meta -#endif diff --git a/src/steam/engine/channel-descriptor-obsolete.hpp b/src/steam/engine/channel-descriptor-obsolete.hpp deleted file mode 100644 index ab0c4ee6e..000000000 --- a/src/steam/engine/channel-descriptor-obsolete.hpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - CHANNEL-DESCRIPTOR.hpp - Channel / Buffer type representation for the engine - - Copyright (C) - 2008, 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 -  Free Software Foundation; either version 2 of the License, or (at your -  option) any later version. See the file COPYING for further details. - -*/ - -/** @file channel-descriptor-obsolete.hpp - ** Representation of the Media type of a data channel used within the engine. - ** - ** @todo as it stands (11/2011) this file is obsoleted and needs to be refactored, - ** alongside with adapting the node invocation to the new BufferProvider interface. - ** @todo as of 5/2024, this will be retained as part of the `FeedManifold`, - ** which in turn takes on some aspects of the old buffer table draft. - ** @deprecated 12/2024 it is now clear that the low-level-Model will be really low-level, - ** implying that any connection to the usage domain will be completely resolved in the builder - ** - ** @see nodewiring-def.hpp - ** @see nodeoperation.hpp - ** @see bufftable-obsolete.hpp storage for the buffer table - ** @see engine::RenderInvocation - */ - -#ifndef ENGINE_CHANNEL_DESCRIPTOR_H -#define ENGINE_CHANNEL_DESCRIPTOR_H - - -#include "lib/error.hpp" -#include "lib/hash-value.h" -#include "steam/streamtype.hpp" - - -namespace steam { -namespace engine { - namespace error = lumiera::error; - - using lib::HashVal; - - class BuffDescr; - class BuffHandle; - class BufferProvider; - - - - class ProcNode_Obsolete; - typedef ProcNode_Obsolete* PNode; - - - struct ChannelDescriptor ///////TODO really need to define that here? it is needed for node wiring only - { - const lumiera::StreamType * bufferType; /////////////////////////////////////////TICKET #828 - }; - - struct InChanDescriptor : ChannelDescriptor - { - PNode dataSrc; ///< the ProcNode to pull this input from - uint srcChannel; ///< output channel to use on the predecessor node - }; - - - -}} // namespace steam::engine -#endif diff --git a/src/steam/engine/connectivity-obsolete.hpp b/src/steam/engine/connectivity-obsolete.hpp deleted file mode 100644 index 8885bdeae..000000000 --- a/src/steam/engine/connectivity-obsolete.hpp +++ /dev/null @@ -1,201 +0,0 @@ -/* - PROC-NODE.hpp - Key abstraction of the Render Engine: a Processing Node - - Copyright (C) - 2008, 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 -  Free Software Foundation; either version 2 of the License, or (at your -  option) any later version. See the file COPYING for further details. - -*/ - -/** @file connectivity-obsolete.hpp - ** @deprecated 2024 old variant of render node definition stashed away to keep other obsolete code buildable. - ** - ** Actually, there are three different interfaces to consider - ** - the ProcNode#pull is the invocation interface. It is function-call style - ** - the builder interface, comprised by the NodeFactory and the WiringFactory. - ** - the actual processing function is supposed to be a C function and will be - ** hooked up within a thin wrapper. - ** - ** By using the builder interface, concrete node and wiring descriptor classes are created, - ** based on some templates. These concrete classes form the "glue" to tie the node network - ** together and contain much of the operation behaviour in a hard wired fashion. - ** - ** @todo WIP-WIP-WIP 2024 delete this file!!!! - ** - ** @see nodefactory.hpp - ** @see operationpoint.hpp - */ - -#ifndef STEAM_ENGINE_CONNECTIVITY_OBSOLETE_H -#define STEAM_ENGINE_CONNECTIVITY_OBSOLETE_H - -#ifdef STEAM_ENGINE_PROC_NODE_H - #error "can not include both the old and new Render Node Connectivity scheme" -#endif - -#include "lib/error.hpp" -#include "steam/common.hpp" -#include "steam/asset/proc.hpp" -#include "steam/mobject/parameter.hpp" -#include "steam/engine/state-closure-obsolete.hpp" /////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation -#include "steam/engine/channel-descriptor-obsolete.hpp" -#include "lib/frameid.hpp" -#include "lib/ref-array.hpp" - -#include - - - -namespace steam { -namespace engine { - - using std::vector; - using lumiera::NodeID; - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation - class ProcNode_Obsolete; - typedef ProcNode_Obsolete* PNode; -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation - - - /** - * Interface: Description of the input and output ports, - * processing function and predecessor nodes for a given ProcNode. - * - * @todo the design of this part is messy in several respects. - * Basically, its left-over from a first prototypical implementation from 2008 - * As of 1/2012, we're re-shaping that engine interface and invocation with a top-down approach, - * starting from the player. Anyhow, you can expect the basic setup to remain as-is: there will - * be a ProcNode and a Connectivity descriptor, telling how it's connected to its predecessors, - * and defining how the Node is supposed to operate - * - * @todo WIP-WIP-WIP 2024 Node-Invocation is reworked from ground up for the »Playback Vertical Slice« - */ - class Connectivity - { - public: /* === public information record describing the node graph === */ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation - uint nrO; - uint nrI; - - lib::RefArray& out; - lib::RefArray& in; - - typedef asset::Proc::ProcFunc ProcFunc; - - ProcFunc* procFunction; - - NodeID const& nodeID; - - virtual ~Connectivity() {} -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation - - protected: -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation - Connectivity (lib::RefArray& o, - lib::RefArray& i, - ProcFunc pFunc, NodeID const& nID) - : out(o), in(i), - procFunction(pFunc), - nodeID(nID) - { - nrO = out.size(); - nrI = in.size(); - } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation - /* ==== strategy API for configuring the node operation ==== */ - - friend class ProcNode_Obsolete; /////////////////////////////////TODO 1/12 : wouldn't it be better to extract that API into a distinct strategy? - - /** the wiring-dependent part of the node operation. - * Includes the creation of a one-way state object on the stack - * holding the actual buffer pointers and issuing the recursive pull() calls - * @see NodeWiring#callDown default implementation - */ - virtual BuffHandle - callDown (StateClosure_OBSOLETE& currentProcess, uint requiredOutputNr) const =0; -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation - - }; - - - - - /** - * Key abstraction of the Render Engine: A Data processing Node - * - * @todo it's not clear as of 9/09 if ProcNode shall be an ABC/Interface - * It might be used as ABC (as was the original intention) when implementing - * several query/information functions. In that case, the ctor will become protected. - * The alternative would be to push down these information-retrieval part into a - * configurable element within Connectivity, in which case we even might drop - * ProcNode as a frontend entirely. - * @todo WIP-WIP-WIP 2024 Node-Invocation is reworked from ground up for the »Playback Vertical Slice« - */ - class ProcNode_Obsolete - : util::NonCopyable - { - typedef mobject::Parameter Param; //////TODO: just a placeholder for automation as of 6/2008 - vector params; - - const Connectivity& wiringConfig_; - - public: -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation - ProcNode_Obsolete (Connectivity const& wd) - : wiringConfig_(wd) - { } - - virtual ~ProcNode_Obsolete() {}; /////////////////////////TODO: do we still intend to build a hierarchy below ProcNode??? -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation - - - public: -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation - bool isValid() const; - - /** output channel count */ - uint nrO() { return wiringConfig_.nrO; } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation - - - /** Engine Core operation: render and pull output from this node. - * On return, currentProcess will hold onto output buffer(s) - * containing the calculated result frames. In case this node - * calculates a multichannel output, only one channel can be - * retrieved by such a \c pull() call, but you can expect data - * of the other channels to be processed and fed to cache. - * @param currentProcess the current processing state for - * managing buffers and accessing current parameter values - * @param requestedOutputNr the output channel requested - * (in case this node delivers more than one output channel) - * @return handle to the buffer containing the calculated result. - */ - BuffHandle - pull (StateClosure_OBSOLETE& currentProcess, uint requestedOutputNr=0) const - { - return this->wiringConfig_.callDown (currentProcess, requestedOutputNr); - } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation - - }; - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation - inline bool - ProcNode_Obsolete::isValid() const - { - UNIMPLEMENTED ("ProcNode validity self-check"); - return false; //////////////////////////TODO - } - - -}} // namespace steam::engine -#endif /*STEAM_ENGINE_CONNECTIVITY_OBSOLETE_H*/ diff --git a/src/steam/engine/feed-manifold-obsolete.hpp b/src/steam/engine/feed-manifold-obsolete.hpp deleted file mode 100644 index ad5296d99..000000000 --- a/src/steam/engine/feed-manifold-obsolete.hpp +++ /dev/null @@ -1,186 +0,0 @@ -/* - FEED-MANIFOLD.hpp - data feed connection system for render nodes - - Copyright (C) - 2008, Hermann Vosseler - 2023, 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 -  Free Software Foundation; either version 2 of the License, or (at your -  option) any later version. See the file COPYING for further details. - -*/ - - -/** @file feed-manifold-obsolete.hpp - ** @todo staled since 2009, picked up in 2024 in an attempt to finish the node invocation. - ** deprecated 2024 this file is a dead-end! It is retained in tree to keep other obsolete code buildable - ** @see nodeinvocation.hpp - */ - - -#ifndef ENGINE_FEED_MANIFOLD_OBSOLETE_H -#define ENGINE_FEED_MANIFOLD_OBSOLETE_H - - -#include "lib/error.hpp" -#include "lib/nocopy.hpp" -#include "steam/engine/channel-descriptor-obsolete.hpp" -//#include "steam/engine/proc-node.hpp" ///////////////////////////////TODO this is a dead end -#include "steam/engine/connectivity-obsolete.hpp" - -#include -#include - - -////////////////////////////////TICKET #826 will be reworked alltogether - -namespace steam { -namespace engine { - - using std::pair; - using std::vector; - - - /** - * Obsolete, to be rewritten /////TICKET #826 - * - * Tables of buffer handles and corresponding dereferenced buffer pointers. - * Used within the invocation of a processing node to calculate data. - * The tables are further differentiated into input data buffers and output - * data buffers. The tables are supposed to be implemented as bare "C" arrays, - * thus the array of real buffer pointers can be fed directly to the - * processing function of the respective node. - * - * @todo this whole design is a first attempt and rather clumsy. It should be reworked - * to use a single contiguous memory area and just layer the object structure on top - * (by using placement new). Yet the idea of an stack-like organisation should be retained - */ - struct FeedManifold_BuffTable_OBSOLETE ///////////////////////////////////OOO this is obliterated by the new implementation of FeedManifold_BuffTable_OBSOLETE - { - typedef BuffHandle * PHa; - typedef BuffHandle::PBuff * PBu; - typedef pair Chunk; - - PHa outHandle; - PHa inHandle; - PBu outBuff; - PBu inBuff; - }; - - class BuffDescr; - - /** Obsolete, to be rewritten /////TICKET #826 */ - class BuffTableStorage - { - /////////////////////////////////////////////////////////////////////////TICKET #826 need to be reworked entirely - /** just a placeholder to decouple the existing code - * from the reworked BuffHandle logic. The existing - * code in turn will be reworked rather fundamentally - */ - struct BuffHaXXXX - : BuffHandle - { - BuffHaXXXX() : BuffHandle(just_satisfy_the_compiler()) { /* wont work ever */ } - static BuffDescr const& - just_satisfy_the_compiler() { } - }; - - ////////////////////////////////////TICKET #825 should be backed by mpool and integrated with node invocation - vector hTab_; - vector pTab_; - size_t level_; - - public: - BuffTableStorage (const size_t maxSiz) - : hTab_(maxSiz), - pTab_(maxSiz), - level_(0) - { } - - ~BuffTableStorage() { ASSERT (0==level_, "buffer management logic broken."); } - - protected: - - friend class BuffTableChunk; - - /** allocate the given number of slots - * starting at current level to be used - * by the newly created BuffTableChunk - */ - FeedManifold_BuffTable_OBSOLETE::Chunk - claim (uint slots) - { - ASSERT (pTab_.size() == hTab_.size()); - REQUIRE (level_+slots <= hTab_.size()); - - size_t prev_level (level_); - level_ += slots; - return std::make_pair (&hTab_[prev_level], - &pTab_[prev_level]); - } - - void - release (uint slots) - { - ASSERT (slots <= level_); - REQUIRE (level_ <= hTab_.size()); - REQUIRE (level_ <= pTab_.size()); - - level_ -= slots; - } - - bool - level_check (FeedManifold_BuffTable_OBSOLETE::Chunk& prev_level) - { - return prev_level.first == &hTab_[level_] - && prev_level.second == &pTab_[level_]; - } - }; - - - /** Obsolete, to be rewritten /////TICKET #826 - * to be allocated on the stack while evaluating a ProcNode#pull() call. - * The "current" State (StateProxy) maintains a BuffTableStorage (=pool), - * which can be used to crate such chunks. The claiming and releasing of - * slots in the BuffTableStorage is automatically tied to BuffTableChunk - * object's lifecycle. - */ - class BuffTableChunk - : public FeedManifold_BuffTable_OBSOLETE, - util::NonCopyable - { - const uint siz_; - FeedManifold_BuffTable_OBSOLETE::Chunk tab_; - BuffTableStorage& sto_; - - public: - BuffTableChunk (Connectivity const& wd, BuffTableStorage& storage) - : siz_(wd.nrI + wd.nrO), - tab_(storage.claim (siz_)), - sto_(storage) - { - const uint nrO(wd.nrO); - - // Setup the publicly visible table locations - this->outHandle = &tab_.first[ 0 ]; - this->inHandle = &tab_.first[nrO]; - this->outBuff = &tab_.second[ 0 ]; - this->inBuff = &tab_.second[nrO]; - } - - ~BuffTableChunk () - { - sto_.release (siz_); - ASSERT ( sto_.level_check (tab_), - "buffer management logic broken."); - } - }; - - - - - -}} // namespace steam::engine -#endif /*ENGINE_FEED_MANIFOLD_OBSOLETE_H*/ diff --git a/src/steam/engine/node-factory.cpp b/src/steam/engine/node-factory.cpp index 7a1e0e07d..b61144e71 100644 --- a/src/steam/engine/node-factory.cpp +++ b/src/steam/engine/node-factory.cpp @@ -42,27 +42,6 @@ namespace engine { } // (END) Details of node fabrication - using mobject::Placement; - using mobject::session::Effect; - - - /** create a processing node able to render an effect - * @todo as of 2016 this is the only (placeholder) implementation - * to indicate how building and wiring of nodes was meant to happen - */ -#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #1367 : Rebuild the Node Invocation - PNode - NodeFactory::operator() (Placement const& effect, WiringSituation& intendedWiring) - { - intendedWiring.resolveProcessor(effect->getProcAsset()); - Connectivity& wiring = wiringFac_(intendedWiring); - - ProcNode& newNode = alloc_.create (wiring); - ENSURE (newNode.isValid()); - return &newNode; - } - UNIMPLEMENTED ("Node Factory for reworked Render Node Connectivity"); -#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #1367 : Rebuild the Node Invocation }} // namespace engine diff --git a/src/steam/engine/node-factory.hpp b/src/steam/engine/node-factory.hpp index 2b96c0e6f..778cdc285 100644 --- a/src/steam/engine/node-factory.hpp +++ b/src/steam/engine/node-factory.hpp @@ -26,7 +26,6 @@ #include "steam/engine/proc-node.hpp" #include "steam/mobject/placement.hpp" -//#include "steam/engine/nodewiring-obsolete.hpp" /////////////////////////////////////////////////////////TICKET #1367 : Adapt to rework of Node Invocation ////////////////////////////////////TODO: make inclusions / forward definitions a bit more orthogonal.... @@ -59,23 +58,11 @@ namespace engine { class NodeFactory { AllocationCluster& alloc_; -#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #1367 : Rebuild the Node Invocation - WiringFactory wiringFac_; -#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #1367 : Rebuild the Node Invocation public: NodeFactory (AllocationCluster& a) : alloc_(a) -#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #1367 : Rebuild the Node Invocation - , wiringFac_(alloc_) -#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #1367 : Rebuild the Node Invocation { } - - -#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #1367 : Rebuild the Node Invocation - PNode operator() (mobject::session::PEffect const&, WiringSituation&); -#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #1367 : Rebuild the Node Invocation - }; diff --git a/src/steam/engine/nodeinvocation-obsolete.hpp b/src/steam/engine/nodeinvocation-obsolete.hpp deleted file mode 100644 index 630b61caf..000000000 --- a/src/steam/engine/nodeinvocation-obsolete.hpp +++ /dev/null @@ -1,233 +0,0 @@ -/* - NODEINVOCATION.hpp - Organise the invocation state within a single pull() call - - Copyright (C) - 2008, 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 -  Free Software Foundation; either version 2 of the License, or (at your -  option) any later version. See the file COPYING for further details. - -*/ - -/** @file nodeinvocation-obsolete.hpp - ** Organise the state related to the invocation of s single ProcNode::pull() call - ** This header defines part of the "glue" which holds together the render node network - ** and enables to pull result frames from the nodes. Doing so requires some invocation - ** local state to be maintained, especially a table of buffers used to carry out the - ** calculations. Further, getting the input buffers filled requires to issue recursive - ** \c pull() calls, which on the whole creates a stack-like assembly of local invocation - ** state. - ** The actual steps to be carried out for a \c pull() call are dependent on the configuration - ** of the node to pull. Each node has been preconfigured by the builder with a Connectivity - ** descriptor and a concrete type of a StateAdapter. The actual sequence of steps is defined - ** in the header nodeoperation.hpp out of a set of basic operation steps. These steps all use - ** the passed in Invocation object (a sub-interface of StateAdapter) to access the various - ** aspects of the invocation state. - ** - ** # composition of the Invocation State - ** - ** For each individual ProcNode#pull() call, the WiringAdapter#callDown() builds an StateAdapter - ** instance directly on the stack, managing the actual buffer pointers and state references. Using this - ** StateAdapter, the predecessor nodes are pulled. The way these operations are carried out is encoded - ** in the actual StateAdapter type known to the NodeWiring (WiringAdapter) instance. All of these actual - ** StateAdapter types are built as implementing the engine::StateClosure interface. - ** - ** @deprecated 12/2024 the internal systematic within the Render Engine has been re-arranged altogether - ** - ** @todo relies still on an [obsoleted implementation draft](\ref bufftable-obsolete.hpp) - ** @see engine::ProcNode - ** @see engine::StateProxy - ** @see engine::FeedManifold_BuffTable_OBSOLETE - ** @see nodewiring.hpp interface for building/wiring the nodes - ** - */ - -#ifndef ENGINE_NODEINVOCATION_H -#define ENGINE_NODEINVOCATION_H - - -//#include "steam/engine/proc-node.hpp" ///////////////////////////////TODO clarify if required further on -#include "steam/engine/connectivity-obsolete.hpp" -#include "steam/engine/state-closure-obsolete.hpp" -#include "steam/engine/channel-descriptor-obsolete.hpp" -#include "steam/engine/feed-manifold-obsolete.hpp" - - - - -namespace steam { -namespace engine { - - - /** - * Adapter to shield the ProcNode from the actual buffer management, - * allowing the processing function within ProcNode to use logical - * buffer IDs. StateAdapter is created on the stack for each pull() - * call, using setup/wiring data preconfigured by the builder. - * Its job is to provide the actual implementation of the Cache - * push / fetch and recursive downcall to render the source frames. - */ - class StateAdapter - : public StateClosure_OBSOLETE - { - protected: - StateClosure_OBSOLETE& parent_; - StateClosure_OBSOLETE& current_; - - StateAdapter (StateClosure_OBSOLETE& callingProcess) - : parent_ (callingProcess), - current_(callingProcess.getCurrentImplementation()) - { } - - virtual StateClosure_OBSOLETE& getCurrentImplementation () { return current_; } - - - - public: /* === proxying the StateClosure interface === */ - - virtual void releaseBuffer (BuffHandle& bh) { current_.releaseBuffer (bh); } - - virtual void is_calculated (BuffHandle const& bh) { current_.is_calculated (bh); } - - virtual BuffHandle fetch (FrameID const& fID) { return current_.fetch (fID); } - - virtual BuffTableStorage& getBuffTableStorage() { return current_.getBuffTableStorage(); } - - // note: allocateBuffer() is chosen specifically based on the actual node wiring - - }; - - - - - - /** - * Invocation context state. - * A ref to this type is carried through the chain of NEXT::step() functions - * which form the actual invocation sequence. The various operations in this sequence - * access the context via the references in this struct, while also using the inherited - * public State interface. The object instance actually used as Invocation is created - * on the stack and parametrised according to the necessities of the invocation sequence - * actually configured. Initially, this real instance is configured without FeedManifold_BuffTable_OBSOLETE, - * because the invocation may be short-circuited due to Cache hit. Otherwise, when - * the invocation sequence actually prepares to call the process function of this - * ProcNode, a buffer table chunk is allocated by the StateProxy and wired in. - */ - struct Invocation - : StateAdapter - { - Connectivity const& wiring; - const uint outNr; - - FeedManifold_BuffTable_OBSOLETE* feedManifold; - - protected: - /** creates a new invocation context state, without FeedManifold_BuffTable_OBSOLETE */ - Invocation (StateClosure_OBSOLETE& callingProcess, Connectivity const& w, uint o) - : StateAdapter(callingProcess), - wiring(w), outNr(o), - feedManifold(0) - { } - - public: - uint nrO() const { return wiring.nrO; } - uint nrI() const { return wiring.nrI; } - uint buffTabSize() const { return nrO()+nrI(); } - - /** setup the link to an externally allocated buffer table */ - void setBuffTab (FeedManifold_BuffTable_OBSOLETE* b) { this->feedManifold = b; } - - bool - buffTab_isConsistent () - { - return (feedManifold) - && (0 < buffTabSize()) - && (nrO()+nrI() <= buffTabSize()) - && (feedManifold->inBuff == &feedManifold->outBuff[nrO()] ) - && (feedManifold->inHandle == &feedManifold->outHandle[nrO()]) - ; - } - - - public: - /** specialised version filling in the additional information, i.e - * the concrete node id and the channel number in question */ - virtual FrameID const& - genFrameID () - { - return current_.genFrameID(wiring.nodeID, outNr); - } - - virtual FrameID const& - genFrameID (NodeID const& nID, uint chanNo) - { - return current_.genFrameID (nID,chanNo); - } - - }; - - - ////////////TICKET #249 this strategy should better be hidden within the BuffHandle ctor (and type-erased after creation) - struct AllocBufferFromParent ///< using the parent StateAdapter for buffer allocations - : Invocation - { - AllocBufferFromParent (StateClosure_OBSOLETE& sta, Connectivity const& w, const uint outCh) - : Invocation(sta, w, outCh) {} - - virtual BuffHandle - allocateBuffer (const lumiera::StreamType* ty) { return parent_.allocateBuffer(ty); } ////////////TODO: actually implement the "allocate from parent" logic! - }; - - struct AllocBufferFromCache ///< using the global current StateClosure, which will delegate to Cache - : Invocation - { - AllocBufferFromCache (StateClosure_OBSOLETE& sta, Connectivity const& w, const uint outCh) - : Invocation(sta, w, outCh) {} - - virtual BuffHandle - allocateBuffer (const lumiera::StreamType* ty) { return current_.allocateBuffer(ty); } - }; - - - /** - * The real invocation context state implementation. It is created - * by the NodeWiring (Connectivity) of the processing node which - * is pulled by this invocation, hereby using the internal configuration - * information to guide the selection of the real call sequence - * - * \par assembling the call sequence implementation - * Each ProcNode#pull() call creates such a StateAdapter subclass on the stack, - * with a concrete type according to the Connectivity of the node to pull. - * This concrete type encodes a calculation Strategy, which is assembled - * as a chain of policy templates on top of OperationBase. For each of the - * possible configurations we define such a chain (see bottom of nodeoperation.hpp). - * The WiringFactory defined in nodewiring.cpp actually drives the instantiation - * of all those possible combinations. - */ - template - class ActualInvocationProcess - : public BufferProvider - , private Strategy - { - public: - ActualInvocationProcess (StateClosure_OBSOLETE& callingProcess, Connectivity const& w, const uint outCh) - : BufferProvider(callingProcess, w, outCh) - { } - - /** contains the details of Cache query and recursive calls - * to the predecessor node(s), eventually followed by the - * ProcNode::process() callback - */ - BuffHandle retrieve () - { - return Strategy::step (*this); - } - }; - - - - -}} // namespace steam::engine -#endif diff --git a/src/steam/engine/nodeoperation-obsolete.hpp b/src/steam/engine/nodeoperation-obsolete.hpp deleted file mode 100644 index f182de758..000000000 --- a/src/steam/engine/nodeoperation-obsolete.hpp +++ /dev/null @@ -1,337 +0,0 @@ -/* - NODEOPERATION.hpp - Specify how the nodes call each other and how processing is organized - - Copyright (C) - 2008, 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 -  Free Software Foundation; either version 2 of the License, or (at your -  option) any later version. See the file COPYING for further details. - -*/ - -/** @file nodeoperation-obsolete.hpp - ** Chunks of operation for invoking the rendernodes. - ** This header defines part of the "glue" which holds together the render node network - ** and enables to pull a result frames from the nodes. Especially, the aspect of - ** buffer management and cache query is covered here. Each node has been preconfigured by - ** the builder with a WiringDescriptor and a concrete type of a StateAdapter, including - ** a specific Configuration, because the node can be built to - ** - participate in the Caching or ignore the cache - ** - actually process a result or just pull frames from a source - ** - employ in-Place calculations or use separate in/out buffers - ** Additionally, each node may have a given number of input/output pins, expecting to - ** be provided with buffers holding a specific kind of data. - ** - ** \par composition of the invocation Strategy - ** For each individual ProcNode#pull() call, the WiringAdapter#callDown() builds an Invocation state - ** instance directly on the stack, holding references to the actual buffer pointers and state. Using this - ** StateAdapter, the predecessor nodes are pulled. The way these operations are carried out is encoded - ** in the actual type of Strategy, which is defined at the bottom of this header. Each Strategy is a chain - ** of elementary operations invoking each other (\c NEXT::step(invocation) ). Notably, all those possible - ** configurations are pre-built while compiling (it's a small number below 32 configuration instance). - ** To be able to select the Strategy for each configuration, we need a Factory (ConfigSelector defined in - ** nodewiring-config.hpp). which is actually instantiated and used in nodewiring.cpp, which is the object - ** file holding all those instantiations. - ** - ** - ** @deprecated 12/2024 the internal systematic within the Render Engine has been re-arranged altogether. - ** The general operation scheme is now conceptualised as a weaving-pattern - ** - ** - ** @see engine::ProcNode - ** @see engine::Invocation - ** @see engine::StateClosure - ** @see engine::NodeFactory - ** @see nodewiring-config.hpp - ** @see nodewiring.hpp interface for building/wiring the nodes - ** - */ - -#ifndef ENGINE_NODEOPERATION_H -#define ENGINE_NODEOPERATION_H - - -//#include "steam/engine/proc-node.hpp" ///////////////////////////////TODO clarify if required further on -#include "steam/engine/connectivity-obsolete.hpp" -#include "steam/engine/state-closure-obsolete.hpp" -#include "steam/engine/channel-descriptor-obsolete.hpp" -#include "steam/engine/nodeinvocation-obsolete.hpp" -#include "steam/engine/feed-manifold-obsolete.hpp" - -#include "lib/meta/util.hpp" -#include "lib/meta/configflags.hpp" -#include "lib/frameid.hpp" - - - - -namespace steam { -namespace engine { -namespace config { - - - /** - * Base class of all concrete invocation sequences. - * Provides a collection of functions used to build up the invocation sequence. - * Additionally providing a marker used to detect the existence of an concrete - * definition/specialisation for a given specific configuration. - */ - struct OperationBase - { - typedef lib::meta::Yes_t is_defined; - - BuffHandle - getSource (Invocation& ivo, uint chanNo) - { - UNIMPLEMENTED ("retrieve source data provided by the vault/scheduler"); - } - - BuffHandle - pullPredecessor (Invocation& ivo, uint chanNo) - { - UNIMPLEMENTED ("invoke pull() on the denoted predecessor node"); - } - - void - releaseBuffers(BuffHandle* table, uint slotCnt, uint slot_to_retain) //////////////TODO this is going to be implemented rather by smart-handle, Ticket #249 - { - UNIMPLEMENTED ("release all buffers with the exception of the desired output"); - } - - bool - validateBuffers (Invocation& ivo) - { - UNIMPLEMENTED ("Do a final, specifically tailored validation step on the buffers prior to invoking the process function"); - } - }; - - - template - struct QueryCache : NEXT - { - BuffHandle - step (Invocation& ivo) - { - BuffHandle fetched = ivo.fetch (ivo.genFrameID()); - if (fetched) - return fetched; - else - return NEXT::step (ivo); - } - }; - - - template - struct AllocBufferTable : NEXT - { - BuffHandle - step (Invocation& ivo) - { - BuffTableChunk buffTab (ivo.wiring, ivo.getBuffTableStorage()); - ivo.setBuffTab(&buffTab); - ASSERT (ivo.feedManifold); - ASSERT (ivo.buffTab_isConsistent()); - - return NEXT::step (ivo); - } - }; - - - template - struct PullInput : NEXT - { - BuffHandle - step (Invocation& ivo) - { - BuffHandle * inH = ivo.feedManifold->inHandle; - BuffHandle::PBuff *inBuff = ivo.feedManifold->inBuff; - - for (uint i = 0; i < ivo.nrI(); ++i ) - { - inBuff[i] = - &*(inH[i] = this->pullPredecessor(ivo,i)); // invoke predecessor - // now Input #i is ready... - } - return NEXT::step (ivo); - } - }; - - - template - struct ReadSource : NEXT - { - BuffHandle - step (Invocation& ivo) - { - BuffHandle *inH = ivo.feedManifold->inHandle; - BuffHandle *outH = ivo.feedManifold->outHandle; - BuffHandle::PBuff *inBuff = ivo.feedManifold->inBuff; - BuffHandle::PBuff *outBuff = ivo.feedManifold->outBuff; - - ASSERT (ivo.nrO() == ivo.nrI() ); - - for (uint i = 0; i < ivo.nrI(); ++i ) - { - inBuff[i] = outBuff[i] = - &*(inH[i] = outH[i] = this->getSource(ivo,i)); - // now Input #i is ready... - } - return NEXT::step (ivo); - } - }; - - - template - struct AllocOutput : NEXT - { - BuffHandle - step (Invocation& ivo) - { - ASSERT (ivo.feedManifold); - ASSERT (ivo.nrO() < ivo.buffTabSize()); - BuffHandle *outH = ivo.feedManifold->outHandle; - BuffHandle::PBuff *outBuff = ivo.feedManifold->outBuff; - - for (uint i = 0; i < ivo.nrO(); ++i ) - { - outBuff[i] = - &*(outH[i] = ivo.allocateBuffer (ivo.wiring.out[i].bufferType)); - // now Output buffer for channel #i is available... - } - return NEXT::step (ivo); - } - }; - - - template - struct ProcessData : NEXT - { - BuffHandle - step (Invocation& ivo) - { - ASSERT (ivo.feedManifold); - ASSERT (ivo.buffTab_isConsistent()); - ASSERT (this->validateBuffers(ivo)); - - // Invoke our own process() function, - // providing the array of outBuffer+inBuffer ptrs - (*ivo.wiring.procFunction) (*ivo.feedManifold->outBuff); - - return NEXT::step (ivo); - } - }; - - - template - struct FeedCache : NEXT - { - BuffHandle - step (Invocation& ivo) - { - for (uint i = 0; i < ivo.nrO(); ++i ) - { - // declare all Outputs as finished - ivo.is_calculated(ivo.feedManifold->outHandle[i]); - } - - return NEXT::step (ivo); - } - }; - - - template - struct ReleaseBuffers : NEXT /////////////////TODO: couldn't this be done automatically by BuffTab's dtor?? - { ///////////////// this would require BuffHandle to be a smart ref.... --> ///TICKET #249 - BuffHandle - step (Invocation& ivo) - { - // all buffers besides the required Output no longer needed - this->releaseBuffers(ivo.feedManifold->outHandle, - ivo.buffTabSize(), - ivo.outNr); - - return ivo.feedManifold->outHandle[ivo.outNr]; - } - }; - - - - - - /* =============================================================== */ - /* === declare the possible Assembly of these elementary steps === */ - - enum Cases - { - CACHING = 1, - PROCESS, - INPLACE, - - NOT_SET = 0, - NUM_Cases = INPLACE - }; - - - using lib::meta::Config; - ///////////////////////TODO: selecting this way isn't especially readable, - ///////////////////////////: but BufferProvider selection is going to be solved differently anyway, see Ticket #249 - template - struct SelectBuffProvider { typedef AllocBufferFromParent Type; }; - template - struct SelectBuffProvider< Config> { typedef AllocBufferFromCache Type; }; - - - template - struct Strategy ; - - - template - struct Strategy< Config> - : QueryCache< - AllocBufferTable< - PullInput< - AllocOutput< - ProcessData< - FeedCache< - ReleaseBuffers< - OperationBase > > > > > > > - { }; - - template - struct Strategy< Config> - : AllocBufferTable< - PullInput< - AllocOutput< - ProcessData< - ReleaseBuffers< - OperationBase > > > > > - { }; - - template<> - struct Strategy< Config<> > - : AllocBufferTable< - ReadSource< - ReleaseBuffers< - OperationBase > > > - { }; - - template<> - struct Strategy< Config > : Strategy< Config<> > { }; - - template<> - struct Strategy< Config > - : AllocBufferTable< - ReadSource< - AllocOutput< - ProcessData< // wiring_.processFunction is supposed to do just buffer copying here - ReleaseBuffers< - OperationBase > > > > > - { }; - - - - -}}} // namespace steam::engine::config -#endif diff --git a/src/steam/engine/nodewiring-config.hpp b/src/steam/engine/nodewiring-config.hpp deleted file mode 100644 index 4ec809eac..000000000 --- a/src/steam/engine/nodewiring-config.hpp +++ /dev/null @@ -1,225 +0,0 @@ -/* - NODEWIRING-CONFIG.hpp - Helper for representing and selecting the wiring case - - Copyright (C) - 2008, 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 -  Free Software Foundation; either version 2 of the License, or (at your -  option) any later version. See the file COPYING for further details. - -*/ - -/** @file nodewiring-config.hpp - ** Sometimes we need to choose a different implementation for dealing with - ** some special cases. While for simple cases, just testing a flag or using a - ** switch statement will do the job, matters get more difficult when we have to - ** employ a completely different execution path for each of the different cases, - ** while using a set of common building blocks. - ** \par - ** In the Lumiera render engine, right on the critical path, we need some glue code - ** for invoking the predecessor nodes when pulling a given processing node. The actual - ** sequence is quite dependent on the specific situation each node is wired up, regarding - ** buffer allocation, cache querying and the possible support for GPU processing and - ** render farms. The solution is to define specialisations of a Strategy template - ** using the specific configuration as template argument. Based on these, we can - ** create a collection of factories, which in turn will build the internal wiring - ** for the individual ProcNode instances in accordance to the situation determined - ** for this node, expressed as a set of flags. As a net result, each node has an - ** individual configuration (as opposed to creating a lot of hand-written individual - ** ProcNode subclasses), but parts of this configuration assembly is done already at - ** compile time, allowing for additional checks by typing and for possible optimisation. - ** - ** @see steam::engine::config::Strategy - ** @see nodewiring.hpp - ** @see configflags.hpp - ** @see config-flags-test.cpp - ** - */ - - -#ifndef ENGINE_NODEWIRING_CONFIG_H -#define ENGINE_NODEWIRING_CONFIG_H - - -#include "lib/meta/configflags.hpp" -#include "lib/meta/util.hpp" -#include "lib/util.hpp" - -#include -#include -#include - - -namespace steam { -namespace engine { -namespace config { - - using util::contains; - using lib::meta::FlagInfo; - - using lib::meta::CONFIG_FLAGS_MAX; - - typedef size_t IxID; ///////////////////////////////TICKET #863 - - - /** - * Helper for fabricating ProcNode Wiring configurations. - * This object builds a table of factories, holding one factory - * for each possible node configuration. Provided with the desired - * configuration encoded as bits, the related factory can be invoked, - * thus producing a product object for the given configuration. - * - * \par implementation notes - * The actual factory class is templated, so it will be defined - * at the use site of ConfigSelector. Moreover, this factory - * usually expects an ctor argument, which will be fed through - * when creating the ConfigSelector instance. This is one of - * the reasons why we go through all these complicated factory - * building: this ctor argument usually brings in a reference - * to the actual memory allocator. Thus we have to rebuild the - * ConfigSelector each time we switch and rebuild the ProcNode - * factories, which in turn happens each time we use a new - * bulk allocation memory block -- typically for each separate - * segment of the Timeline and processing node graph. - * - * Now the selection of the possible flag configurations, for which - * Factory instances are created in the table, is governed by the - * type parameter of the ConfigSelector ctor. This type parameter - * needs to be a Typelist of Typelists, each representing a flag - * configuration. The intention is to to drive this selection by - * the use of template metaprogramming for extracting all - * currently defined StateProxy object configurations. - * @todo as the factories live only within the enclosed table (map) - * we could allocate them in-place. Unfortunately this is - * non-trivial, because the STL containers employ - * value semantics and thus do a copy even on insert. - * Thus, for now we use a shared_ptr to hold the factory - * heap allocated. ---> see Ticket #248 - */ - template< template class Factory - , typename FUNC ///< common function type of all Factory instances - , typename PAR ///< ctor parameter of the Factories - > - class ConfigSelector - { - typedef std::function FacFunction; - - template - struct FactoryHolder ///< impl type erasure - : private FAC, - public FacFunction - { - FactoryHolder(PAR p) - : FAC(p), - FacFunction (static_cast (*this)) - { } - }; - - - typedef std::shared_ptr PFunc; - typedef std::map ConfigTable; - - ConfigTable possibleConfig_; ///< Table of factories - - - /** Helper: a visitor usable with FlagInfo. - * Used to create a factory for each config */ - struct FactoryTableBuilder - { - PAR ctor_param_; - ConfigTable& factories_; - - FactoryTableBuilder (ConfigTable& tab, PAR p) - : ctor_param_(p), - factories_(tab) { } - - - /* === visitation interface === */ - - typedef void Ret; - - template - void - visit (IxID code) - { - PFunc pFactory (new FactoryHolder> (ctor_param_)); - factories_[code] = pFactory; - } - - void done() {} - }; - - - public: - template - ConfigSelector(CONFS const&, PAR factory_ctor_param) - { - FactoryTableBuilder buildTable(this->possibleConfig_, - factory_ctor_param ); - // store a new Factory instance - // for each possible Flag-Configuration - FlagInfo::accept (buildTable); - } - - FacFunction& - operator[] (IxID configFlags) ///< retrieve the factory corresponding to the given config - { - if (contains (possibleConfig_, configFlags)) - return *possibleConfig_[configFlags]; - else - throw lumiera::error::Invalid("ConfigSelector: No preconfigured factory for config-bits=" - +std::bitset(configFlags).to_string()); - } - }; - - - - - using lib::meta::Yes_t; - using lib::meta::No_t; - - /** - * Helper template for semi-automatic detection if instantiation is possible. - * Requires help by the template to be tested, which needs to define a type member - * `is_defined`. The embedded metafunction Test can be used as a predicate for - * filtering types which may yield a valid instantiation of the candidate template - * in question. - * @todo 1/2016 is there no better way to achieve this, based on new language features /////////////TICKET #986 - * Basically we want a SFINAE helper not only to check if a specific instantiation - * can be formed (which would be trivial), but rather, if a specific instantiation - * has _already been defined_. An automated solution for this problem seems questionable - * by theoretic reasons; such would endanger the "One Definition Rule", since the state - * of definedness of any type may change during the course of a translation unit from - * "unknown" to "declared", "partially defined" to "fully defined". To hinge the existence - * of another type on this transitory state would introduce a dangerous statefulness into - * the meta-language, which is assumed to be stateless. - * @todo what _could_ be done though is to detect if a given template can be _default constructed_, - * which, by logical weakening, implies it has be defined at all. Would that satisfy our - * purpose here? - * @todo 1/2016 also I'm not happy with the name "Instantiation". It should be something like `is_XYZ` - */ - template class _CandidateTemplate_> - struct Instantiation - { - - template - class Test - { - typedef _CandidateTemplate_ Instance; - - template - static Yes_t check(typename U::is_defined *); - template - static No_t check(...); - - public: - static const bool value = (sizeof(Yes_t)==sizeof(check(0))); - }; - }; - - - -}}} // namespace steam::engine::config -#endif diff --git a/src/steam/engine/nodewiring-obsolete.cpp b/src/steam/engine/nodewiring-obsolete.cpp deleted file mode 100644 index fe4051dd1..000000000 --- a/src/steam/engine/nodewiring-obsolete.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/* - NodeWiring - Implementation of the node network and operation control - - Copyright (C) - 2008, 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 -  Free Software Foundation; either version 2 of the License, or (at your -  option) any later version. See the file COPYING for further details. - -* *****************************************************************/ - - -/** @file nodewiring-obsolete.cpp - ** Implementation of node wiring to build a render node network - ** @todo unfinished draft from 2009 regarding the render process - ** - ** @deprecated 12/2024 the internal systematic within the Render Engine has been re-arranged altogether; - ** instead of orchestrating generic invocation building-blocks, a collection of generic - ** _weaving-patterns_ will be instantiated directly in the library-adapter plug-ins - */ - - -//#include "steam/engine/proc-node.hpp" ///////////////////////////////TODO clarify if required further on -#include "steam/engine/connectivity-obsolete.hpp" -#include "steam/engine/nodewiring-obsolete.hpp" -#include "steam/engine/nodeoperation-obsolete.hpp" -#include "steam/engine/nodewiring-config.hpp" - -#include "lib/meta/typelist-manip.hpp" - - -namespace steam { -namespace engine { - - namespace config { - - using lib::meta::Flags; - using lib::meta::CombineFlags; - using lib::meta::DefineConfigByFlags; - using lib::meta::Apply; - using lib::meta::Filter; - - using lib::AllocationCluster; - - - typedef Flags::Tuple AllFlags; - - /** build the list of all possible flag combinations */ - typedef CombineFlags AllFlagCombinations; - - /** build a configuration type for each of those flag combinations */ - typedef Apply AllConfigs; - - /** filter those configurations which actually define a wiring strategy */ - typedef Filter::Test> PossibleConfigs; - - - - // internal details: setting up a factory for each required configuration - - - - /** - * Fabricating a Connectivity descriptor - * tailored for a specific node wiring situation. - */ - template - class WiringDescriptorFactory - { - AllocationCluster& alloc_; - - /* ==== pick actual wiring code ==== */ - typedef typename SelectBuffProvider::Type BuffProvider; - typedef ActualInvocationProcess, BuffProvider> InvocationStateType; - - // the concrete implementation of the glue code... - typedef NodeWiring ActualWiring; - - - public: - WiringDescriptorFactory(AllocationCluster& a) - : alloc_(a) {} - - Connectivity& - operator() (WiringSituation const& intendedWiring) - { - return alloc_.create (intendedWiring); - } - }; - - /** invocation signature of the factories */ - typedef Connectivity& (FunctionType)(WiringSituation const&); - - /** preconfigured table of all possible factories */ - typedef ConfigSelector< WiringDescriptorFactory ///< Factory template to instantiate - , FunctionType ///< function signature of the Factories - , AllocationCluster& ///< allocator fed to all factories - > WiringSelector; - - - struct WiringFactoryImpl - { - WiringSelector selector; - - WiringFactoryImpl (AllocationCluster& alloc) - : selector(config::PossibleConfigs::List(), alloc) - { } - }; - - } // (END) internals (namespace config) - - - - - /** As the WiringFactory (and all the embedded factories - * for the specific wiring situations) use the AllocationCluster - * of the current build process, we need to create a new instance - * for each newly built segment of the low-level model. - * @note This ctor creates a WiringFactoryImpl instance, thus - * compiling this definition actually drives the necessary - * template instantiations for all cases encountered while - * building the node network. - */ - WiringFactory::WiringFactory (lib::AllocationCluster& a) - : alloc_(a), - pImpl_(new config::WiringFactoryImpl (alloc_)) - { } - - - WiringFactory::~WiringFactory () {} - - - - - /** create and configure a concrete wiring descriptor to tie - * a ProcNode to its predecessor nodes. This includes selecting - * the actual StateAdapter type, configuring it based on operation - * control templates (policy classes). - * The created WiringDescriptor object is bulk allocated similar to the ProcNode - * objects for a given segment of the Timeline. It should be further configured - * with the actual predecessor nodes pointers and can then be used to create - * the new processing node to be wired up. - */ - Connectivity& - WiringFactory::operator() (WiringSituation const& setup) - { - long config = setup.getFlags(); - return pImpl_->selector[config] (setup); - } - - -}} // namespace steam::engine diff --git a/src/steam/engine/nodewiring-obsolete.hpp b/src/steam/engine/nodewiring-obsolete.hpp deleted file mode 100644 index 65faeaa61..000000000 --- a/src/steam/engine/nodewiring-obsolete.hpp +++ /dev/null @@ -1,231 +0,0 @@ -/* - NODEWIRING.hpp - Implementation of the node network and operation control - - Copyright (C) - 2008, 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 -  Free Software Foundation; either version 2 of the License, or (at your -  option) any later version. See the file COPYING for further details. - -*/ - - -/** @file nodewiring.hpp - ** Mechanism to wire ProcNode instances for a render network - ** @todo unfinished draft from 2009 regarding the render process - ** @deprecated 2024 this header will likely be obsoleted - ** @see node-wiring-builder.hpp for the rewritten node-builder - */ - - -#ifndef ENGINE_NODEWIRING_OBSOLETE_H -#define ENGINE_NODEWIRING_OBSOLETE_H - - -#include "steam/engine/connectivity-obsolete.hpp" -#include "lib/allocation-cluster.hpp" -#include "lib/ref-array.hpp" -#include "lib/util-foreach.hpp" -#include "lib/nocopy.hpp" - -#include - - - -namespace steam { -namespace engine { - - - class WiringFactory; - - namespace config { class WiringFactoryImpl; } - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : inlined here and then dropped in node-wiring-builder.hpp - using lib::RefArray; - - - /** - * Finding out about a concrete way of wiring up a - * ProcNode about to be built. Such a (temporary) setup object - * is used while building the low-level model. It is loaded with - * information concerning the intended connections to be made - * and then used to initialise the wiring descriptor, which - * in turn allows us to setup the ProcNode. - * - * \par intended usage pattern - * The goal is to describe the constellation of a new node to be built. - * Thus, we start with one or several existing nodes, specifying which - * output should go to which input pin of the yet-to-be created new node. - * When intending to create a source node, a default WiringSituation - * should be used, without adding any connection information. - * - * @deprecated WIP-WIP-WIP 2024 Node-Invocation is reworked from ground up for the »Playback Vertical Slice« - */ - class WiringSituation - : util::NonCopyable - { - long flags_; - asset::Proc::ProcFunc* function_; - - public: /* === API for querying collected data === */ - RefArray& - makeOutDescriptor() const - { - UNIMPLEMENTED ("build new output descriptors for the node under construction"); //////////TODO: where to get the information about the output channels??? - } - - RefArray& - makeInDescriptor() const - { - UNIMPLEMENTED ("build new input descriptors for the node under construction"); - } - - Connectivity::ProcFunc* - resolveProcessingFunction() const - { - REQUIRE (function_); - return function_; - } - - lumiera::NodeID const& - createNodeID() const - { - UNIMPLEMENTED ("initiate generation of a new unique node-ID"); // see rendergraph.cpp - } - - - - public: /* === API for specifying the desired wiring === */ - - /** A default WiringSituation doesn't specify any connections. - * It can be used as-is for building a source node, or augmented - * with connection information later on. - */ - WiringSituation() - : flags_(0) - , function_(0) - { - UNIMPLEMENTED ("representation of the intended wiring"); - } - - - /** Continue the wiring by hooking directly into the output - * of an existing predecessor node - */ - WiringSituation (PNode predecessor) - : flags_(0) - , function_(0) - { - UNIMPLEMENTED ("wiring representation; hook up connections 1:1"); - REQUIRE (predecessor); - - //////////////////////////TODO: see Ticket 254 - // for_each (predecessor->outputs(), ..... see also Ticket 183 (invoking member fun in for_each) - - } - - - /** set up a connection leading to a specific input pin of the new node */ - WiringSituation& - defineInput (uint inPin, PNode pred, uint outPin) - { - UNIMPLEMENTED ("wiring representation; define new connection"); - return *this; - } - - /** set up the next input connection, - * originating at a specific output pin of the predecessor */ - WiringSituation& - defineInput (PNode pred, uint outPin) - { - UNIMPLEMENTED ("wiring representation; define new connection"); - return *this; - } - - /** set up the next input connection to a specific input pin, - * originating at a the next/sole output pin of the predecessor */ - WiringSituation& - defineInput (uint inPin, PNode pred) - { - UNIMPLEMENTED ("wiring representation; define new connection"); - return *this; - } - - - /** set detail flags regarding the desired node operation mode */ - WiringSituation& - setFlag (long code) - { - flags_ |= code; - return *this; - } - - long getFlags () const { return flags_; } - - - /** trigger resolving of the actual processing function */ - WiringSituation& - resolveProcessor (asset::Proc const& procAsset) - { - function_ = procAsset.resolveProcessor(); - ENSURE (function_); - } - - }; -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : (END)inlined here and then dropped in node-wiring-builder.hpp - - - - - /** - * Actual implementation of the link between nodes, - * also acting as "track switch" for the execution path - * chosen while operating the node network for rendering. - * @param STATE Invocation state object controlling the - * behaviour of callDown() while rendering. - * @see StateAdapter - * @see NodeFactory - */ - template - class NodeWiring - : public Connectivity - { - - public: - NodeWiring(WiringSituation const& setup) - : Connectivity(setup.makeOutDescriptor(), - setup.makeInDescriptor(), - setup.resolveProcessingFunction(), - setup.createNodeID()) - { } - - private: - virtual BuffHandle - callDown (StateClosure_OBSOLETE& currentProcess, uint requestedOutputNr) const - { - STATE thisStep (currentProcess, *this, requestedOutputNr); - return thisStep.retrieve (); // fetch or calculate results - } - }; - - - - class WiringFactory - { - lib::AllocationCluster& alloc_; - std::unique_ptr pImpl_; - - public: - WiringFactory (lib::AllocationCluster& a); - ~WiringFactory (); - - Connectivity& - operator() (WiringSituation const& setup); - }; - - - -}} // namespace steam::engine -#endif diff --git a/src/steam/engine/proc-node.hpp b/src/steam/engine/proc-node.hpp index 5eda779ba..5f09ba990 100644 --- a/src/steam/engine/proc-node.hpp +++ b/src/steam/engine/proc-node.hpp @@ -168,39 +168,17 @@ namespace engine { class Connectivity { public: /* === public information record describing the node graph === */ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation + using Ports = lib::Several; using Leads = lib::Several; Ports ports; Leads leads; -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation - -// protected: -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation Connectivity (Ports&& pr, Leads&& lr) : ports(move(pr)) , leads(move(lr)) { } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation - /* ==== strategy API for configuring the node operation ==== */ - - friend class ProcNode; /////////////////////////////////OOO who needs friendship? - - /** the wiring-dependent part of the node operation. - * Includes the creation of a one-way state object on the stack - * holding the actual buffer pointers and issuing the recursive pull() calls - * @see NodeWiring#callDown default implementation - */ -#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #1367 : Rebuild the Node Invocation - virtual BuffHandle - callDown (StateClosure_OBSOLETE& currentProcess, uint requiredOutputNr) const =0; -#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #1367 : Rebuild the Node Invocation -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation }; diff --git a/src/steam/engine/renderengine.cpp b/src/steam/engine/renderengine.cpp deleted file mode 100644 index 87780adba..000000000 --- a/src/steam/engine/renderengine.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - RenderEngine - a complete network of processing nodes usable for rendering - - Copyright (C) - 2008, 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 -  Free Software Foundation; either version 2 of the License, or (at your -  option) any later version. See the file COPYING for further details. - -* *****************************************************************/ - - -/** @file renderengine.cpp - ** @deprecated a pile of crap, leftovers and started drafts, stalled since 2011 -- but maybe here to stay... - */ - - -#include "lib/error.hpp" -#include "steam/engine/renderengine.hpp" - -namespace steam { -namespace engine { - - - RenderEngine::RenderEngine() - : RenderGraph() - { - UNIMPLEMENTED("wtf... a video editor without implemented render engine??"); - } - - - /** */ - - - -}} // namespace engine diff --git a/src/steam/engine/renderengine.hpp b/src/steam/engine/renderengine.hpp deleted file mode 100644 index 4b26dc9f9..000000000 --- a/src/steam/engine/renderengine.hpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - RENDERENGINE.hpp - a complete network of processing nodes usable for rendering - - Copyright (C) - 2008, 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 -  Free Software Foundation; either version 2 of the License, or (at your -  option) any later version. See the file COPYING for further details. - -*/ - - -/** @file renderengine.hpp - ** (Planned) access point to the render engine as service. - ** @deprecated a pile of crap, leftovers and started drafts, stalled since 2011 -- but maybe here to stay... - */ - - -#ifndef STEAM_ENGINE_RENDERENGINE_H -#define STEAM_ENGINE_RENDERENGINE_H - -#include "steam/engine/rendergraph.hpp" - -#include - - - -/////////////////////////////TODO 7/11 this is a piece of debris, left over from the first attempt to complete the render nodes network. -/////////////////////////////TODO Meanwhile the intention is to treat the render nodes network more like a data structure, -/////////////////////////////TODO consequently this will become some kind of root or anchor point for this network - -//////////TODO for the "real" engine API: look at engine-serivce.hpp - -namespace steam { -namespace engine { - - using std::list; - - /** - * @todo this was planned to become the frontend - * to the render node network, which can be considered - * at the lower end of the middle layer; the actual - * render operations are mostly implemented by the vault layer - * ////////TODO WIP as of 12/2010 - */ - class RenderEngine - : public RenderGraph - { - public: - ///// TODO: find out about the public operations - // note: the play controller lives in the steam-layer, - // but is a subsystem separate of the session. - RenderEngine(); - - private: - list renderSegments; - - }; - -}} // namespace steam::engine -#endif /*STEAM_ENGINE_RENDERENGINE_H*/ diff --git a/src/steam/engine/rendergraph.cpp b/src/steam/engine/rendergraph.cpp index 951af705e..79433edae 100644 --- a/src/steam/engine/rendergraph.cpp +++ b/src/steam/engine/rendergraph.cpp @@ -18,8 +18,7 @@ #include "steam/engine/rendergraph.hpp" -#include "steam/engine/state-closure-obsolete.hpp" -#include "lib/frameid.hpp" +#include "lib/frameid.hpp" //////////////////////////////////////////////////////////////////////////////TICKET #1367 : role of frameid.hpp and NodeID could not yet be clarified (5/25) namespace lumiera { diff --git a/src/steam/engine/rendergraph.hpp b/src/steam/engine/rendergraph.hpp index 0a44d0da5..f92da6bb8 100644 --- a/src/steam/engine/rendergraph.hpp +++ b/src/steam/engine/rendergraph.hpp @@ -14,6 +14,11 @@ /** @file rendergraph.hpp ** @deprecated a pile of crap, leftovers and started drafts, stalled since 2011 -- but maybe here to stay... + ** @todo 5/2025 the »Playback Vertical Slice« was not yet helpful to clarify + ** how the top-level of the low-level-model will be organised. + ** Some considerations were made regarding ExitNode, but nothing implemented yet. + ** Might become relevant for the next »Vertical Slice«, where we want to add a clip + ** and then actually invoke a real Builder implementation. Future work! */ @@ -21,13 +26,13 @@ #define STEAM_ENGINE_RENDERGRAPH_H #include "steam/common.hpp" -#include "steam/engine/state-closure-obsolete.hpp" #include "lib/time/timevalue.hpp" /////////////////////////////TODO 7/11 this is a piece of debris, left over from the first attempt to complete the render nodes network. /////////////////////////////TODO Meanwhile the intention is to treat the render nodes network more like a data structure, /////////////////////////////TODO consequently this will become some kind of root or anchor point for this network + ///////////////////////////////////////////////////////////////////////////////////TICKET #1367 : 5/25 left in tree for now; purpose unclear, maybe relevant for the next »Vertical Slice« ? namespace steam { @@ -52,7 +57,8 @@ namespace engine { public: RenderGraph() - : segment_(Time::ZERO, FSecs(5)) + : output{nullptr} + , segment_(Time::ZERO, FSecs(5)) { UNIMPLEMENTED ("anything regarding the Fixture datastructure"); } diff --git a/src/steam/engine/state-closure-obsolete.hpp b/src/steam/engine/state-closure-obsolete.hpp deleted file mode 100644 index e8bdc70e9..000000000 --- a/src/steam/engine/state-closure-obsolete.hpp +++ /dev/null @@ -1,113 +0,0 @@ -/* - STATE-CLOSURE.hpp - Key Interface representing a render process and encapsulating state - - Copyright (C) - 2008, 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 -  Free Software Foundation; either version 2 of the License, or (at your -  option) any later version. See the file COPYING for further details. - -*/ - - -/** @file state-closure.hpp - ** Access point to an ongoing render's processing state. - ** - ** @deprecated 2024 Node-Invocation is reworked from ground up for the »Playback Vertical Slice« - */ - - -#ifndef STEAM_ENGINE_STATE_CLOSURE_OBSOLETE_H -#define STEAM_ENGINE_STATE_CLOSURE_OBSOLETE_H - - -#include "lib/error.hpp" -#include "lib/frameid.hpp" -#include "steam/engine/buffhandle.hpp" - -#include - - -namespace steam { -namespace engine { - - using lumiera::FrameID; - using lumiera::NodeID; - - class StateAdapter; - class BuffTableStorage; - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Rebuild the Node Invocation - /** - * Abstraction to access the state of a currently ongoing render/calculation process, - * as it is tied to the supporting facilities of the vault layer. An StateClosure (subclass) instance - * is the sole connection for the render node to invoke services of the vault needed - * to carry out the calculations. - * - * @see engine::RenderInvocation top-level entrance point - * @see nodeinvocation.hpp impl. used from \em within the nodes - */ - class StateClosure_OBSOLETE - { - ////////////////////////////////////////////////TICKET #826 expected to be reworked to quite some extent (9/2011) - public: - /** allocate a new writable buffer with type and size according to - * the BuffDescr. The actual provider of this buffer depends - * on the StateClosure implementation; it could be a temporary, located in - * the cache, used for feeding calculated frames over a network, etc. - * @return a BuffHandle encapsulating the information necessary to get - * at the actual buffer address and for releasing the buffer. - */ - virtual BuffHandle allocateBuffer (const lumiera::StreamType*) =0; - - /** resign control of the buffer denoted by the handle */ - virtual void releaseBuffer (BuffHandle&) =0; - - /** declare the data contained in the Buffer to be ready. - * The caller is required to restrain itself from modifying the data - * afterwards, as this buffer now can be used (readonly) by other - * calculation processes in parallel. - */ - virtual void is_calculated (BuffHandle const&) =0; - - /** generate (or calculate) an ID denoting a media data frame - * appearing at the given position in the render network, - * for the time point this rendering process is currently - * calculating data for. - * @param NodeID the unique identification of a specific node - * @param chanNo the number of the output channel of this node - * @return a complete FrameID which unambiguously denotes this - * specific frame and can be used for caching - */ - virtual FrameID const& genFrameID (NodeID const&, uint chanNo) =0; - - /** try to fetch an existing buffer containing the denoted frame - * from a cache or similar backing system (e.g. network peer). - * @return either a handle to a readonly buffer, or a null handle - * @note the client is responsible for not modifying the provided data - */ - virtual BuffHandle fetch (FrameID const&) =0; - - /** necessary for creating a local BuffTableChunk */ - virtual BuffTableStorage& getBuffTableStorage() =0; - - - protected: - virtual ~StateClosure_OBSOLETE() {}; - - /** resolves to the StateClosure object currently "in charge". - * Intended as a performance shortcut to avoid calling - * up through a chain of virtual functions when deep down - * in chained ProcNode::pull() calls. This allows derived - * classes to proxy the state interface. - */ - virtual StateClosure_OBSOLETE& getCurrentImplementation () =0; - - friend class engine::StateAdapter; - }; - -}} // namespace steam::engine -#endif /*STEAM_ENGINE_STATE_CLOSURE_OBSOLETE_H*/ diff --git a/src/steam/mobject/builder/assembler.cpp b/src/steam/mobject/builder/assembler.cpp deleted file mode 100644 index ad5969d6e..000000000 --- a/src/steam/mobject/builder/assembler.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* - Assembler - building facility (implementation of the build process) - - Copyright (C) - 2008, 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 -  Free Software Foundation; either version 2 of the License, or (at your -  option) any later version. See the file COPYING for further details. - -* *****************************************************************/ - - -/** @file assembler.cpp - ** @todo initially generated code of unclear relevance - */ - - -#include "lib/error.hpp" -#include "steam/mobject/builder/assembler.hpp" - -namespace steam { -namespace mobject { -namespace builder { - - - engine::RenderEngine & - Assembler::build () - { - UNIMPLEMENTED ("the builder..."); - } - - - -}}} // namespace steam::mobject::builder diff --git a/src/steam/mobject/builder/assembler.hpp b/src/steam/mobject/builder/assembler.hpp deleted file mode 100644 index 0e0257327..000000000 --- a/src/steam/mobject/builder/assembler.hpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - ASSEMBLER.hpp - building facility (implementation of the build process) - - Copyright (C) - 2008, 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 -  Free Software Foundation; either version 2 of the License, or (at your -  option) any later version. See the file COPYING for further details. - -*/ - - -/** @file assembler.hpp - ** @todo initially generated code of unclear relevance - */ - - -#ifndef MOBJECT_BUILDER_ASSEMBLER_H -#define MOBJECT_BUILDER_ASSEMBLER_H - -#include "steam/engine/renderengine.hpp" - - -namespace steam { -namespace mobject { -namespace builder { - - - /** - * This is the actual building facility: - * provided the correct tools and associations, - * it serves to build and connect the individual ProcNode objects - */ - class Assembler - { - public: - engine::RenderEngine& - build (); - // TODO: allocation, GC??? - }; - - - -}}} // namespace steam::mobject::builder -#endif diff --git a/src/steam/mobject/builder/toolfactory.hpp b/src/steam/mobject/builder/toolfactory.hpp index e26903275..2fd778319 100644 --- a/src/steam/mobject/builder/toolfactory.hpp +++ b/src/steam/mobject/builder/toolfactory.hpp @@ -64,7 +64,7 @@ namespace builder { /** receive the finished product of the build process; effectively * releases any other builder tool object - * @todo unclear what to do and to return here + * @todo 2025 unclear what to do and to return here ///////////////////////////////////////////////TICKET #1367 : 5/25 left in tree for now; purpose unclear, maybe relevant for the next »Vertical Slice« ? */ engine::RenderGraph& getProduct (); }; diff --git a/tests/12metaprogramming.tests b/tests/12metaprogramming.tests index e4c9cadaf..0c4c914ff 100644 --- a/tests/12metaprogramming.tests +++ b/tests/12metaprogramming.tests @@ -87,109 +87,6 @@ return: 0 END -TEST "ConfigFlags_test" ConfigFlags_test <- -out-lit: Conf2 :-<2>- -out-lit: Conf3 :-<3>- -out-lit: Conf4 :-<2>-<4>- -out-lit: AllFlags :-<1>-<2>-<3>-<4>- -out-lit: __________________________ -out-lit: __________________________ check_flags() -out-lit: Flags1 :-<2>-<4>- -out-lit: Flags2 :-<2>-<4>- -out-lit: SimpleConfig_defined_by_Typelist :-<1>- -out-lit: AnotherConfig_defined_by_Typelist :-<1>-<2>-<3>-<4>- -out-lit: __________________________ -out-lit: __________________________ check_instantiation() -out-lit: defined Conf0? ---> 0 -out-lit: defined Conf1? ---> 1 -out-lit: defined Conf2? ---> 1 -out-lit: defined Conf3? ---> 1 -out-lit: defined Conf4? ---> 1 -out-lit: defined Trash? ---> 0 -out-lit: __________________________ -out-lit: __________________________ check_filter() -out-lit: SomeFlagsets : -out-lit: +---<1>-<3>-+ -out-lit: +---<2>-<4>-+- -out-lit: Configs_defined_by_Flagsets : -out-lit: +-Conf-[-<1>-<3>-] -out-lit: +-Conf-[-<2>-<4>-]- -out-lit: Filter_possible_Configs : -out-lit: +-Conf-[-<2>-<4>-]- -out-lit: AllFlagCombinations : -out-lit: +---<1>-<2>-<3>-<4>-<·>-+ -out-lit: +---<1>-<2>-<3>-<·>-+ -out-lit: +---<1>-<2>-<4>-<·>-+ -out-lit: +---<1>-<2>-<·>-+ -out-lit: +---<1>-<3>-<4>-<·>-+ -out-lit: +---<1>-<3>-<·>-+ -out-lit: +---<1>-<4>-<·>-+ -out-lit: +---<1>-<·>-+ -out-lit: +---<2>-<3>-<4>-<·>-+ -out-lit: +---<2>-<3>-<·>-+ -out-lit: +---<2>-<4>-<·>-+ -out-lit: +---<2>-<·>-+ -out-lit: +---<3>-<4>-<·>-+ -out-lit: +---<3>-<·>-+ -out-lit: +---<4>-<·>-+ -out-lit: +---<·>-+- -out-lit: ListAllConfigs : -out-lit: +-Conf-[-<1>-<2>-<3>-<4>-] -out-lit: +-Conf-[-<1>-<2>-<3>-] -out-lit: +-Conf-[-<1>-<2>-<4>-] -out-lit: +-Conf-[-<1>-<2>-] -out-lit: +-Conf-[-<1>-<3>-<4>-] -out-lit: +-Conf-[-<1>-<3>-] -out-lit: +-Conf-[-<1>-<4>-] -out-lit: +-Conf-[-<1>-] -out-lit: +-Conf-[-<2>-<3>-<4>-] -out-lit: +-Conf-[-<2>-<3>-] -out-lit: +-Conf-[-<2>-<4>-] -out-lit: +-Conf-[-<2>-] -out-lit: +-Conf-[-<3>-<4>-] -out-lit: +-Conf-[-<3>-] -out-lit: +-Conf-[-<4>-] -out-lit: +-Conf-[-]- -out-lit: Filter_all_possible_Configs : -out-lit: +-Conf-[-<1>-] -out-lit: +-Conf-[-<2>-<3>-] -out-lit: +-Conf-[-<2>-<4>-] -out-lit: +-Conf-[-<2>-] -out-lit: +-Conf-[-<3>-]- -out-lit: __________________________ -out-lit: __________________________ check_FlagInfo() -out-lit: Flags1 :-<1>-<3>- -out-lit: max bit : 3 -out-lit: binary code: 10 -out-lit: SomeConfigs : -out-lit: +-Conf-[-<1>-<3>-] -out-lit: +-Conf-[-<2>-<4>-]- -out-lit: max bit in [SomeConfigs] : 4 -out-lit: TestVisitor application: -out-lit: visit(code=10) --> -out-lit: +-Conf-[-<1>-<3>-]- -out-lit: visit(code=20) --> -out-lit: +-Conf-[-<2>-<4>-]- -out-lit: __________________________ -out-lit: __________________________ check_ConfigSelector() -out-lit: Possible_Configs : -out-lit: +-Conf-[-<1>-] -out-lit: +-Conf-[-<2>-<3>-] -out-lit: +-Conf-[-<2>-<4>-] -out-lit: +-Conf-[-<2>-] -out-lit: +-Conf-[-<3>-]- -out-lit: Flag-code = 2 ConfigSelector() ---> 1010 -out-lit: Flag-code = 12 ConfigSelector() ---> 1023 -out-lit: Flag-code = 20 ConfigSelector() ---> 1024 -out-lit: Flag-code = 4 ConfigSelector() ---> 1020 -out-lit: Flag-code = 8 ConfigSelector() ---> 1030 -out: LUMIERA_ERROR_INVALID:invalid input or parameters.+No preconfigured factory for config-bits=10111 -return: 0 -END - - TEST "Duck typing support" DuckDetector_test < : Yes out: HasNested_Core : No diff --git a/tests/library/meta/config-flags-test.cpp b/tests/library/meta/config-flags-test.cpp deleted file mode 100644 index 2c759a759..000000000 --- a/tests/library/meta/config-flags-test.cpp +++ /dev/null @@ -1,328 +0,0 @@ -/* - ConfigFlags(Test) - generating a configuration type defined by flags - - Copyright (C) - 2008, 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 -  Free Software Foundation; either version 2 of the License, or (at your -  option) any later version. See the file COPYING for further details. - -* *****************************************************************/ - - -/** @file config-flags-test.cpp - ** \par build a type representing a single configuration defined by a set of flags - ** - ** The semi-automatic assembly of processing node invocation code utilises some - ** metaprogramming to generate a factory, which in turn produces node wiring objects - ** according to the configuration to be used for the corresponding ProcNode. This relies on - ** generating a distinct type based on a given set of configuration flags, - ** which is covered by this test. - ** - ** @see configflags.hpp - ** @see typelistmanip.hpp - ** @see nodewiring-config.hpp real world usage example - ** - */ - - -#include "lib/test/run.hpp" -#include "lib/format-string.hpp" -#include "lib/meta/generator.hpp" -#include "lib/meta/typelist-manip.hpp" -#include "lib/meta/configflags.hpp" -#include "meta/typelist-diagnostics.hpp" -#include "steam/engine/nodewiring-config.hpp" -#include "lib/format-cout.hpp" -#include "lib/util.hpp" - - -using ::test::Test; -using util::_Fmt; -using std::string; - - -namespace lib { -namespace meta { -namespace test { - - using steam::engine::config::Instantiation; - - namespace { // internal definitions - - enum Cases - { ONE = 1 - , TWO - , THR - , FOU - , NUM_Cases = FOU - - , NOT_SET = 0 - }; - - - - /* === Test data === */ - typedef Config<> Conf0; - typedef Config Conf1; - typedef Config Conf2; - typedef Config Conf3; - typedef Config Conf4; - - typedef Flags::Tuple Flags1; - typedef Flags::Tuple Flags2; - typedef Types SomeFlagsets; - - typedef Flags::Tuple AllFlags; - typedef CombineFlags AllFlagCombinations; - - - - /** a type which is only partially defined, for some configs. - * In ConfigFlags_test::check_filter() we use the metaprogramming machinery - * to figure out all possible configs for which \c struct Maybe is defined. - * (for this to work, the "defined" specialisations need to provide a - * typedef \c is_defined ) - */ - template struct Maybe; - - struct Indeed { typedef Yes_t is_defined; }; - template<> struct Maybe : Indeed { enum{ CODE = 10 }; }; - template<> struct Maybe : Indeed { enum{ CODE = 30 }; }; - - template - struct Maybe> - { - typedef Yes_t is_defined; - - enum{ CODE = 20 + Fl }; - }; - - - } // (End) internal defs - -#define PRINT_DELIMITER(TITLE) \ -cout << "__________________________\n" \ - "__________________________ " \ - << STRINGIFY(TITLE) << "\n"; - - - - - - /**********************************************************************//** - * @test check the handling of types representing a specific configuration. - * Basically, this is a bitset like feature, but working on types - * instead of runtime values. The Goal is to detect automatically - * all possible defined specialisations of some template based on - * such configuration-tuples. This allows us to assemble the glue code - * for pulling data from processing nodes out of small building blocks - * in all possible configurations. - */ - class ConfigFlags_test : public Test - { - virtual void run(Arg) - { - check_testdata (); - check_flags(); - check_instantiation (); - check_filter (); - check_FlagInfo (); - check_ConfigSelector (); - } - - - void check_testdata () - { - DISPLAY (Conf0); - DISPLAY (Conf1); - DISPLAY (Conf2); - DISPLAY (Conf3); - DISPLAY (Conf4); - - DISPLAY (AllFlags); - } - - - /** @test conversion between list-of-flags and a config-type in both directions */ - void check_flags () - { - PRINT_DELIMITER (check_flags()); - - typedef Config Flags1; - typedef Flags Flags2; - DISPLAY (Flags1); - DISPLAY (Flags2); - // should denote the same type - Flags1::Flags flags1 = Flags2::Tuple(); - Flags2::Tuple flags2 = flags1; - CHECK (1==sizeof(flags1)); // pure marker-type without content - CHECK (1==sizeof(flags2)); - - typedef DefineConfigByFlags,NullType>>::Config SimpleConfig_defined_by_Typelist; - DISPLAY (SimpleConfig_defined_by_Typelist); - - typedef DefineConfigByFlags::Config AnotherConfig_defined_by_Typelist; - DISPLAY (AnotherConfig_defined_by_Typelist); - } - - - /** @test creates a predicate template (metafunction) returning true - * iff the template \c Maybe is defined for the configuration in question - */ - void check_instantiation () - { - #define CAN_INSTANTIATE(NAME) \ - cout << "defined " \ - << STRINGIFY(NAME) \ - << "? ---> " \ - << Instantiation::Test::value << "\n"; - - PRINT_DELIMITER (check_instantiation()); - - CAN_INSTANTIATE (Conf0); - CAN_INSTANTIATE (Conf1); - CAN_INSTANTIATE (Conf2); - CAN_INSTANTIATE (Conf3); - CAN_INSTANTIATE (Conf4); - - typedef Config Trash; - CAN_INSTANTIATE (Trash); - } - - - /** @test given a list of flag-tuples, we first create config-types out of them - * and then filter out those configs for which \c template Maybe is defined - */ - void check_filter () - { - PRINT_DELIMITER (check_filter()); - - DISPLAY (SomeFlagsets); - - typedef Apply Configs_defined_by_Flagsets; - DISPLAY (Configs_defined_by_Flagsets); - - typedef Filter::Test> Filter_possible_Configs; - DISPLAY (Filter_possible_Configs); - - - DISPLAY (AllFlagCombinations); - typedef Apply ListAllConfigs; - DISPLAY (ListAllConfigs); - - typedef Filter::Test> Filter_all_possible_Configs; - DISPLAY (Filter_all_possible_Configs); - } - - - - struct TestVisitor - { - string result; ///< metafunction result - - TestVisitor() : result ("TestVisitor application:\n") {} - - /* === visitation interface === */ - typedef string Ret; - - Ret done() {return result; } - - template - void - visit (ulong code) - { - result += string (_Fmt ("visit(code=%u) -->%s\n") - % code % Printer::print() ); - } - }; - - /** @test FlagInfo metafunction, which takes as argument a list-of-flags - * as well as a list-of-lists-of-flags and especially allows to - * apply a visitor object to the latter - */ - void check_FlagInfo() - { - PRINT_DELIMITER (check_FlagInfo()); - - DISPLAY (Flags1); - cout << "max bit : " << FlagInfo::BITS <<"\n"; - cout << "binary code: " << FlagInfo::CODE <<"\n"; - - typedef Apply SomeConfigs; - DISPLAY (SomeConfigs); - cout << "max bit in [SomeConfigs] : " << FlagInfo::BITS <<"\n"; - - TestVisitor visitor; - cout << FlagInfo::accept (visitor); - } - - - template - struct TestFactory - { - uint operator() () { return offset_ + Maybe::CODE; } - TestFactory(long o) : offset_(o) {} - - private: - long offset_; - }; - - - /** @test use the ConfigSelector template to build a set of factories, - * based on a set of configurations. Then invoke the appropriate - * factory by specifying the configuration bit code - */ - void check_ConfigSelector() - { - PRINT_DELIMITER (check_ConfigSelector()); - - typedef Apply ListAllConfigs; - typedef Filter::Test> Possible_Configs; - DISPLAY (Possible_Configs); - - using steam::engine::config::ConfigSelector; - typedef ConfigSelector< TestFactory // Factory template - , uint(void) // Factory function type - , long // common ctor argument - > TestFactorySelector; - - const long offset = 1000; // parameter fed to all TestFactory ctors - TestFactorySelector testConfigSelector (Possible_Configs::List(), offset); - - - #define INVOKE_CONFIG_SELECTOR(CODE) \ - cout << " Flag-code = " << CODE \ - << " ConfigSelector() ---> " \ - << testConfigSelector[CODE] () << "\n"; - - INVOKE_CONFIG_SELECTOR (2); - INVOKE_CONFIG_SELECTOR (12); - INVOKE_CONFIG_SELECTOR (20); - INVOKE_CONFIG_SELECTOR (4); - INVOKE_CONFIG_SELECTOR (8); - - try - { - INVOKE_CONFIG_SELECTOR (23); - NOTREACHED (); - } - catch (lumiera::error::Invalid& err) - { - cout << err.what() << "\n"; - lumiera_error (); // reset error flag - } - } - - - }; - - - /** Register this test class... */ - LAUNCHER (ConfigFlags_test, "unit common"); - - - -}}} // namespace lib::meta::test diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 9a9180ce3..86fa69a04 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -162820,7 +162820,7 @@ Since then others have made contributions, see the log for the history. - + @@ -162838,7 +162838,7 @@ Since then others have made contributions, see the log for the history. - + @@ -162865,7 +162865,7 @@ Since then others have made contributions, see the log for the history. - + @@ -163407,8 +163407,53 @@ Since then others have made contributions, see the log for the history. - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ das ist der Ansatz mit den Feature-Flags in Metaprogramming. +

+

+ Dieser Weg ist definitiv obsolet! +

+

+ Habe stattdessen die Feed-Manifold, und der flexible Teil besteht nun Richtung Weaving Pattern und Domain Ontologies +

+ +
+
+
+
+ + + +