Invocation: start with some rename-refactorings

... to plot a clearer understanding of the intended usage
This commit is contained in:
Fischlurch 2024-05-06 23:51:48 +02:00
parent bb3d565436
commit 9a435a667e
24 changed files with 222 additions and 474 deletions

View file

@ -38,7 +38,7 @@ the wiring interface
This part of the design defines how nodes can be combined and wired up by the
builder to form a network usable for rendering. For this purpose, the
link:ProcNode[] is used as a shell / container, which is then configured by a
const WiringDescriptor. Thus, the node gets to know its predecessor(s) and is
Connectivity descriptor. Thus, the node gets to know its predecessor(s) and is
preselected to use a combination of specific working modes:
* participate in caching

View file

@ -1,52 +0,0 @@
/*
CONTROLLERFACADE.hpp - Facade and service access point for the Steam Layer Controller
Copyright (C) Lumiera.org
2008, Hermann Vosseler <Ichthyostega@web.de>
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 controllerfacade.hpp
** unfinished draft for a "Steam-Layer Controller"
** @todo as of 2016 it very much looks like there wont'be any such thing...
*/
#ifndef STEAM_INTERFACE_CONTROLLERFACADE_H
#define STEAM_INTERFACE_CONTROLLERFACADE_H
namespace proc_interface
{
/**
* Interface providing unified access to the Steam-Subsystem Controller.
* Especially, this Facade class exports the functions to get a render
* engine for carrying out actual renderings.
*/
class ControllerFacade
{
//////////
};
} // namespace proc_interface
#endif

View file

@ -1,8 +1,9 @@
/*
BUFFTABLE-OBSOLTE.hpp - Old dead code to be removed when rewriting ProcNode!!!!!
FEED-MANIFOLD.hpp - data feed connection system for render nodes
Copyright (C) Lumiera.org
2008, Hermann Vosseler <Ichthyostega@web.de>
2023, Hermann Vosseler <Ichthyostega@web.de>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@ -21,14 +22,15 @@
*/
/** @file bufftable-obsolete.hpp
** @deprecated obsolete since 2009, left in tree to keep some likewise unfinished code alive.
/** @file feed-manifold.hpp
** @todo staled since 2009, picked up in 2024 in an attempt to finish the node invocation.
** @todo WIP-WIP 2024 rename and re-interpret as a connection system
** @see nodeinvocation.hpp
*/
#ifndef ENGINE_BUFFHTABLE_OBSOLETE_H
#define ENGINE_BUFFHTABLE_OBSOLETE_H
#ifndef ENGINE_FEED_MANIFOLD_H
#define ENGINE_FEED_MANIFOLD_H
#include "lib/error.hpp"
@ -40,9 +42,7 @@
#include <utility>
////////////////////////////////WARNING: obsolete code
////////////////////////////////WARNING: ...just left in tree to keep it compiling
////////////////////////////////TICKET #826 need to be reworked entirely
////////////////////////////////TICKET #826 will be reworked alltogether
namespace steam {
namespace engine {
@ -65,7 +65,7 @@ namespace engine {
* 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 BuffTable
struct BuffTable ///////////////////////////////////OOO rename into FeedManifold
{
typedef BuffHandle * PHa;
typedef BuffHandle::PBuff * PBu;
@ -164,7 +164,7 @@ namespace engine {
BuffTableStorage& sto_;
public:
BuffTableChunk (WiringDescriptor const& wd, BuffTableStorage& storage)
BuffTableChunk (Connectivity const& wd, BuffTableStorage& storage)
: siz_(wd.nrI + wd.nrO),
tab_(storage.claim (siz_)),
sto_(storage)
@ -191,4 +191,4 @@ namespace engine {
}} // namespace steam::engine
#endif
#endif /*ENGINE_FEED_MANIFOLD_H*/

View file

@ -69,7 +69,7 @@ using lib::LUID;
* Job tickets are created on demand, specialised for each segment
* of the low-level model, and for each individual feed (corresponding
* to a single model port). Once created, they are final for this segment,
* stored together with the other descriptor objects (ProcNode and WiringDescriptor)
* stored together with the other descriptor objects (ProcNode and Connectivity)
* and finally discarded in bulk, in case that segment of the low-level model becomes
* obsolete and is replaced by a newly built new version of this model segment.
*

View file

@ -1,47 +0,0 @@
/*
Mask - Video ProcNode for masking regions of the image (automatable)
Copyright (C) Lumiera.org
2008, Hermann Vosseler <Ichthyostega@web.de>
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 mask.cpp
** Mask generator node implementation
** @deprecated not clear if needed as of 2016
*/
#include "lib/error.hpp"
#include "steam/engine/mask.hpp"
namespace steam {
namespace engine {
Mask::Mask (WiringDescriptor const& wd)
: ProcNode(wd)
{
UNIMPLEMENTED("do we need a dedicated ProcNode subclass as mask generator?");
}
/** */
}}// namespace engine

View file

@ -1,54 +0,0 @@
/*
MASK.hpp - Video ProcNode for masking regions of the image (automatable)
Copyright (C) Lumiera.org
2008, Hermann Vosseler <Ichthyostega@web.de>
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 mask.hpp
** Specialised render node for generating mask (alpha channel) data.
** @todo this file is there since the very first code generation steps at start
** of the Lumiera project. It never became clear if a mask generator would
** need to be a dedicated ProcNode subclass; but in fact the project did
** not reach the point of implementing anything regarding that topic.
*/
#ifndef STEAM_ENGINE_MASK_H
#define STEAM_ENGINE_MASK_H
#include "steam/engine/proc-node.hpp"
namespace steam {
namespace engine{
class Mask
: public ProcNode
{
public:
Mask (WiringDescriptor const&);
};
}} // namespace steam::engine
#endif /*STEAM_ENGINE_MASK_H*/

View file

@ -1,5 +1,5 @@
/*
NODEWIRING-DEF.hpp - Implementation of the node network and operation control
NODE-WIRING-BUILDER.hpp - Setup of render nodes connectivity
Copyright (C) Lumiera.org
2009, Hermann Vosseler <Ichthyostega@web.de>
@ -24,7 +24,7 @@
** Helper for defining the desired wiring and operation mode for a render node.
** During the Builder run, the render nodes network is wired up starting from the
** source (generating) nodes up to the exit nodes. As the wiring is implemented through
** a const engine::WiringDescriptor, when a new node gets fabricated, all of the connections
** a const engine::Connectivity, when a new node gets fabricated, all of the connections
** to its predecessors need to be completely settled; similarly, any information pertaining
** the desired operation mode of this node need to be available. Thus we use this temporary
** information record to assemble all these pieces of information.
@ -36,8 +36,8 @@
*/
#ifndef ENGINE_NODEWIRING_DEF_H
#define ENGINE_NODEWIRING_DEF_H
#ifndef ENGINE_NODE_WIRING_BUILDER_H
#define ENGINE_NODE_WIRING_BUILDER_H
#include "steam/engine/proc-node.hpp"
@ -87,7 +87,7 @@ namespace engine {
UNIMPLEMENTED ("build new input descriptors for the node under construction");
}
WiringDescriptor::ProcFunc*
Connectivity::ProcFunc*
resolveProcessingFunction() const
{
REQUIRE (function_);
@ -183,4 +183,4 @@ namespace engine {
}} // namespace steam::engine
#endif
#endif /*ENGINE_NODE_WIRING_BUILDER_H*/

View file

@ -62,7 +62,7 @@ namespace engine {
NodeFactory::operator() (Placement<Effect> const& effect, WiringSituation& intendedWiring)
{
intendedWiring.resolveProcessor(effect->getProcAsset());
WiringDescriptor& wiring = wiringFac_(intendedWiring);
Connectivity& wiring = wiringFac_(intendedWiring);
ProcNode& newNode = alloc_.create<ProcNode> (wiring);
ENSURE (newNode.isValid());

View file

@ -29,11 +29,11 @@
** \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 WiringDescriptor
** 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.
** 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
**
@ -41,7 +41,7 @@
** 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::State interface.
** StateAdapter types are built as implementing the engine::StateClosure interface.
**
** @todo relies still on an [obsoleted implementation draft](\ref bufftable-obsolete.hpp)
** @see engine::ProcNode
@ -58,7 +58,7 @@
#include "steam/engine/proc-node.hpp"
#include "steam/engine/state-closure.hpp"
#include "steam/engine/channel-descriptor.hpp"
#include "steam/engine/bufftable-obsolete.hpp"
#include "steam/engine/feed-manifold.hpp"
@ -76,22 +76,22 @@ namespace engine {
* push / fetch and recursive downcall to render the source frames.
*/
class StateAdapter
: public State
: public StateClosure
{
protected:
State& parent_;
State& current_;
StateClosure& parent_;
StateClosure& current_;
StateAdapter (State& callingProcess)
StateAdapter (StateClosure& callingProcess)
: parent_ (callingProcess),
current_(callingProcess.getCurrentImplementation())
{ }
virtual State& getCurrentImplementation () { return current_; }
virtual StateClosure& getCurrentImplementation () { return current_; }
public: /* === proxying the State interface === */
public: /* === proxying the StateClosure interface === */
virtual void releaseBuffer (BuffHandle& bh) { current_.releaseBuffer (bh); }
@ -99,7 +99,7 @@ namespace engine {
virtual BuffHandle fetch (FrameID const& fID) { return current_.fetch (fID); }
virtual BuffTableStorage& getBuffTableStorage() { return current_.getBuffTableStorage(); }
virtual BuffTableStorage& getBuffTableStorage() { return current_.getBuffTableStorage(); }
// note: allocateBuffer() is chosen specifically based on the actual node wiring
@ -124,14 +124,14 @@ namespace engine {
struct Invocation
: StateAdapter
{
WiringDescriptor const& wiring;
Connectivity const& wiring;
const uint outNr;
BuffTable* buffTab;
protected:
/** creates a new invocation context state, without BuffTable */
Invocation (State& callingProcess, WiringDescriptor const& w, uint o)
Invocation (StateClosure& callingProcess, Connectivity const& w, uint o)
: StateAdapter(callingProcess),
wiring(w), outNr(o),
buffTab(0)
@ -176,36 +176,36 @@ namespace engine {
////////////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 (State& sta, WiringDescriptor 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 State, which will delegate to Cache
: Invocation
{
AllocBufferFromCache (State& sta, WiringDescriptor const& w, const uint outCh)
: Invocation(sta, w, outCh) {}
virtual BuffHandle
allocateBuffer (const lumiera::StreamType* ty) { return current_.allocateBuffer(ty); }
};
struct AllocBufferFromParent ///< using the parent StateAdapter for buffer allocations
: Invocation
{
AllocBufferFromParent (StateClosure& 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& 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 (WiringDescriptor) of the processing node which
* 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
* 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 WiringDescriptor of the node to pull.
* 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).
@ -218,12 +218,12 @@ namespace engine {
, private Strategy
{
public:
ActualInvocationProcess (State& callingProcess, WiringDescriptor const& w, const uint outCh)
ActualInvocationProcess (StateClosure& 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
* to the predecessor node(s), eventually followed by the
* ProcNode::process() callback
*/
BuffHandle retrieve ()

View file

@ -46,7 +46,7 @@
**
** @see engine::ProcNode
** @see engine::Invocation
** @see engine::State
** @see engine::StateClosure
** @see engine::NodeFactory
** @see nodewiring-config.hpp
** @see nodewiring.hpp interface for building/wiring the nodes
@ -60,8 +60,8 @@
#include "steam/engine/proc-node.hpp"
#include "steam/engine/state-closure.hpp"
#include "steam/engine/channel-descriptor.hpp"
#include "steam/engine/bufftable-obsolete.hpp"
#include "steam/engine/nodeinvocation.hpp"
#include "steam/engine/feed-manifold.hpp"
#include "lib/meta/util.hpp"
#include "lib/meta/configflags.hpp"

View file

@ -67,7 +67,7 @@ namespace engine {
/**
* Fabricating a WiringDescriptor
* Fabricating a Connectivity descriptor
* tailored for a specific node wiring situation.
*/
template<class CONF>
@ -87,7 +87,7 @@ namespace engine {
WiringDescriptorFactory(AllocationCluster& a)
: alloc_(a) {}
WiringDescriptor&
Connectivity&
operator() (WiringSituation const& intendedWiring)
{
return alloc_.create<ActualWiring> (intendedWiring);
@ -95,7 +95,7 @@ namespace engine {
};
/** invocation signature of the factories */
typedef WiringDescriptor& (FunctionType)(WiringSituation const&);
typedef Connectivity& (FunctionType)(WiringSituation const&);
/** preconfigured table of all possible factories */
typedef ConfigSelector< WiringDescriptorFactory ///< Factory template to instantiate
@ -147,7 +147,7 @@ namespace engine {
* with the actual predecessor nodes pointers and can then be used to create
* the new processing node to be wired up.
*/
WiringDescriptor&
Connectivity&
WiringFactory::operator() (WiringSituation const& setup)
{
long config = setup.getFlags();

View file

@ -32,8 +32,8 @@
#include "steam/engine/proc-node.hpp"
#include "steam/engine/node-wiring-builder.hpp"
#include "lib/allocation-cluster.hpp"
#include "steam/engine/nodewiring-def.hpp"
#include <memory>
@ -59,16 +59,16 @@ namespace engine {
* @param STATE Invocation state object controlling the
* behaviour of callDown() while rendering.
* @see StateAdapter
* @see NodeFactory
* @see NodeFactory
*/
template<class STATE>
class NodeWiring
: public WiringDescriptor
: public Connectivity
{
public:
NodeWiring(WiringSituation const& setup)
: WiringDescriptor(setup.makeOutDescriptor(),
: Connectivity(setup.makeOutDescriptor(),
setup.makeInDescriptor(),
setup.resolveProcessingFunction(),
setup.createNodeID())
@ -76,12 +76,11 @@ namespace engine {
private:
virtual BuffHandle
callDown (State& currentProcess, uint requestedOutputNr) const
callDown (StateClosure& currentProcess, uint requestedOutputNr) const
{
STATE thisStep (currentProcess, *this, requestedOutputNr);
return thisStep.retrieve (); // fetch or calculate results
}
};
@ -95,7 +94,7 @@ namespace engine {
WiringFactory (lib::AllocationCluster& a);
~WiringFactory ();
WiringDescriptor&
Connectivity&
operator() (WiringSituation const& setup);
};

View file

@ -24,10 +24,10 @@
** Interface to the processing nodes and the render nodes network.
**
** Actually, there are three different interfaces to consider
** - the ProcNode#pull is the invocation interface. It is call-style (easily callable by C)
** - the builder interface, comprised by the NodeFactory and the WiringFactory. It's C++ (using templates)
** - the actual processing function is supposed to be a C function; it uses a set of C functions
** for accessing the frame buffers with the data to be processed.
** - 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
@ -57,7 +57,6 @@ namespace steam {
namespace engine {
using std::vector;
using proc_interface::State;
using lumiera::NodeID;
class ProcNode;
@ -72,10 +71,10 @@ namespace engine {
* 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 WiringDescriptor, telling how it's connected to its predecessors, and
* defining how the Node is supposed to operate
* be a ProcNode and a Connectivity descriptor, telling how it's connected to its predecessors,
* and defining how the Node is supposed to operate
*/
class WiringDescriptor
class Connectivity
{
public: /* === public information record describing the node graph === */
uint nrO;
@ -90,10 +89,10 @@ namespace engine {
NodeID const& nodeID;
virtual ~WiringDescriptor() {}
virtual ~Connectivity() {}
protected:
WiringDescriptor (lib::RefArray<ChannelDescriptor>& o,
Connectivity (lib::RefArray<ChannelDescriptor>& o,
lib::RefArray<InChanDescriptor>& i,
ProcFunc pFunc, NodeID const& nID)
: out(o), in(i),
@ -115,7 +114,7 @@ namespace engine {
* @see NodeWiring#callDown default implementation
*/
virtual BuffHandle
callDown (State& currentProcess, uint requiredOutputNr) const =0;
callDown (StateClosure& currentProcess, uint requiredOutputNr) const =0;
};
@ -129,7 +128,7 @@ namespace engine {
* 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 WiringDescriptor, in which case we even might drop
* configurable element within Connectivity, in which case we even might drop
* ProcNode as a frontend entirely.
*/
class ProcNode
@ -138,10 +137,10 @@ namespace engine {
typedef mobject::Parameter<double> Param; //////TODO: just a placeholder for automation as of 6/2008
vector<Param> params;
const WiringDescriptor& wiringConfig_;
const Connectivity& wiringConfig_;
public:
ProcNode (WiringDescriptor const& wd)
ProcNode (Connectivity const& wd)
: wiringConfig_(wd)
{ }
@ -161,14 +160,14 @@ namespace engine {
* 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
* @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 (State& currentProcess, uint requestedOutputNr=0) const
pull (StateClosure& currentProcess, uint requestedOutputNr=0) const
{
return this->wiringConfig_.callDown (currentProcess, requestedOutputNr);
}

View file

@ -27,7 +27,7 @@
** @todo unfinished draft from 2009 regarding the render process
**
** @see engine::ProcNode
** @see State
** @see StateClosure
** @see node-basic-test.cpp
**
*/

View file

@ -1,42 +0,0 @@
/*
Source - Representation of a Media source
Copyright (C) Lumiera.org
2008, Hermann Vosseler <Ichthyostega@web.de>
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 source.cpp
** Implementation of a source media reading render node.
*/
#include "steam/engine/source.hpp"
namespace steam {
namespace engine {
Source::Source (WiringDescriptor const& wd)
: ProcNode(wd)
{ }
/** */
}} // namespace engine

View file

@ -1,62 +0,0 @@
/*
SOURCE.hpp - Representation of a Media source
Copyright (C) Lumiera.org
2008, Hermann Vosseler <Ichthyostega@web.de>
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 source.hpp
** Processing node to read media data.
** The render engine node network is activated by _"pulling"_ from the _exit nodes._
** Recursively, any rendering calculations will eventually hit a engine::Source node,
** to retrieve existing (raw) media data
** @todo this file is there since the very first code generation steps at start
** of the Lumiera project. It is not yet clear if those source reading nodes
** will indeed be ProcNode subclasses, or rather specifically configured
** processing nodes...
*/
#ifndef ENGINE_SOURCE_H
#define ENGINE_SOURCE_H
#include "steam/engine/proc-node.hpp"
namespace steam {
namespace engine
{
/**
* Source Node: represents a media source to pull data from.
* Source is special, because it has no predecessor nodes,
* but rather makes calls down to the vault layer internally
* to get at the raw data.
*/
class Source : public ProcNode
{
Source (WiringDescriptor const&);
};
}} // namespace steam::engine
#endif

View file

@ -49,20 +49,20 @@ namespace engine {
/**
* 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 State (subclass) instance
* 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 State
class StateClosure
{
////////////////////////////////////////////////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 BufferDescriptor. The actual provider of this buffer depends
* on the State implementation; it could be a temporary, located in
* 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.
@ -102,27 +102,18 @@ namespace engine {
protected:
virtual ~State() {};
virtual ~StateClosure() {};
/** resolves to the State object currently "in charge".
/** 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 State& getCurrentImplementation () =0;
virtual StateClosure& getCurrentImplementation () =0;
friend class engine::StateAdapter;
};
}} // namespace steam::engine
namespace proc_interface {
using steam::engine::State;
} // namespace proc_interface
#endif /*STEAM_ENGINE_STATE_CLOSURE_H*/

View file

@ -28,7 +28,7 @@
** into this recursive evaluation, beyond the data in the local call stack. Such
** additional statefull dependencies are problematic (regarding concurrency and
** throughput) and are thus abstracted from the actual processing operations
** with the help of the steam::engine::State interface
** with the help of the steam::engine::StateClosure interface
** @todo unfinished draft from 2009 regarding the render process
*/
@ -40,16 +40,16 @@
#include "steam/engine/state-closure.hpp"
namespace steam {
namespace steam {
namespace engine {
class StateProxy
: public proc_interface::State
: public StateClosure
{
private: /* === top-level implementation of the State interface === */
private: /* === top-level implementation of the StateClosure interface === */
BuffHandle allocateBuffer (const lumiera::StreamType*); //////////////////////////TICKET #828
@ -63,7 +63,7 @@ namespace engine {
BuffTableStorage& getBuffTableStorage();
virtual State& getCurrentImplementation () { return *this; }
virtual StateClosure& getCurrentImplementation () { return *this; }
};

View file

@ -1,63 +0,0 @@
/*
RENDERSTATE.hpp - renderengine state management
Copyright (C) Lumiera.org
2008, Hermann Vosseler <Ichthyostega@web.de>
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 renderstate.hpp
** Build and prepare the render state abstraction.
** The intention was to rely later, during the actual rendering, on the
** setup prepared here
** @deprecated stalled design draft from 2008 -- especially the part regarding RenderSate
** will likely be implemented in a different way
*/
#ifndef MOBJECT_BUILDER_RENDERSTATE_H
#define MOBJECT_BUILDER_RENDERSTATE_H
#include "steam/engine/state-closure.hpp"
namespace steam {
namespace mobject {
namespace builder {
typedef proc_interface::State State;
/**
* Encapsulates the logic used to get a "render process".
* The provided StateProxy serves to hold any mutable state used
* in the render process, so the rest of the render engine
* can be stateless.
* @todo probably the state management will work different (6/08)
*/
class RenderState
{
public:
State& getRenderProcess () ;
};
}}} // namespace steam::mobject::session
#endif /*MOBJECT_BUILDER_RENDERSTATE_H*/

View file

@ -53,7 +53,7 @@
** Validity of these handles will be checked on each access. The actual
** model port descriptors are owned and managed by the fixture;
** @todo they might bulk allocated in a similar manner than the
** ProcNode and WiringDescriptor objects are.
** ProcNode and Connectivity objects are.
**
** @see ModelPortRegistry_test abstract usage example
** @see ModelPortRegistry management interface

View file

@ -27,7 +27,7 @@ return: 0
END
PLANNED "buffer table" BuffTable_test <<END
PLANNED "feed manifold" FeedManifold_test <<END
return: 0
END

View file

@ -1,5 +1,5 @@
/*
BuffTable(Test) - check consistency of buffer table chunk allocation
FeedManifold(Test) - check consistency of buffer table chunk allocation
Copyright (C) Lumiera.org
2008, Hermann Vosseler <Ichthyostega@web.de>
@ -20,8 +20,8 @@
* *****************************************************/
/** @file buff-table-test.cpp
** unit test \ref BuffTable_test
/** @file feed-manifold-test.cpp
** unit test \ref FeedManifold_test
*/
@ -29,7 +29,7 @@
#include "lib/error.hpp"
#include "steam/engine/proc-node.hpp"
#include "steam/engine/bufftable-obsolete.hpp"
#include "steam/engine/feed-manifold.hpp"
#include "lib/ref-array.hpp"
#include "lib/format-cout.hpp"
@ -61,15 +61,15 @@ namespace test {
DummyArray<InChanDescriptor> dummy2;
/** a "hijacked" WiringDescriptor requesting
/** a "hijacked" Connectivity descriptor requesting
* a random number of inputs and outputs */
struct MockSizeRequest
: WiringDescriptor
: Connectivity
{
uint ii,oo;
MockSizeRequest()
: WiringDescriptor(dummy1,dummy2,0,NodeID()),
: Connectivity(dummy1,dummy2,0,NodeID()),
ii(rand() % CHUNK_MAX),
oo(rand() % CHUNK_MAX)
{ }
@ -77,7 +77,7 @@ namespace test {
virtual uint getNrI() const { return ii; }
virtual uint getNrO() const { return oo; }
virtual BuffHandle callDown (State&, uint) const
virtual BuffHandle callDown (StateClosure&, uint) const
{ throw lumiera::Error("not intended to be called"); }
};
@ -106,7 +106,7 @@ namespace test {
bool
consistencyCheck (BuffTable const& b, WiringDescriptor const& num, void* lastLevel)
consistencyCheck (BuffTable const& b, Connectivity const& num, void* lastLevel)
{
return (b.outHandle == lastLevel ) // storage is allocated continuously
&& (b.outBuff <= b.inBuff ) // input slots are behind the output slots
@ -131,7 +131,7 @@ namespace test {
* deallocated and the internal level in the storage vector
* should have doped to zero again.
*/
class BuffTable_test : public Test
class FeedManifold_test : public Test
{
using PSto = std::unique_ptr<BuffTableStorage>;
@ -179,7 +179,7 @@ namespace test {
/** Register this test class... */
LAUNCHER (BuffTable_test, "unit engine");
LAUNCHER (FeedManifold_test, "unit engine");

View file

@ -50,7 +50,7 @@ namespace test {
namespace { // Test fixture
/**
* Mock State/Invocation object.
* Mock StateClosure/Invocation object.
* Used as a replacement for the real RenderInvocation,
* so the test can verify that calculations are actually
* happening in correct order.
@ -84,7 +84,7 @@ namespace test {
AllocationCluster alloc;
NodeFactory nodeFab(alloc);
ProcNode * testSource; ///////////TODO: how to fabricate a test-Node???
ProcNode * testSource; ///////////TODO: how to fabricate a test Source-Node????
WiringSituation setup(testSource);

View file

@ -80022,8 +80022,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1714268830367" HGAP="31" ID="ID_1837848811" MODIFIED="1714328850202" TEXT="Verh&#xe4;ltnis von ModelPort &#x27f7; ExitNode &#x27f7; CalcStream &#x27f7; Feed" VSHIFT="15">
<linktarget COLOR="#ae506a" DESTINATION="ID_1837848811" ENDARROW="Default" ENDINCLINATION="-736;34;" ID="Arrow_ID_1857939913" SOURCE="ID_419173079" STARTARROW="None" STARTINCLINATION="-150;-171;"/>
<linktarget COLOR="#a9276b" DESTINATION="ID_1837848811" ENDARROW="Default" ENDINCLINATION="26;-72;" ID="Arrow_ID_1346798150" SOURCE="ID_1172676625" STARTARROW="None" STARTINCLINATION="-562;35;"/>
<linktarget COLOR="#ae506a" DESTINATION="ID_1837848811" ENDARROW="Default" ENDINCLINATION="-736;34;" ID="Arrow_ID_1857939913" SOURCE="ID_419173079" STARTARROW="None" STARTINCLINATION="-150;-171;"/>
<icon BUILTIN="flag-yellow"/>
<node CREATED="1714328873346" ID="ID_460977758" MODIFIED="1714328884461" TEXT="ModelPort und Feed entsprechen sich">
<icon BUILTIN="info"/>
@ -80479,6 +80479,18 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node CREATED="1713743244876" ID="ID_788939728" MODIFIED="1713743250142" TEXT="Einsch&#xe4;tzung">
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1713743251125" ID="ID_1888464433" MODIFIED="1713743458090" TEXT="was ich schon bef&#xfc;rchtet habe &#x2014; sehr detailiert ausimplementiert und doch &#x201e;frei schwebend&#x201c;">
<icon BUILTIN="messagebox_warning"/>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1715038313968" ID="ID_964790631" MODIFIED="1715038605412">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
an der WiringSituation bin ich <b><font color="#ed050d">gescheitert</font></b>
</p>
</body>
</html></richcontent>
<arrowlink COLOR="#a1002f" DESTINATION="ID_1007152185" ENDARROW="Default" ENDINCLINATION="-122;-926;" ID="Arrow_ID_335584613" STARTARROW="None" STARTINCLINATION="518;34;"/>
<icon BUILTIN="clanbomber"/>
</node>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1713743423876" ID="ID_1769296388" MODIFIED="1713743465725">
<richcontent TYPE="NODE"><html>
@ -80559,8 +80571,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</li>
</ul>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="idea"/>
</node>
<node CREATED="1714870821093" ID="ID_1386001047" MODIFIED="1714870851226" TEXT="OutputBuffer k&#xf6;nnen auf verschiedene Weise zur Verf&#xfc;gung stehen">
@ -80581,8 +80592,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
Rolle der <font face="Monospaced" color="#53352d">chanNo</font>&#160;im bestehenden Invocation-Code
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<node CREATED="1714912639208" ID="ID_910049756" MODIFIED="1714912937725" TEXT="die Unbestimmtheit hier h&#xe4;ngt mit der Sub/Kanal-Adressierung zusammen">
<richcontent TYPE="NOTE"><html>
<head/>
@ -80591,8 +80601,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
...welche ihrerseits ein komplexes, widerspr&#252;chliches und auf lange Sicht unbestimmtes Thema ist
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<arrowlink COLOR="#c65566" DESTINATION="ID_258322349" ENDARROW="Default" ENDINCLINATION="38;-195;" ID="Arrow_ID_1387680951" STARTARROW="None" STARTINCLINATION="225;9;"/>
<arrowlink COLOR="#aa3f74" DESTINATION="ID_739040055" ENDARROW="Default" ENDINCLINATION="-1316;83;" ID="Arrow_ID_238210700" STARTARROW="None" STARTINCLINATION="1219;30;"/>
</node>
@ -80605,8 +80614,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
Medien-Erzeugung (Sound, Bild) kann durchaus mehrere, gleichberechtigte Aspekte oder Dimensionen erzeugen, und es kann sehr wohl sein, da&#223; man einen Teil davon oder alle auch weiterverarbeitet. Beispielsweise kann eine Sound-Synthese verschiedene und miteinander verwobene Abstrahlungen nachbilden, beispielsweise in Anlehnung an ein Blasinstrument, das eine Abstrahlung am Mund hat, eine Abstrahlung des K&#246;rpers und eine Abstrahlung vom Trichter. Und man m&#246;chte diese jeweils eigens in einen virtuellen Raum einbinden k&#246;nnen. Oder eine Bild-Analyse, die ein interpoliertes Bildelement, sowie einen Bewegungsvektor desselben ausgibt
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1714913655894" ID="ID_777905676" MODIFIED="1714914285982" TEXT="komplexe Verarbeitung auf mehreren Ebenen">
<richcontent TYPE="NOTE"><html>
@ -80616,8 +80624,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
In diese Kategorie fallen alle Verarbeitungsschritte, die sich <i>nicht</i>&#160; auf komplett isolierte Primitiv-Operationen auf Einzelkan&#228;len faktorisieren lassen. Beispiel w&#228;re ein Resonanz- oder Reflexionsvorgang in einem Schallfeld, oder eine &#220;berblende- oder Overlay-Operation mit mehreren Masken-Ebenen, die neben dem Basis-Farbwert sowohl Transparenz alsauch Luminanz umfa&#223;t (also das Problem, das pre-multiplied Alpha nicht wirklich l&#246;sen kann).
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1714914301470" ID="ID_927742999" MODIFIED="1714914436555" TEXT="de-Multiplexing in Kan&#xe4;le oder Einzelframes">
<richcontent TYPE="NOTE"><html>
@ -80627,8 +80634,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
Alle &#187;de-Coder&#171; fallen tats&#228;chlich in diese Kategorie, im Besonderen beim Extrahieren von Einzelkan&#228;len zur getrennten Weiterverarbeitung, aber auch beim decodieren von komprimierten Str&#246;men in Roh-Datenframes &#252;ber eine Zeitspanne hinweg
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
</node>
<node CREATED="1714914443874" ID="ID_936224279" MODIFIED="1714914512352">
@ -80639,8 +80645,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
die eigentliche Frage ist: <b>wie &#252;bersetzt sich das in Topologie</b>?
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<richcontent TYPE="NOTE"><html>
<head/>
<body>
@ -80648,8 +80653,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
diese Frage mu&#223; wohl eigens gestellt werden &#8212; und das wird leider meistens vers&#228;umt
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
</node>
<node CREATED="1714870490954" ID="ID_433835630" MODIFIED="1714870505595" TEXT="Aufr&#xe4;umen">
@ -80697,8 +80701,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</li>
</ul>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1714269170695" ID="ID_1617973869" MODIFIED="1714269186785" TEXT="Unterschied zwischen Nodes und ExitNodes">
<icon BUILTIN="messagebox_warning"/>
@ -80717,8 +80720,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
Insofern braucht es im NodeGraph selber hier keinerlei spezielle Funktionalit&#228;t, sondern jeweils nur eine top-level-Node, deren Output zur DataSink f&#252;r den pull-Vorgang pa&#223;t. All die Services, die wir von einer ExitNode erwarten, finden auf einem Level h&#246;her statt, n&#228;mlich in der Job-Planung; dort brauchen wir diverse ID-Aufl&#246;sungen und Informationsdienste
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="forward"/>
</node>
</node>
@ -80750,8 +80752,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
...was nat&#252;rlich KISS ist; in einem zweiten Schritt repariert man diese Verschwendung durch ein mehr- oder weniger trickreiches Caching
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1714954232786" ID="ID_270340884" MODIFIED="1714955059503" TEXT="alle Outputs fallen grunds&#xe4;tzlich in einen Buffer; ein Nachfolger selektiert aus diesen">
<richcontent TYPE="NOTE"><html>
@ -80761,8 +80762,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
bei dieser Variante ist der entscheidende Aspekt, da&#223; diese Adaptierung automatisch in der Verschaltung realisiert wird; ebenso sorgt die Verschaltung daf&#252;r, ggfs den Cache mit anzusteuern
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<arrowlink COLOR="#55567b" DESTINATION="ID_1605763598" ENDARROW="Default" ENDINCLINATION="122;4;" ID="Arrow_ID_610262787" STARTARROW="Default" STARTINCLINATION="112;4;"/>
</node>
<node CREATED="1714954261920" ID="ID_1173414210" MODIFIED="1714954800194" TEXT="der Nachfolger mu&#xdf; stets alle Outputs entgegennehmen">
@ -80773,8 +80773,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
...sie werden <i>en bloc </i>in seine Liste der Inputs &#252;bernommen; erst in einem internen Adaptions-Schritt (FeedManifold) wird ggfs daraus ausgew&#228;hlt
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1714954801243" ID="ID_1605763598" MODIFIED="1714955495179" TEXT="wenn es mehrere Outputs gibt, mu&#xdf; zwingend eine Routing-Node nachgeschaltet werden">
<richcontent TYPE="NOTE"><html>
@ -80795,6 +80794,86 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node CREATED="1715037725903" ID="ID_831972019" MODIFIED="1715037738345" TEXT="Connectivity legt zus&#xe4;tzliche Freiheitsgrade fest">
<node CREATED="1715037739669" ID="ID_254890940" MODIFIED="1715037769327">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
nicht nur <i>welche </i>Vorg&#228;nger, sondern auch <i>wie </i>diese angebunden sind
</p>
</body>
</html></richcontent>
</node>
</node>
</node>
<node CREATED="1715037797261" ID="ID_1888148655" MODIFIED="1715037803336" TEXT="Erzeugen einer Node">
<node CREATED="1715037805125" ID="ID_1432652709" MODIFIED="1715037824459" TEXT="grunds&#xe4;tzlich: Konstrkution &#x2259; Verdrahtung">
<icon BUILTIN="idea"/>
</node>
<node CREATED="1715037845910" ID="ID_1617576533" MODIFIED="1715037937135" TEXT="WiringSituation &#x27f6; WiringFactory &#x27fc; Connectivity &#x27f9; ProcNode als Fa&#xe7;ade">
<icon BUILTIN="info"/>
<node CREATED="1715039318386" ID="ID_930788559" MODIFIED="1715039341769" TEXT="Doku lesen: RfC DesignRenderNodesInterface">
<icon BUILTIN="info"/>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1715038140535" ID="ID_1007152185" MODIFIED="1715038605412" TEXT="wie baut man eine WiringSituation?">
<linktarget COLOR="#a1002f" DESTINATION="ID_1007152185" ENDARROW="Default" ENDINCLINATION="-122;-926;" ID="Arrow_ID_335584613" SOURCE="ID_964790631" STARTARROW="None" STARTINCLINATION="518;34;"/>
<icon BUILTIN="help"/>
<node CREATED="1715038164036" ID="ID_1603867276" MODIFIED="1715038172778" TEXT="wird jeweils vom Vorg&#xe4;nger her konstruiert"/>
<node CREATED="1715038236922" ID="ID_1405235739" MODIFIED="1715038254462">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
das &#8222;schreit&#8220; gradezu nach einem <b>Builder</b>
</p>
</body>
</html></richcontent>
<node CREATED="1715038460764" ID="ID_739280365" MODIFIED="1715038466834" TEXT="das API ist eigentlich eine Builder"/>
<node CREATED="1715038467369" ID="ID_786662983" MODIFIED="1715038479263" TEXT="m&#xf6;glicherweise habe ich hier zwei Ebenen vermischt"/>
<node CREATED="1715038480514" ID="ID_807793427" MODIFIED="1715038523263" TEXT="die Unterscheidung von Martin Fowler: command-&amp;-control vs. DSL">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...das Buch kannte ich damals noch nicht, und das merkt man
</p>
</body>
</html></richcontent>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1715039008633" ID="ID_843551056" MODIFIED="1715039202734" TEXT="Beschlu&#xdf;: WiringSituation &#x27fc; NodeWiringBuilder">
<icon BUILTIN="yes"/>
</node>
</node>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1715038646879" ID="ID_796717158" MODIFIED="1715038668408" TEXT="sehr problematisch : Verkopplung mit Proc/Assets">
<icon BUILTIN="stop-sign"/>
<node CREATED="1715038669859" ID="ID_1764548491" MODIFIED="1715038680651" TEXT="aus damaliger Sicht war das f&#xfc;r mich offensichtlich"/>
<node CREATED="1715038681327" ID="ID_261439848" MODIFIED="1715038780263" TEXT="es f&#xfc;hrt aber zu einem gef&#xe4;hrlich monolithischen System">
<icon BUILTIN="clanbomber"/>
</node>
<node CREATED="1715038717490" ID="ID_226214844" MODIFIED="1715038783206" TEXT="und war konkret auch der Grund, warum ich damals steckenblieb">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
denn das high-Level-Model kann man genau deshalb im Kern (noch) nicht definieren, weil der Builder und das low-Level-Model fehlt
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="idea"/>
</node>
</node>
</node>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1713823635758" ID="ID_899523613" MODIFIED="1713823821818" TEXT="Gundelemente des Aufrufs">
@ -81103,8 +81182,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node CREATED="1714261510123" ID="ID_1955700140" MODIFIED="1714261512894" TEXT="Connection">
<node CREATED="1714261513554" ID="ID_1927102337" MODIFIED="1714261515950" TEXT="Stream">
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1714269206776" ID="ID_750168325" MODIFIED="1714953312547" TEXT="inwiefern ist eine ExitNode eine spezielle Node?">
<linktarget COLOR="#90498f" DESTINATION="ID_750168325" ENDARROW="Default" ENDINCLINATION="-738;-46;" ID="Arrow_ID_170319452" SOURCE="ID_497981804" STARTARROW="None" STARTINCLINATION="-825;174;"/>
<linktarget COLOR="#853dac" DESTINATION="ID_750168325" ENDARROW="Default" ENDINCLINATION="11;-193;" ID="Arrow_ID_1075271478" SOURCE="ID_697852023" STARTARROW="None" STARTINCLINATION="436;26;"/>
<linktarget COLOR="#90498f" DESTINATION="ID_750168325" ENDARROW="Default" ENDINCLINATION="-738;-46;" ID="Arrow_ID_170319452" SOURCE="ID_497981804" STARTARROW="None" STARTINCLINATION="-825;174;"/>
<icon BUILTIN="help"/>
<node CREATED="1714780261258" ID="ID_641526316" MODIFIED="1714780287711" TEXT="die ExitNode(s) liefern den Ankn&#xfc;pfungspunkt"/>
<node CREATED="1714780288611" ID="ID_1768584022" MODIFIED="1714780303677" TEXT="dagegen das Rendern ist auf jeder Node gleicherma&#xdf;en m&#xf6;glich"/>