diff --git a/src/proc/play/output-slot-connection.hpp b/src/proc/play/output-slot-connection.hpp new file mode 100644 index 000000000..c19080ed4 --- /dev/null +++ b/src/proc/play/output-slot-connection.hpp @@ -0,0 +1,162 @@ +/* + OUTPUT-SLOT-CONNECTION.hpp - implementation API for concrete output slots + + Copyright (C) Lumiera.org + 2011, Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +/** @file output-slot-connection.hpp + ** Interface for concrete output implementations to talk to the OutputSlot frontend. + ** The OutputSlot concept helps to decouple the render engine implementation from the details + ** of handling external output connections. For this to work, a concrete implementation of such + ** an external output needs to integrate with the generic OutputSlot frontend, as used by the + ** engine. This generic frontend uses a PImpl, pointing to a ConnectionState object, which embodies + ** the actual implementation. Moreover, this actual implementation is free to use specifically crafted + ** OutputSlot::Connection elements to handle the ongoing output for individual channels. The latter + ** thus becomes the central implementation side API for providing actual output capabilities. + ** + ** @see OutputSlotProtocol_test + ** @see diagnostic-output-slot.hpp ////TODO + */ + + +#ifndef PROC_PLAY_OUTPUT_SLOT_CONNECTION_H +#define PROC_PLAY_OUTPUT_SLOT_CONNECTION_H + + +#include "lib/error.hpp" +#include "proc/play/output-slot.hpp" +#include "lib/handle.hpp" +//#include "lib/time/timevalue.hpp" +//#include "proc/engine/buffer-provider.hpp" +//#include "proc/play/timings.hpp" +#include "lib/iter-source.hpp" +#include "lib/iter-adapter-stl.hpp" +//#include "lib/sync.hpp" + +#include +#include +//#include +//#include +//#include + + +namespace proc { +namespace play { + +//using ::engine::BuffHandle; +//using ::engine::BufferProvider; +//using lib::time::Time; +//using std::string; + using lib::transform; + using lib::iter_stl::eachElm; + +//using std::vector; +//using std::tr1::shared_ptr; + using boost::scoped_ptr; + + + + + /** established output channel */ + class OutputSlot::Connection + { + public: + virtual ~Connection(); + + virtual void lock (FrameID) =0; + virtual void transfer (FrameID) =0; + virtual void pushout (FrameID) =0; + }; + + + + + class OutputSlot::ConnectionState + : public OutputSlot::Allocation + , boost::noncopyable + { + public: + virtual ~ConnectionState() { } + }; + + + template + class ConnectionStateManager + : public OutputSlot::ConnectionState + , public vector + { + + typedef OutputSlot::OpenedSinks OpenedSinks; + + + /* == Allocation Interface == */ + + OpenedSinks + getOpenedSinks() + { + REQUIRE (this->isActive()); + return transform (eachElm(*this), connectOutputSink); + } + + bool + isActive() + { + return 0 < vector::size(); + } + + + public: + ConnectionStateManager() + { + UNIMPLEMENTED ("immediately build up the necessary number of connections"); + } + + virtual + ~ConnectionStateManager() + { + UNIMPLEMENTED ("shut down all connections"); + } + + virtual + CON + buildConnection() =0; + + + private: // Implementation details + + DataSink + connectOutputSink (CON& connection) + { + DataSink newSink; + newSink.activate(&connection, shutdownConnection); + return newSink; + } + + void + shutdownConnection (CON* toClose) + { + UNIMPLEMENTED ("how to mark a connection as closed"); + } + }; + + + + +}} // namespace proc::play +#endif diff --git a/src/proc/play/output-slot.cpp b/src/proc/play/output-slot.cpp index 5f4ae9f7b..6cd3c5aa4 100644 --- a/src/proc/play/output-slot.cpp +++ b/src/proc/play/output-slot.cpp @@ -23,6 +23,7 @@ #include "lib/error.hpp" #include "proc/play/output-slot.hpp" +#include "proc/play/output-slot-connection.hpp" #include #include @@ -42,48 +43,8 @@ namespace play { } // (End) hidden service impl details - class Connection - { - public: - }; - class ConnectionState - : public OutputSlot::Allocation - , public vector - , boost::noncopyable - { - - typedef OutputSlot::OpenedSinks OpenedSinks; - - - private: /* == Allocation Interface == */ - OpenedSinks - getOpenedSinks() - { - UNIMPLEMENTED ("yield all opened channels"); - } - - bool - isActive() - { - return 0 < size(); - } - - - public: - ConnectionState() - { - UNIMPLEMENTED ("immediately build up the necessary number of connections"); - } - - virtual - ~ConnectionState() - { - UNIMPLEMENTED ("shut down all connections"); - } - }; - OutputSlot::~OutputSlot() { } // emit VTables here.... @@ -114,10 +75,19 @@ namespace play { UNIMPLEMENTED ("internal interface to determine the number of channel-connections"); - this->state_.reset(new ConnectionState()); + state_.reset (this->buildState()); return *state_; } + void + OutputSlot::disconnect() + { + if (!isFree()) + state_.reset(0); + } + + + }} // namespace proc::play diff --git a/src/proc/play/output-slot.hpp b/src/proc/play/output-slot.hpp index 70e0c7bf4..04754e4bd 100644 --- a/src/proc/play/output-slot.hpp +++ b/src/proc/play/output-slot.hpp @@ -38,7 +38,7 @@ #include "lib/error.hpp" #include "lib/handle.hpp" -#include "lib/time/timevalue.hpp" +//#include "lib/time/timevalue.hpp" #include "proc/engine/buffer-provider.hpp" #include "proc/play/timings.hpp" #include "lib/iter-source.hpp" @@ -56,7 +56,7 @@ namespace play { using ::engine::BuffHandle; using ::engine::BufferProvider; - using lib::time::Time; +//using lib::time::Time; //using std::string; //using std::vector; @@ -64,25 +64,10 @@ namespace play { using boost::scoped_ptr; - /** established output channel */ - class Connection; - /** Table to maintain connection state */ - class ConnectionState; - - - typedef int64_t FrameNr; - - - class DataSink - : public lib::Handle - { - - public: - BuffHandle lockBufferFor(FrameNr); - void emit(FrameNr); - }; + class DataSink; + typedef int64_t FrameID; @@ -94,8 +79,16 @@ namespace play { class OutputSlot : boost::noncopyable { + + protected: + + /** Table to maintain connection state */ + class ConnectionState; + scoped_ptr state_; + virtual ConnectionState* buildState() =0; + public: virtual ~OutputSlot(); @@ -113,17 +106,19 @@ namespace play { ~Allocation(); }; + /** established output channel */ + class Connection; + + /** can this OutputSlot be allocated? */ bool isFree() const; + /** claim this slot for exclusive use */ Allocation& allocate(); - protected: - friend class DataSink; - - virtual void lock (FrameNr, uint channel) =0; - virtual void transfer (FrameNr, uint channel) =0; - virtual void pushout (FrameNr, uint channel) =0; + /** disconnect from this OutputSlot + * @warning may block until DataSinks are gone */ + void disconnect(); private: @@ -131,5 +126,18 @@ namespace play { + class DataSink + : public lib::Handle + { + + public: + BuffHandle lockBufferFor(FrameID); + void emit(FrameID); + }; + + + + + }} // namespace proc::play #endif diff --git a/tests/components/proc/play/diagnostic-output-slot.hpp b/tests/components/proc/play/diagnostic-output-slot.hpp index 18a13c6b3..ffd1ce829 100644 --- a/tests/components/proc/play/diagnostic-output-slot.hpp +++ b/tests/components/proc/play/diagnostic-output-slot.hpp @@ -105,28 +105,28 @@ namespace play { bool - buffer_was_used (uint channel, FrameNr frame) + buffer_was_used (uint channel, FrameID frame) { UNIMPLEMENTED ("determine if the denoted buffer was indeed used"); } bool - buffer_unused (uint channel, FrameNr frame) + buffer_unused (uint channel, FrameID frame) { UNIMPLEMENTED ("determine if the specified buffer was never touched/locked for use"); } bool - buffer_was_closed (uint channel, FrameNr frame) + buffer_was_closed (uint channel, FrameID frame) { UNIMPLEMENTED ("determine if the specified buffer was indeed closed properly"); } bool - emitted (uint channel, FrameNr frame) + emitted (uint channel, FrameID frame) { UNIMPLEMENTED ("determine if the specivied buffer was indeed handed over for emitting output"); }