Switch first Layer-Separation-Interface to expose the service implementation via lib::Depend
Actually this is on the implementation side only. Since Layer-Separation-Interfaces route each call through a binding layer, we get two Service-"Instances" to manage - on the client side we have to route into the Lumiera Interface system - on the implementation side the C-Language calls from the Interface system need to get to the actual service implementation. The latter is now managed and exposed via DependInject::ServiceInstance
This commit is contained in:
parent
be789bea59
commit
29ee5131f4
6 changed files with 89 additions and 39 deletions
|
|
@ -206,7 +206,7 @@ namespace lib {
|
|||
* @throws error::Logic (LUMIERA_ERROR_LIFECYCLE) when the default factory has already
|
||||
* been invoked at the point when calling this (re)configuration function.
|
||||
*/
|
||||
template<class IMP>
|
||||
template<class IMP =SRV>
|
||||
class ServiceInstance
|
||||
: util::MoveOnly
|
||||
{
|
||||
|
|
@ -221,11 +221,38 @@ namespace lib {
|
|||
activateServiceAccess (*instance_);
|
||||
}
|
||||
|
||||
/** create in deactivated state. Can be [activated](\ref #createInstance) later */
|
||||
ServiceInstance()
|
||||
: instance_{}
|
||||
{
|
||||
__assert_compatible<IMP>();
|
||||
}
|
||||
|
||||
~ServiceInstance()
|
||||
{
|
||||
deactivateServiceAccess();
|
||||
shutdown();
|
||||
}
|
||||
|
||||
template<typename...ARGS>
|
||||
IMP&
|
||||
createInstance(ARGS&& ...ctorArgs)
|
||||
{
|
||||
instance_.reset (new IMP(forward<ARGS> (ctorArgs)...));
|
||||
activateServiceAccess (*instance_);
|
||||
return *instance_;
|
||||
}
|
||||
|
||||
void
|
||||
shutdown() noexcept
|
||||
{
|
||||
if (instance_)
|
||||
{
|
||||
deactivateServiceAccess();
|
||||
instance_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
explicit
|
||||
operator bool() const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -313,6 +313,17 @@ namespace lib {
|
|||
ENSURE (object);
|
||||
return *object;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* allow to "peek" if a dependency is already available and exposed.
|
||||
* @remark relevant when C code relies on a service with lifecycle.
|
||||
*/
|
||||
explicit
|
||||
operator bool() const
|
||||
{
|
||||
return instance.load (std::memory_order_acquire);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@
|
|||
#include "proc/control/session-command-service.hpp"
|
||||
#include "proc/mobject/session.hpp"
|
||||
#include "backend/thread-wrapper.hpp"
|
||||
#include "lib/depend-inject.hpp"
|
||||
#include "lib/util.hpp" ///////////////TODO for test command invocation
|
||||
|
||||
#include <memory>
|
||||
|
|
@ -116,9 +117,10 @@ namespace control {
|
|||
, public CommandDispatch
|
||||
, public Sync<RecursiveLock_Waitable>
|
||||
{
|
||||
using ServiceHandle = lib::DependInject<SessionCommandService>::ServiceInstance<>;
|
||||
|
||||
/** manage the primary public Session interface */
|
||||
unique_ptr<SessionCommandService> commandService_;
|
||||
ServiceHandle commandService_;
|
||||
|
||||
CommandQueue queue_;
|
||||
Looper looper_;
|
||||
|
|
@ -135,8 +137,8 @@ namespace control {
|
|||
*/
|
||||
DispatcherLoop (Subsys::SigTerm notification)
|
||||
: Thread{"Lumiera Session", bind (&DispatcherLoop::runSessionThread, this, notification)}
|
||||
, commandService_()
|
||||
, queue_()
|
||||
, commandService_{}
|
||||
, queue_{}
|
||||
, looper_([&]() -> bool
|
||||
{
|
||||
return not queue_.empty();
|
||||
|
|
@ -145,15 +147,15 @@ namespace control {
|
|||
Thread::sync(); // done with setup; loop may run now....
|
||||
INFO (session, "Proc-Dispatcher running...");
|
||||
{
|
||||
Lock(this); // open public session interface:
|
||||
commandService_.reset(new SessionCommandService(*this));
|
||||
Lock(this); // open public session interface:
|
||||
commandService_.createInstance(*this);
|
||||
}
|
||||
}
|
||||
|
||||
~DispatcherLoop()
|
||||
{
|
||||
try {
|
||||
commandService_.reset(); // redundant call, to ensure session interface is closed reliably
|
||||
commandService_.shutdown(); // redundant call, to ensure session interface is closed reliably
|
||||
INFO (session, "Proc-Dispatcher stopped.");
|
||||
}
|
||||
ERROR_LOG_AND_IGNORE(session, "Stopping the Proc-Dispatcher");
|
||||
|
|
@ -181,7 +183,7 @@ namespace control {
|
|||
requestStop() noexcept
|
||||
{
|
||||
Lock sync(this);
|
||||
commandService_.reset(); // closes Session interface
|
||||
commandService_.shutdown(); // closes Session interface
|
||||
looper_.triggerShutdown();
|
||||
sync.notifyAll();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -189,9 +189,8 @@ namespace control {
|
|||
|
||||
|
||||
using lumiera::facade::LUMIERA_ERROR_FACADE_LIFECYCLE;
|
||||
typedef lib::SingletonRef<SessionCommand>::Accessor InstanceRef;
|
||||
|
||||
InstanceRef _instance; ///< a backdoor for the C Language impl to access the actual SessionCommand implementation...
|
||||
lib::Depend<SessionCommandService> _instance; ///< a backdoor for the C Language impl to access the actual SessionCommand implementation...
|
||||
|
||||
|
||||
|
||||
|
|
@ -206,7 +205,7 @@ namespace control {
|
|||
if (!_instance)
|
||||
return lumiera_error_set(LUMIERA_ERROR_FACADE_LIFECYCLE, cmdID);
|
||||
else
|
||||
return _instance->cycle(cmdID, invocationID);
|
||||
return _instance().cycle(cmdID, invocationID);
|
||||
}
|
||||
)
|
||||
, LUMIERA_INTERFACE_INLINE (trigger,
|
||||
|
|
@ -214,7 +213,7 @@ namespace control {
|
|||
{
|
||||
if (!_instance) lumiera_error_set(LUMIERA_ERROR_FACADE_LIFECYCLE, cmdID);
|
||||
else
|
||||
_instance->trigger(cmdID, *static_cast<Rec const *> (args));
|
||||
_instance().trigger(cmdID, *static_cast<Rec const *> (args));
|
||||
}
|
||||
)
|
||||
, LUMIERA_INTERFACE_INLINE (bindArg,
|
||||
|
|
@ -222,7 +221,7 @@ namespace control {
|
|||
{
|
||||
if (!_instance) lumiera_error_set(LUMIERA_ERROR_FACADE_LIFECYCLE, cmdID);
|
||||
else
|
||||
_instance->bindArg(cmdID, *static_cast<Rec const *> (args));
|
||||
_instance().bindArg(cmdID, *static_cast<Rec const *> (args));
|
||||
}
|
||||
)
|
||||
, LUMIERA_INTERFACE_INLINE (invoke,
|
||||
|
|
@ -230,7 +229,7 @@ namespace control {
|
|||
{
|
||||
if (!_instance) lumiera_error_set(LUMIERA_ERROR_FACADE_LIFECYCLE, cmdID);
|
||||
else
|
||||
_instance->invoke(cmdID);
|
||||
_instance().invoke(cmdID);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
|
@ -241,15 +240,14 @@ namespace control {
|
|||
|
||||
|
||||
|
||||
|
||||
SessionCommandService::SessionCommandService (CommandDispatch& dispatcherLoopInterface)
|
||||
/** @remark actual instance created from within ProcDispatcher */
|
||||
SessionCommandService::SessionCommandService (CommandDispatch& dispatcherLoopInterface)
|
||||
: dispatcher_{dispatcherLoopInterface}
|
||||
, instanceManager_{dispatcher_}
|
||||
, implInstance_{this,_instance}
|
||||
, serviceInstance_{ LUMIERA_INTERFACE_REF (lumieraorg_SessionCommand, 0, lumieraorg_SessionCommandService)}
|
||||
{
|
||||
INFO (gui, "SessionCommand Facade opened.");
|
||||
}
|
||||
{
|
||||
INFO (gui, "SessionCommand Facade opened.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@
|
|||
#include "proc/control/command-dispatch.hpp"
|
||||
#include "proc/control/command-instance-manager.hpp"
|
||||
#include "common/instancehandle.hpp"
|
||||
#include "lib/singleton-ref.hpp"
|
||||
#include "lib/diff/gen-node.hpp"
|
||||
#include "lib/nocopy.hpp"
|
||||
#include "lib/symbol.hpp"
|
||||
|
|
@ -85,26 +84,23 @@ namespace control {
|
|||
CommandInstanceManager instanceManager_;
|
||||
|
||||
|
||||
/* === Interface Lifecycle === */
|
||||
|
||||
using ServiceInstanceHandle = lumiera::InstanceHandle< LUMIERA_INTERFACE_INAME(lumieraorg_SessionCommand, 0)
|
||||
, SessionCommand
|
||||
>;
|
||||
ServiceInstanceHandle serviceInstance_;
|
||||
|
||||
public:
|
||||
SessionCommandService (CommandDispatch& dispatcherLoopInterface);
|
||||
|
||||
|
||||
/* === Implementation of the Facade Interface === */
|
||||
|
||||
Symbol cycle (Symbol cmdID, string const& invocationID) override;
|
||||
void trigger (Symbol cmdID, Rec const& args) override;
|
||||
void bindArg (Symbol cmdID, Rec const& args) override;
|
||||
void invoke (Symbol cmdID) override;
|
||||
|
||||
|
||||
/* === Interface Lifecycle === */
|
||||
|
||||
typedef lumiera::InstanceHandle< LUMIERA_INTERFACE_INAME(lumieraorg_SessionCommand, 0)
|
||||
, SessionCommand
|
||||
> ServiceInstanceHandle;
|
||||
|
||||
lib::SingletonRef<SessionCommand> implInstance_;
|
||||
ServiceInstanceHandle serviceInstance_;
|
||||
|
||||
public:
|
||||
SessionCommandService (CommandDispatch& dispatcherLoopInterface);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -28295,8 +28295,8 @@
|
|||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1521858774321" ID="ID_302686020" MODIFIED="1521858778744" TEXT="aufräumen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1521858774321" ID="ID_302686020" MODIFIED="1522635466053" TEXT="aufräumen">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1521858779614" ID="ID_62114860" MODIFIED="1521928808594" TEXT="was ist depend4test?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1521928764171" ID="ID_507085354" MODIFIED="1521928798462" TEXT="die alte Testmock-Lösung">
|
||||
|
|
@ -28321,13 +28321,29 @@
|
|||
<node CREATED="1521928963447" ID="ID_1493572426" MODIFIED="1521929015463" TEXT="ziemlich eng mit den Interface-Proxies verbandelt">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1521928978853" ID="ID_47671209" MODIFIED="1521929006930" TEXT="diese sollten auf Depend umgestellt werden">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1521928978853" ID="ID_47671209" MODIFIED="1522635461892" TEXT="diese sollten auf Depend umgestellt werden">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1522635397309" ID="ID_1630981728" MODIFIED="1522635457722" TEXT="SessionCommandService">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1522635417932" ID="ID_826517015" MODIFIED="1522635454403" TEXT="DisplayService">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1522635433910" ID="ID_578198662" MODIFIED="1522635455354" TEXT="GuiNotification">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1522635450269" ID="ID_609069219" MODIFIED="1522635455898" TEXT="DummyPlayerService">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1521929007449" ID="ID_451474924" MODIFIED="1521929011482" TEXT="danach kann es weg">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1522635350488" ID="ID_1673980887" MODIFIED="1522635365465" TEXT="InterfaceProxy auch umstellen?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1522635366958" ID="ID_70940233" MODIFIED="1522635375297" TEXT="wäre jetzt ebenfalls denkbar"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1522033564057" ID="ID_1294295502" MODIFIED="1522632239961" TEXT="Nacharbeiten">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
|
|
|
|||
Loading…
Reference in a new issue