From 1101e1f1dbf8696280af27f02b83115324f7e5f7 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 3 Apr 2018 02:44:12 +0200 Subject: [PATCH] Dismantle the woefully complex interfaceproxy Accessor in favour of lib::Depend The recently rewritten lib::Depend front-end for service dependencies, together with the configuration as lib::DependInject::ServiceInstance provides all the necessary features and is even threadsafe. Beyond that, the expectation is that also the instantiation of the interface proxies can be simplified. The proxies themselves however need to be hand-written as before --- src/common/instancehandle.hpp | 9 +- src/common/interfaceproxy.cpp | 74 +----- src/gui/display-interface-proxy.hpp | 4 - src/gui/notification-interface-proxy.hpp | 10 - src/include/display-facade.h | 4 +- src/include/dummy-player-facade.h | 8 +- src/include/gui-notification-facade.h | 4 +- src/include/interfaceproxy.hpp | 54 ---- src/include/session-command-facade.h | 4 +- .../session-command-interface-proxy.hpp | 11 - .../play/dummy-player-interface-proxy.hpp | 3 - src/proc/play/dummy-player-service.cpp | 78 ------ src/proc/play/play-service.cpp | 9 - wiki/thinkPad.ichthyo.mm | 243 +++++++++++++++++- 14 files changed, 251 insertions(+), 264 deletions(-) diff --git a/src/common/instancehandle.hpp b/src/common/instancehandle.hpp index 2214be24f..a4d422922 100644 --- a/src/common/instancehandle.hpp +++ b/src/common/instancehandle.hpp @@ -127,13 +127,10 @@ namespace lumiera { using IH = InstanceHandle; using SH = ServiceHandle; - using SH::SH; + Link (IH const& iha); + ~Link (); - FA* - operator->() const - { - return SH::operator->(); - } + FA* operator->() const; }; diff --git a/src/common/interfaceproxy.cpp b/src/common/interfaceproxy.cpp index 84ce65a3f..88496ba41 100644 --- a/src/common/interfaceproxy.cpp +++ b/src/common/interfaceproxy.cpp @@ -59,75 +59,15 @@ namespace facade { * for building Facade Proxy implementations. * Typically the purpose of such a proxy is to route * any calls through the C-Bindings of the Lumiera Interface system. - * The actual storage for the concrete proxy object is embedded, - * inline within the #open() function. For access by the clients, - * a frontend-object of type \c Accessor may be placed into - * the facade interface; this accessor-frontend is basically - * a concealed static pointer to the proxy, and will be set, - * when the interface is opened. This opening and closing - * of the interface itself is controlled by the - * InstanceHandle, which in turn is typically - * created and managed within the context - * of the service implementation. + * The actual instance and thus the storage for the concrete proxy object + * is controlled via lib::DependInject::ServiceInstance, which in turn is + * embedded into and thus linked to the lifetime of a InstanceHandle to + * connect via Lumiera's Interface/Plug-in system. Typically the actual + * Service implementation object will hold an instance of that InstanceHandle + * and thus tie the opening/closing of the interface and access mechanism + * to the service lifecycle. */ template - class Holder; - - template - class Holder> - : Accessor - , protected FA - { - protected: - typedef InstanceHandle IHandle; - typedef Holder THolder; - typedef Proxy TProxy; - typedef Accessor Access; - - I& _i_; - - Holder (IHandle const& iha) - : _i_(iha.get()) - { } - - public: - static TProxy& open(IHandle const& iha) - { - static char buff[sizeof(TProxy)]; - TProxy* p = new(buff) TProxy(iha); - Access::implProxy_ = p; - return *p; - } - - static void close() - { - if (!Access::implProxy_) return; - TProxy* p = static_cast (Access::implProxy_); - Access::implProxy_ = 0; - p->~TProxy(); - } - }; - - - template - FA* Accessor::implProxy_; - - - template - void - openProxy (IHA const& iha) - { -// Proxy::open(iha); - } - - template - void - closeProxy () - { -// Proxy::close(); - } - /////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1086 : new implementation draft below.... - template class Binding; template diff --git a/src/gui/display-interface-proxy.hpp b/src/gui/display-interface-proxy.hpp index 6ead497c6..2159f3945 100644 --- a/src/gui/display-interface-proxy.hpp +++ b/src/gui/display-interface-proxy.hpp @@ -44,10 +44,6 @@ namespace lumiera { - /** storage for the facade proxy factory - * used by client code to invoke through the interface */ - lumiera::facade::Accessor Display::facade; - /// emit the vtable here into this translation unit within liblumieracommon.so... Display::~Display() { } diff --git a/src/gui/notification-interface-proxy.hpp b/src/gui/notification-interface-proxy.hpp index ae08a6686..e597436b1 100644 --- a/src/gui/notification-interface-proxy.hpp +++ b/src/gui/notification-interface-proxy.hpp @@ -41,16 +41,6 @@ #include "include/gui-notification-facade.h" #include "include/interfaceproxy.hpp" -namespace gui { - - /** storage for the facade proxy factory - * used by client code to invoke through the interface */ - lumiera::facade::Accessor GuiNotification::facade; - -} // namespace gui - - - namespace lumiera { namespace facade { using gui::ID; diff --git a/src/include/display-facade.h b/src/include/display-facade.h index c29900a83..21f2d35ca 100644 --- a/src/include/display-facade.h +++ b/src/include/display-facade.h @@ -51,7 +51,7 @@ #ifdef __cplusplus /* ============== C++ Interface ================= */ -#include "include/interfaceproxy.hpp" +#include "lib/depend.hpp" #include "lib/handle.hpp" @@ -87,7 +87,7 @@ namespace lumiera { { public: /** get an implementation instance of this service */ - static lumiera::facade::Accessor facade; + static lib::Depend facade; /** diff --git a/src/include/dummy-player-facade.h b/src/include/dummy-player-facade.h index 6a11672d4..cd26970e7 100644 --- a/src/include/dummy-player-facade.h +++ b/src/include/dummy-player-facade.h @@ -22,6 +22,7 @@ /** @file dummy-player-facade.h + * @deprecated left-over from an early design draft (2009) */ @@ -36,7 +37,7 @@ #ifdef __cplusplus /* ============== C++ Interface ================= */ #include "common/subsys.hpp" -#include "include/interfaceproxy.hpp" +#include "lib/depend.hpp" #include "lib/handle.hpp" @@ -65,7 +66,8 @@ namespace lumiera { * with our interface layout and the way we create bindings to the * implementation. The moment we attempt to use other abstractions * within an interface (as we do here with the Process interface), - * we're running into serious maintenance and library dependency problems. + * we're running into serious maintenance and library dependency problems. + * @deprecated obsoleted design from 2009 and not operative anymore (2018) */ class DummyPlayer { @@ -76,7 +78,7 @@ namespace lumiera { static lumiera::Subsys& getDescriptor(); /** get an implementation instance of this service */ - static lumiera::facade::Accessor facade; + static lib::Depend facade; class ProcessImplementationLink; diff --git a/src/include/gui-notification-facade.h b/src/include/gui-notification-facade.h index 759548f9d..3a6de7446 100644 --- a/src/include/gui-notification-facade.h +++ b/src/include/gui-notification-facade.h @@ -43,7 +43,7 @@ #ifdef __cplusplus /* ============== C++ Interface ================= */ -#include "include/interfaceproxy.hpp" +#include "lib/depend.hpp" #include "lib/diff/mutation-message.hpp" #include "lib/idi/entry-id.hpp" @@ -77,7 +77,7 @@ namespace gui { class GuiNotification { public: - static lumiera::facade::Accessor facade; + static lib::Depend facade; /** push a user visible notification text */ diff --git a/src/include/interfaceproxy.hpp b/src/include/interfaceproxy.hpp index 78ef4b9ee..ece35dff8 100644 --- a/src/include/interfaceproxy.hpp +++ b/src/include/interfaceproxy.hpp @@ -85,60 +85,6 @@ namespace lumiera { namespace facade { - /** error-ID for accessing a (currently) closed facade */ - LUMIERA_ERROR_DECLARE(FACADE_LIFECYCLE); - - - /*****************************************************************//** - * access-frontend to the implementation of a service. - * Usually, an instance of Accessor is placed as static member - * right into the facade interface used to access the service. - * This allows clients to get the current actual implementation - * of that service, just by invoking the function operator on - * that member, e.g. \c lumiera::Play::facade() - * - * The reason for this rather indirect access technique is Lifecycle: - * Service implementations may come up and go down; moreover, a service - * might be implemented through a plugin component and thus the actual - * invocation needs to be passed through a binding layer. In this case, - * clients rather access a proxy object, which then passes on any call - * through that binding layer to the actual implementation located - * "somewhere". - * - * @note the pointer to the actual implementation is a static variable. - * This has two consequences. For one, we're dealing with kind of - * singleton service here. And, secondly, the implementation or - * proxy accessor can inherit from Accessor where FA is the - * facade interface. Being a subclass, allows the implementation - * to set that pointer when the service comes up, and to clear - * it when the service goes down and the access needs to - * be closed. - */ - template - class Accessor - { - protected: - static FA* implProxy_; - - - public: - FA& - operator() () - { - if (implProxy_) - return *implProxy_; - else - throw error::State("Facade interface currently closed." - , LUMIERA_ERROR_FACADE_LIFECYCLE); - } - }; - - template - void openProxy (IHA const&); - - template - void closeProxy (); - template class Proxy; diff --git a/src/include/session-command-facade.h b/src/include/session-command-facade.h index 973f9df10..787d42a1e 100644 --- a/src/include/session-command-facade.h +++ b/src/include/session-command-facade.h @@ -51,7 +51,7 @@ #ifdef __cplusplus /* ============== C++ Interface ================= */ -#include "include/interfaceproxy.hpp" +#include "lib/depend.hpp" #include "lib/diff/gen-node.hpp" #include "lib/symbol.hpp" @@ -93,7 +93,7 @@ namespace control { class SessionCommand { public: - static lumiera::facade::Accessor facade; + static lib::Depend facade; /** start next command cycle and "open" a new anonymous command instance */ virtual Symbol cycle (Symbol cmdID, string const& invocationID) =0; diff --git a/src/proc/control/session-command-interface-proxy.hpp b/src/proc/control/session-command-interface-proxy.hpp index 33c85abed..78e652c11 100644 --- a/src/proc/control/session-command-interface-proxy.hpp +++ b/src/proc/control/session-command-interface-proxy.hpp @@ -41,17 +41,6 @@ #include "include/session-command-facade.h" #include "include/interfaceproxy.hpp" -namespace proc { -namespace control { - - /** storage for the facade proxy factory - * used by client code to invoke through the interface */ - lumiera::facade::Accessor SessionCommand::facade; - -}} // namespace proc::control - - - namespace lumiera { namespace facade { diff --git a/src/proc/play/dummy-player-interface-proxy.hpp b/src/proc/play/dummy-player-interface-proxy.hpp index 8a66398e6..c9ada3687 100644 --- a/src/proc/play/dummy-player-interface-proxy.hpp +++ b/src/proc/play/dummy-player-interface-proxy.hpp @@ -58,9 +58,6 @@ namespace lumiera { - /** storage for the DummyPlayer facade proxy factory... */ - lumiera::facade::Accessor DummyPlayer::facade; - // emit the vtable here into this translation unit within liblumieracommon.so ... DummyPlayer::~DummyPlayer() { } diff --git a/src/proc/play/dummy-player-service.cpp b/src/proc/play/dummy-player-service.cpp index 2dee57464..346f53f62 100644 --- a/src/proc/play/dummy-player-service.cpp +++ b/src/proc/play/dummy-player-service.cpp @@ -235,84 +235,6 @@ namespace proc { } // (End) hidden service impl details -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1086 : find out where the Proxy is implemented -}}//(END)proc::play -#include "include/dummy-player-facade.h" -#include "include/interfaceproxy.hpp" - -namespace lumiera{ - namespace facade { - -//////////////////////////////////////////////////////TICKET #1086 : copy-n-paste from interfaceproxy.cpp - template - class Binding; - - template - class Binding> - : public FA - { - protected: - typedef InstanceHandle IHandle; - typedef Binding IBinding; - - I& _i_; - public: /////////////////////////////////////TICKET #1086 : need to make the inherited ctor public - - Binding (IHandle const& iha) - : _i_(iha.get()) - { } - }; -//////////////////////////////////////////////////////TICKET #1086 : copy-n-paste from interfaceproxy.cpp - - typedef lumiera::InstanceHandle< LUMIERA_INTERFACE_INAME(lumieraorg_DummyPlayer, 0) - , lumiera::DummyPlayer - > IHandle_DummyPlayer; - - - template<> - class Proxy - : public Binding - { - //----Proxy-Implementation-of-DummyPlayer-------- - typedef lumiera::DummyPlayer::Process Process; - typedef proc::play::ProcessImpl ProcessImpl; - - /** @note as an optimisation we hand out a direct reference - * to the implementing process object. While this ref could - * still be passed as handle to the C Language interface, using - * it directly within the client (=GUI) bypasses the C interface - * and thus leaves us only with one level of indirection, - * irrespective if using the C or C++ interface. - * @note in hindsight this turned out as a very bad idea, - * since it complicated the definition of the facade proxy - * and created quite involved library dependency problems. - */ - Process start(LumieraDisplaySlot viewerHandle) override - { - ProcessImplementationLink* pP = static_cast (_i_.startPlay (viewerHandle)); - - if (!pP) - throw lumiera::error::State("failed to start DummyPlayer", lumiera_error()); - - return pP->createHandle(); - } - - - - public: - using IBinding::IBinding; - }; - - -// template void openProxy (IHandle_DummyPlayer const&); -// template void closeProxy (void); - - - } // namespace facade -} -namespace proc { -namespace play { -/////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1086 : find out where the Proxy is implemented diff --git a/src/proc/play/play-service.cpp b/src/proc/play/play-service.cpp index 984dbcd6d..e1f9d5f46 100644 --- a/src/proc/play/play-service.cpp +++ b/src/proc/play/play-service.cpp @@ -48,15 +48,6 @@ namespace lumiera { Play::~Play() { } // emit VTables here... - /** Storage for the lumiera::Play facade access point - * @note PlayService uses a InterfaceFacadeLink member - * for actually establishing the PlayService instance - * as implementation of lumiera::Play - */ - facade::Accessor Play::facade; - - - }//(End) namespace lumiera diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 334b6670f..67de9abeb 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -28400,16 +28400,16 @@ - - + + - - + + - - + + @@ -28424,8 +28424,7 @@ der Interface-Anbieter implementiert einen konkreten Proxy

- - +
@@ -28487,9 +28486,180 @@ + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ Modus der Definition +

+

+ und Instantiierung +

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

+ brauchen eigenen Zugriffs-Mechanismus auf ein weiteres Handle-Objekt +

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

+ ...oder sogar den ctor, das ist egal -- +

+

+ denn das Problem ist, ctor (oder activate) werden aus demjenigen Kontext heraus aufgerufen, +

+

+ der die Service-Implementierung startet und damit die Erzeugung des Proxy triggert. +

+

+ +

+

+ Dieser Kontext darf den konkreten Typ des Proxy aber genau nicht kennen (wegen Entkopplung)… +

+

+ Genau aus diesem Grunde leiten wir ja ctor/dtor der ServiceInstance(Handle)-Klasse in eine ander TU um. +

+

+ +

+

+ Problem ist nun, diese umgeleiteten Funktionsdefinitionen können nur einen Typ (Template-Parameter) bekommen, und dieser Typ wiederum muß -- zumindest als abstrakter Platzhalter -- in allen TU sichtbar sein. +

+ + +
+
+ + + + +
+
+ + + +
+ + + +
+
+
@@ -28527,8 +28697,7 @@ an der gleichen Stelle erfolgen

- - + @@ -28541,6 +28710,55 @@
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
@@ -28769,8 +28987,7 @@ bevor es statisch initialisiert sein kann...

- - +