WIP work out further how to handle start/stop of layer separation interfaces
This commit is contained in:
parent
b841ab3139
commit
e8639b8319
9 changed files with 166 additions and 29 deletions
|
|
@ -94,7 +94,7 @@ namespace lumiera
|
||||||
/** @internal helper used to delegate destroying the single instance
|
/** @internal helper used to delegate destroying the single instance
|
||||||
* to the Create policy, at the same time allowing the Life policy
|
* to the Create policy, at the same time allowing the Life policy
|
||||||
* to control the point in the Application lifecycle when the
|
* to control the point in the Application lifecycle when the
|
||||||
* destruction of this instance occures.
|
* destruction of this instance occurs.
|
||||||
*/
|
*/
|
||||||
static void destroy()
|
static void destroy()
|
||||||
{
|
{
|
||||||
|
|
@ -131,7 +131,7 @@ namespace lumiera
|
||||||
///// the object may already have been released when the runtime system calls the
|
///// the object may already have been released when the runtime system calls the
|
||||||
///// destructors of static objects at shutdown.
|
///// destructors of static objects at shutdown.
|
||||||
///// It seems this would either cost us much of the flexibility or get complicated
|
///// It seems this would either cost us much of the flexibility or get complicated
|
||||||
///// to a point where we could as well implement our own Depenency Injection Manager.
|
///// to a point where we could as well implement our own Dependency Injection Manager.
|
||||||
|
|
||||||
} // namespace lumiera
|
} // namespace lumiera
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ namespace lumiera
|
||||||
* the provided deleter function(s) at application shutdown,
|
* the provided deleter function(s) at application shutdown,
|
||||||
* relying on the runtime system calling destructors of static
|
* relying on the runtime system calling destructors of static
|
||||||
* objects. Because this Policy class can be shared between
|
* objects. Because this Policy class can be shared between
|
||||||
* several Singletons, we need to memoize all registered
|
* several Singletons, we need to memorise all registered
|
||||||
* deleter functions for calling them at shutdown.
|
* deleter functions for calling them at shutdown.
|
||||||
*/
|
*/
|
||||||
static void scheduleDelete (DelFunc kill_the_singleton)
|
static void scheduleDelete (DelFunc kill_the_singleton)
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ namespace lumiera
|
||||||
|
|
||||||
|
|
||||||
/* ********************************************************************** */
|
/* ********************************************************************** */
|
||||||
/* Forward declarations of all Classes we want to specialize the template */
|
/* Forward declarations of all Classes we want to specialise the template */
|
||||||
/* ********************************************************************** */
|
/* ********************************************************************** */
|
||||||
|
|
||||||
namespace test
|
namespace test
|
||||||
|
|
@ -87,8 +87,7 @@ namespace backend_interface
|
||||||
/* Specialisation Definitions */
|
/* Specialisation Definitions */
|
||||||
/* ************************** */
|
/* ************************** */
|
||||||
|
|
||||||
namespace lumiera
|
namespace lumiera {
|
||||||
{
|
|
||||||
|
|
||||||
using test::MockInjector;
|
using test::MockInjector;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ namespace gui {
|
||||||
namespace { // facade implementation details
|
namespace { // facade implementation details
|
||||||
|
|
||||||
|
|
||||||
class GuiNotificationFacade
|
struct GuiNotificationFacade
|
||||||
: public GuiNotification
|
: public GuiNotification
|
||||||
{
|
{
|
||||||
void
|
void
|
||||||
|
|
@ -57,37 +57,41 @@ namespace gui {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
lumiera::Singleton<GuiNotificationFacade> _facade;
|
||||||
|
|
||||||
/*=================== define an lumieraorg_guinotification instance ====================== */
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ================== define an lumieraorg_guinotification instance ======================= */
|
||||||
|
|
||||||
LUMIERA_INTERFACE_INSTANCE (lumieraorg_interfacedescriptor, 0
|
LUMIERA_INTERFACE_INSTANCE (lumieraorg_interfacedescriptor, 0
|
||||||
,lumieraorg_GuiNotificationFacade_descriptor
|
,lumieraorg_GuiNotificationFacade_descriptor
|
||||||
, NULL, NULL, NULL
|
, NULL, NULL, NULL
|
||||||
, LUMIERA_INTERFACE_INLINE (name, LUIDGEN,
|
, LUMIERA_INTERFACE_INLINE (name, "\044\117\156\365\344\056\362\220\166\350\320\214\115\221\302\177",
|
||||||
const char*, (LumieraInterface iface),
|
const char*, (LumieraInterface iface),
|
||||||
{ return "GuiNotification"; }
|
{ return "GuiNotification"; }
|
||||||
)
|
)
|
||||||
, LUMIERA_INTERFACE_INLINE (brief, LUIDGEN,
|
, LUMIERA_INTERFACE_INLINE (brief, "\160\240\102\325\175\145\270\140\350\241\163\303\331\343\253\142",
|
||||||
const char*, (LumieraInterface iface),
|
const char*, (LumieraInterface iface),
|
||||||
{ return "GUI Interface: push state update and notification of events into the GUI"; }
|
{ return "GUI Interface: push state update and notification of events into the GUI"; }
|
||||||
)
|
)
|
||||||
, LUMIERA_INTERFACE_INLINE (homepage, LUIDGEN,
|
, LUMIERA_INTERFACE_INLINE (homepage, "\217\232\066\101\042\116\054\217\070\233\253\241\166\145\234\133",
|
||||||
const char*, (LumieraInterface iface),
|
const char*, (LumieraInterface iface),
|
||||||
{ return "http://www.lumiera.org/develompent.html" ;}
|
{ return "http://www.lumiera.org/develompent.html" ;}
|
||||||
)
|
)
|
||||||
, LUMIERA_INTERFACE_INLINE (version, LUIDGEN,
|
, LUMIERA_INTERFACE_INLINE (version, "\350\365\121\052\037\022\300\021\171\357\017\367\270\071\266\376",
|
||||||
const char*, (LumieraInterface iface),
|
const char*, (LumieraInterface iface),
|
||||||
{ return "0.1~pre"; }
|
{ return "0.1~pre"; }
|
||||||
)
|
)
|
||||||
, LUMIERA_INTERFACE_INLINE (author, LUIDGEN,
|
, LUMIERA_INTERFACE_INLINE (author, "\117\007\006\234\153\206\000\344\303\043\027\261\045\320\166\133",
|
||||||
const char*, (LumieraInterface iface),
|
const char*, (LumieraInterface iface),
|
||||||
{ return "Hermann Vosseler"; }
|
{ return "Hermann Vosseler"; }
|
||||||
)
|
)
|
||||||
, LUMIERA_INTERFACE_INLINE (email, LUIDGEN,
|
, LUMIERA_INTERFACE_INLINE (email, "\356\243\022\137\345\275\016\034\337\144\031\260\303\050\140\327",
|
||||||
const char*, (LumieraInterface iface),
|
const char*, (LumieraInterface iface),
|
||||||
{ return "Ichthyostega@web.de"; }
|
{ return "Ichthyostega@web.de"; }
|
||||||
)
|
)
|
||||||
, LUMIERA_INTERFACE_INLINE (copyright, LUIDGEN,
|
, LUMIERA_INTERFACE_INLINE (copyright, "\365\220\260\051\267\345\330\046\145\134\331\320\115\157\332\356",
|
||||||
const char*, (LumieraInterface iface),
|
const char*, (LumieraInterface iface),
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
|
|
@ -95,7 +99,7 @@ namespace gui {
|
||||||
" 2008 Hermann Vosseler <Ichthyostega@web.de>";
|
" 2008 Hermann Vosseler <Ichthyostega@web.de>";
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
, LUMIERA_INTERFACE_INLINE (license, LUIDGEN,
|
, LUMIERA_INTERFACE_INLINE (license, "\155\335\361\364\221\012\115\325\306\046\153\152\002\117\075\077",
|
||||||
const char*, (LumieraInterface iface),
|
const char*, (LumieraInterface iface),
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
|
|
@ -114,11 +118,11 @@ namespace gui {
|
||||||
"Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA";
|
"Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA";
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
, LUMIERA_INTERFACE_INLINE (state, LUIDGEN,
|
, LUMIERA_INTERFACE_INLINE (state, "\227\170\230\144\310\330\131\175\367\152\327\324\113\275\223\245",
|
||||||
int, (LumieraInterface iface),
|
int, (LumieraInterface iface),
|
||||||
{return LUMIERA_INTERFACE_EXPERIMENTAL; }
|
{return LUMIERA_INTERFACE_EXPERIMENTAL; }
|
||||||
)
|
)
|
||||||
, LUMIERA_INTERFACE_INLINE (versioncmp, LUIDGEN,
|
, LUMIERA_INTERFACE_INLINE (versioncmp, "\253\066\335\233\025\161\135\347\377\156\121\135\347\313\130\014",
|
||||||
int, (const char* a, const char* b),
|
int, (const char* a, const char* b),
|
||||||
{return 0;} ////////////////////////////////////////////TODO
|
{return 0;} ////////////////////////////////////////////TODO
|
||||||
)
|
)
|
||||||
|
|
@ -128,15 +132,15 @@ namespace gui {
|
||||||
LUMIERA_INTERFACE_INSTANCE (lumieraorg_GuiNotification, 1
|
LUMIERA_INTERFACE_INSTANCE (lumieraorg_GuiNotification, 1
|
||||||
,lumieraorg_GuiNotificationFacade
|
,lumieraorg_GuiNotificationFacade
|
||||||
, LUMIERA_INTERFACE_REF(lumieraorg_interfacedescriptor, 0, lumieraorg_GuiNotificationFacade_descriptor)
|
, LUMIERA_INTERFACE_REF(lumieraorg_interfacedescriptor, 0, lumieraorg_GuiNotificationFacade_descriptor)
|
||||||
, open_facade
|
, NULL /* on open */
|
||||||
, close_facade
|
, NULL /* on close */
|
||||||
, LUMIERA_INTERFACE_INLINE (displayInfo, LUIDGEN,
|
, LUMIERA_INTERFACE_INLINE (displayInfo, "\366\075\213\163\207\040\221\233\010\366\174\374\317\126\331\205",
|
||||||
void, (const char* text),
|
void, (const char* text),
|
||||||
{ return _facade->displayInfo(text); }
|
{ return _facade().displayInfo(text); }
|
||||||
)
|
)
|
||||||
, LUMIERA_INTERFACE_INLINE (triggerGuiShutdown, LUIDGEN,
|
, LUMIERA_INTERFACE_INLINE (triggerGuiShutdown, "\267\043\244\065\107\314\370\175\063\330\264\257\302\146\326\303",
|
||||||
void, (const char* cause),
|
void, (const char* cause),
|
||||||
{ return _facade->triggerGuiShutdown(cause); }
|
{ return _facade().triggerGuiShutdown(cause); }
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
128
src/lumiera/instancehandle.hpp
Normal file
128
src/lumiera/instancehandle.hpp
Normal file
|
|
@ -0,0 +1,128 @@
|
||||||
|
/*
|
||||||
|
INSTANCEHANDLE.hpp - automatically handling interface lifecycle
|
||||||
|
|
||||||
|
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 instancehandle.hpp
|
||||||
|
** A handle template for automatically dealing with interface and plugin
|
||||||
|
** registration and deregistration. By placing an instance of this template,
|
||||||
|
** parametrised with the appropriate interface type, the respective interface
|
||||||
|
** and instance is loaded and opened through the Lumiera Interface system.
|
||||||
|
** It will be closed and unregistered automatically when the handle goes
|
||||||
|
** out of scope. Additionally, access via an (existing) interface proxy
|
||||||
|
** may be enabled and disabled alongside with the loading and unloading.
|
||||||
|
**
|
||||||
|
** @see gui::GuiFacade usage example
|
||||||
|
** @see interface.h
|
||||||
|
** @see interfaceproxy.cpp
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LUMIERA_INSTANCEHANDLE_H
|
||||||
|
#define LUMIERA_INSTANCEHANDLE_H
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "lumiera/interface.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <boost/noncopyable.hpp>
|
||||||
|
//#include <boost/scoped_ptr.hpp>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace lumiera {
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
// using boost::scoped_ptr;
|
||||||
|
|
||||||
|
namespace { // implementation details
|
||||||
|
|
||||||
|
LumieraInterface
|
||||||
|
register_and_open (LumieraInterface* descriptors)
|
||||||
|
{
|
||||||
|
if (!descriptors) return NULL;
|
||||||
|
lumiera_interfaceregistry_bulkregister_interfaces (descriptors, NULL);
|
||||||
|
LumieraInterface masterI = descriptors[0];
|
||||||
|
return lumiera_interface_open (masterI->interface,
|
||||||
|
masterI->version,
|
||||||
|
masterI->size,
|
||||||
|
masterI->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // (End) impl details
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle tracking the registration of an interface, deregistering it on deletion.
|
||||||
|
* Depending on which flavour of the ctor is used, either (bulk) registration of interfaces
|
||||||
|
* or plugin loading is triggered. The interface type is defined by type parameter.
|
||||||
|
* @todo when provided with the type of an facade interface class, care for enabling/disabling
|
||||||
|
* access through the facade proxy singleton when opening/closing the registration.
|
||||||
|
*/
|
||||||
|
template< class I ///< fully mangled name of the interface type
|
||||||
|
>
|
||||||
|
class InstanceHandle
|
||||||
|
: private boost::noncopyable
|
||||||
|
{
|
||||||
|
LumieraInterface* desc_;
|
||||||
|
I* instance_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** Set up an InstanceHandle representing a plugin.
|
||||||
|
* Should be placed at the client side.
|
||||||
|
* @param iName unmangled name of the interface
|
||||||
|
* @param version major version
|
||||||
|
* @param minminor minimum acceptable minor version number
|
||||||
|
* @param impName unmangled name of the instance (implementation)
|
||||||
|
*/
|
||||||
|
InstanceHandle (string const& iName, uint version, size_t minminor, string const& impName)
|
||||||
|
: descriptors_(0),
|
||||||
|
instance_(static_cast<I*>
|
||||||
|
(lumiera_interface_open (iName, version, minminor, impName)))
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/** Set up an InstanceHandle managing the
|
||||||
|
* registration and deregistration of interface(s).
|
||||||
|
* Should be placed at the service providing side.
|
||||||
|
* @param descriptors zero terminated array of interface descriptors,
|
||||||
|
* usually available through lumiera_plugin_interfaces()
|
||||||
|
*/
|
||||||
|
InstanceHandle (LumieraInterface* descriptors)
|
||||||
|
: desc_(descriptors),
|
||||||
|
instance_(static_cast<I*> (register_and_open (desc_)))
|
||||||
|
{ }
|
||||||
|
|
||||||
|
~InstanceHandle ()
|
||||||
|
{
|
||||||
|
lumiera_interface_close ((LumieraInterface)instance_);
|
||||||
|
if (desc_)
|
||||||
|
lumiera_interfaceregistry_bulkremove_interfaces (desc_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace lumiera
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -316,7 +316,7 @@ LUMIERA_INTERFACE_INSTANCE (lumieraorg__plugin, 0,
|
||||||
lumiera_interface_handle->close (&(handle)->interface_header_)
|
lumiera_interface_handle->close (&(handle)->interface_header_)
|
||||||
|
|
||||||
|
|
||||||
#else /* compile as buildin */
|
#else /* compile as builtin */
|
||||||
|
|
||||||
#define LUMIERA_PLUGIN_INTERFACEHANDLE static LUMIERA_INTERFACE_HANDLE(lumieraorg_interface, 0) lumiera_interface_handle
|
#define LUMIERA_PLUGIN_INTERFACEHANDLE static LUMIERA_INTERFACE_HANDLE(lumieraorg_interface, 0) lumiera_interface_handle
|
||||||
#define LUMIERA_PLUGIN_STORE_INTERFACEHANDLE(name) lumiera_interface_handle = LUMIERA_INTERFACE_CAST (lumieraorg_interface, 0) name
|
#define LUMIERA_PLUGIN_STORE_INTERFACEHANDLE(name) lumiera_interface_handle = LUMIERA_INTERFACE_CAST (lumieraorg_interface, 0) name
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,8 @@ namespace gui {
|
||||||
/** storage for the facade proxy factory used by client code to invoke through the interface */
|
/** storage for the facade proxy factory used by client code to invoke through the interface */
|
||||||
lumiera::SingletonSub<GuiNotification> GuiNotification::facade (typeinfo_proxyInstance_to_create);
|
lumiera::SingletonSub<GuiNotification> GuiNotification::facade (typeinfo_proxyInstance_to_create);
|
||||||
|
|
||||||
|
///////////////////////////////////////TODO: this solution is not correct, because it doesn't detect when the interface is shut down!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace gui
|
} // namespace gui
|
||||||
|
|
|
||||||
|
|
@ -499,7 +499,7 @@ TEST ("plugin_examplepluginc")
|
||||||
lumiera_interfaceregistry_init ();
|
lumiera_interfaceregistry_init ();
|
||||||
lumiera_plugin_discover (lumiera_plugin_load, lumiera_plugin_register);
|
lumiera_plugin_discover (lumiera_plugin_load, lumiera_plugin_register);
|
||||||
|
|
||||||
TODO ("macro to derrive minminor version from a slot");
|
TODO ("macro to derive minminor version from a slot");
|
||||||
|
|
||||||
LUMIERA_INTERFACE_HANDLE(lumieraorg_testhello, 0) german =
|
LUMIERA_INTERFACE_HANDLE(lumieraorg_testhello, 0) german =
|
||||||
LUMIERA_INTERFACE_OPEN (lumieraorg_testhello, 0, 0, lumieraorg_hello_german);
|
LUMIERA_INTERFACE_OPEN (lumieraorg_testhello, 0, 0, lumieraorg_hello_german);
|
||||||
|
|
|
||||||
|
|
@ -1378,12 +1378,12 @@ Thus, the Proc-Layer exposes (one or several) facade interfaces for the GUI to u
|
||||||
<div title="GuiIntegration" modifier="Ichthyostega" created="200812050532" tags="overview" changecount="1">
|
<div title="GuiIntegration" modifier="Ichthyostega" created="200812050532" tags="overview" changecount="1">
|
||||||
<pre>Considering how to interface to and integrate with the GUI Layer. Running the GUI is //optional,// but it requires to be [[started up|GuiStart]], installing the necessary LayerSeparationInterfaces.</pre>
|
<pre>Considering how to interface to and integrate with the GUI Layer. Running the GUI is //optional,// but it requires to be [[started up|GuiStart]], installing the necessary LayerSeparationInterfaces.</pre>
|
||||||
</div>
|
</div>
|
||||||
<div title="GuiStart" modifier="Ichthyostega" modified="200812050606" created="200812050525" tags="GuiIntegration" changecount="3">
|
<div title="GuiStart" modifier="Ichthyostega" modified="200812060214" created="200812050525" tags="GuiIntegration" changecount="4">
|
||||||
<pre>Starting up the GUI is optional and is considered part of the Application start/stop and lifecycle.
|
<pre>Starting up the GUI is optional and is considered part of the Application start/stop and lifecycle.
|
||||||
* main and AppState activate the lifecyle methods on the ~GuiSubsysDescriptor
|
* main and AppState activate the lifecyle methods on the ~GuiSubsysDescriptor
|
||||||
* loading a GuiStarterPlugin creates an instance of the notification interface within the InterfaceSystem
|
* loading a GuiStarterPlugin creates an instance of the notification interface within the InterfaceSystem
|
||||||
* its implementation (within GuiStarterPlugin) is linked against the GuiNotificationFacade, i.e. the actual implementation. This link is hard wired.
|
* its implementation (within GuiStarterPlugin) is linked against the GuiNotificationFacade, i.e. the actual implementation. This link is hard wired.
|
||||||
* the process of loading this GuiStarterPlugin creates an interface ref on the calling side, which is made available through the usual singleton factory embedded within the GuiNotificationFacade interface.
|
* the process of loading this GuiStarterPlugin creates an interface ref on the calling side, which is made available through the usual singleton factory embedded within the GuiNotificationFacade interface. {{red{TODO current solution doesn't handle shutdown correctly}}}
|
||||||
* activating this singleton factory yields the (single) instance of the forwarding proxy, which calls through this interface ref.
|
* activating this singleton factory yields the (single) instance of the forwarding proxy, which calls through this interface ref.
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1801,7 +1801,7 @@ From experiences with other middle scale projects, I prefer having the test code
|
||||||
[img[Example: Interfaces/Namespaces of the ~Session-Subsystems|uml/fig130053.png]]
|
[img[Example: Interfaces/Namespaces of the ~Session-Subsystems|uml/fig130053.png]]
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<div title="LayerSeparationInterfaces" modifier="Ichthyostega" created="200812050619" tags="def" changecount="1">
|
<div title="LayerSeparationInterfaces" modifier="Ichthyostega" modified="200812060633" created="200812050619" tags="def" changecount="2">
|
||||||
<pre>Lumiera uses a 3-layered architecture. Separation between layers is crucial. Any communication between the layers regarding the normal operation of the application should //at least be initiated// through ''Layer abstraction interfaces''. This is a low-impact version of layering, because, aside from this triggering, direct cooperation of parts within the single Lumiera process is allowed, under the condition that is is implemented using additional abstractions (interfaces with implementation level granularity). We stick to the policy of //disallowing direct coupling of implementations located in different layers.//
|
<pre>Lumiera uses a 3-layered architecture. Separation between layers is crucial. Any communication between the layers regarding the normal operation of the application should //at least be initiated// through ''Layer abstraction interfaces''. This is a low-impact version of layering, because, aside from this triggering, direct cooperation of parts within the single Lumiera process is allowed, under the condition that is is implemented using additional abstractions (interfaces with implementation level granularity). We stick to the policy of //disallowing direct coupling of implementations located in different layers.//
|
||||||
|
|
||||||
To implement such a structure, each layer separation interface actually is comprised of several parts:
|
To implement such a structure, each layer separation interface actually is comprised of several parts:
|
||||||
|
|
@ -1809,6 +1809,10 @@ To implement such a structure, each layer separation interface actually is compr
|
||||||
* a facade interface defining the respective abstractions in terms of the implementation language (C or C++)
|
* a facade interface defining the respective abstractions in terms of the implementation language (C or C++)
|
||||||
* a implementation object on the service proiding side which is directly addressed by the implementation instantiated within the InterfaceSystem
|
* a implementation object on the service proiding side which is directly addressed by the implementation instantiated within the InterfaceSystem
|
||||||
* a proxy object on the client side, which usually is given inline alongside with the CLI interface definition.
|
* a proxy object on the client side, which usually is given inline alongside with the CLI interface definition.
|
||||||
|
|
||||||
|
!opening and closing
|
||||||
|
Handling the lifecycle can be tricky, because client- and service-side need to carry out the opening and closing operations in sync and observing a specific call order to ensure calls get blocked already on the client side unless the whole interface compound is really up and running. To add to this complexity, plugins and built-in interfaces are handled differently regarding the question who is in charge of the lifecycle: interfaces are installed on the service side, whereas the loading of plugins is triggered from client side by requesting the plugin from the loader.
|
||||||
|
Anyway, interfaces are resources which best should be managed automatically. At least within the C++ part of the application we can ensure this by using a handle class. This way the handling of plugins and interfaces can be unified; the only remaining difference is on what side (client or service provider side) the handle is instantiated, with the appropriate ctor parameters.
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<div title="LoadingMedia" modifier="Ichthyostega" modified="200806030203" created="200709220005" tags="design spec" changecount="4">
|
<div title="LoadingMedia" modifier="Ichthyostega" modified="200806030203" created="200709220005" tags="design spec" changecount="4">
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue