WIP start drafting a better InterfaceProxy handling

This commit is contained in:
Fischlurch 2009-01-04 15:21:04 +01:00
parent e8229623bc
commit 8d4bc62fbe
6 changed files with 119 additions and 10 deletions

View file

@ -161,7 +161,7 @@ namespace lumiera {
* @note we don't provide operator* */
FA * operator-> () const { return accessFacade(); }
/** directly access the instance via the CLI interface */
/** directly access the instance via the CL interface */
I& get () const { ENSURE(instance_); return *instance_; }

View file

@ -21,7 +21,8 @@
* *****************************************************/
#include "lib/singletonsubclass.hpp"
#include "include/interfaceproxy.hpp"
#include "lib/singletonsubclass.hpp" ////////////////////TODO
#include "include/guinotificationfacade.h"
#include "lib/util.hpp"
#include "lib/error.hpp"

View file

@ -70,7 +70,8 @@ namespace gui {
namespace { // implementation details
/**
* Implement the necessary steps for starting up the GUI main thread
* Implement the necessary steps for actually making the Lumiera Gui available.
* Open the business interface(s) and start up the GTK GUI main event loop.
*/
struct GuiFacadeImpl
: public GuiFacade
@ -104,7 +105,7 @@ namespace gui {
};
lumiera::Singleton<GuiFacadeImpl> facade_;
lumiera::Singleton<GuiFacadeImpl> guiImplProvider_;
} // (End) impl details
@ -197,7 +198,7 @@ extern "C" { /* ================== define an lumieraorg_Gui instance ===========
, LUMIERA_INTERFACE_INLINE (kickOff, "\255\142\006\244\057\170\152\312\301\372\220\323\230\026\200\065",
void, (void* termSig),
{
gui::facade_().kickOff (
gui::guiImplProvider_().kickOff (
*reinterpret_cast<Subsys::SigTerm *> (termSig));
}
)

View file

@ -83,7 +83,7 @@ namespace gui {
extern "C" {
#endif /* =========================== CLI Interface ================= */
#endif /* =========================== CL Interface ===================== */
#include "common/interface.h"

View file

@ -0,0 +1,107 @@
/*
INTERFACEPROXY - definition of forwarding proxies for the facade interfaces
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 interfaceproxy.hpp
** Facade Interfaces Lifecycle. Communication between the Layers within Lumiera
** usually is routed through <b>Layer Separation Interfaces</b>. These are comprised
** of a Facade interface and a equivalent rendering as C Language interface defined
** with the help of the Interface/Plugin system. But in order to be able to actually
** access a service via this Facade, you need an instance of the interface.
**
** InterfaceProxy and InstanceHandle together are used to create such an concrete
** instance of the Facade interface. It is implemented such as to route each call
** through the corresponding C Language function defined in the Interface/Plugin system.
** Typically there is another subclass of the Facade interfaces sitting "on the other side"
** of the interface barrier and actually implementing the functionality. The template
** InterfaceProxy can be thought of as a factory creating such a proxy instance of the
** facade interface for the client code to use. Typically, in instance of the \em factory
** is embedded (as a static functor member object) right within the otherwise abstract
** facade interface, this way allowing the client code to write e.g. \c XYZInterface::facade()
** to yield a reference to a proxy object implementing \c XYZInterface.
**
** Interface Lifecycle
**
** Instances of an Interface are either directly provided by some facility within the core,
** or they are loaded from a shared module (plugin). In either case this means the interface
** isn't accessible all the time, rather it comes up at a defined point in the application
** lifecycle and similarly will be shut down deliberately at some point. Beyond this time
** window of availability, any access through the proxy factory throws an lumiera::error::State.
** Any sort of dependency management is outside the scope of the InterfaceProxy (for the core
** services, it is handled by the dependency of subsystems, while the plugin loader cares
** for dependency issues regarding loadable modules, thereby building on the deployment
** descriptors.
**
** For the Layer separation interfaces, the process of loading and opening is abstracted as
** an InstanceHandle object. When creating such an InstanceHandle using the appropriate
** template and ctor parameters, in addition to the registration with the Interface/Plugin
** system, the corresponding InterfaceProxy factory is addressed and "opened" by creating
** the right proxy object instance. Similarly, when the InstanceHandle object goes out
** of scope, prior to detaching from the Interface/Proxy system, the corresponding
** InterfaceProxy factory is "closed", which means destroying the proxy object instance
** and switching any further access to throwing and exception.
**
** While client code just includes the interface header (including interfaceproxy.hpp
** in turn), there needs to be an actual implementation of each proxy object located in
** some translation unit. The usual place is interfaceproxy.cpp, which gets linked into
** \c liblumieracommon.so and contains actual specialisations and literal forwarding
** code <i>for each individual facade.</i>
**
** @see interface.h
** @see plugin.h
** @see lumiera::Subsys
** @see guinotification.h usage example (facade interface)
** @see guinotificationfacade.cpp corresponding implementation within the GUI
*/
#ifndef LUMIERA_INTERFACE_PROXY_H
#define LUMIERA_INTERFACE_PROXY_H
#include <string>
namespace lumiera {
using std::string;
/*********************************************************************
*
*/
template<class FA>
class InterfaceProxy
{
friend class lumiera::InstanceHandle;/////////////TODO use an abstraction here!
public:
};
} // namespace lumiera
#endif

View file

@ -21,14 +21,14 @@
*/
/** @file singletonsubclass.hpp
** Spezialized SingletonFactory creating sublcasses of the nominal type.
** Specialised SingletonFactory creating subclasses of the nominal type.
** The rationale is to be able to defer the decision what type to create
** down to the point where the singleton factory is actualy created.
** down to the point where the singleton factory is actually created.
** Thus the code using the singleton need not know the implementation
** class, but nevertheless gets an non-virtual access function to the
** singleton instance (which can be inlined), and the compiler is
** still able to spot type errors. Maybe someone knows a less
** contrieved solution fulfilling the same criteria....?
** contrived solution fulfilling the same criteria....?
**
** @see configrules.cpp usage example
** @see SingletonSubclass_test
@ -63,7 +63,7 @@ namespace lumiera {
struct Link
{
virtual ~Link() {}
virtual I* create () = 0; ///< @note compiler will check the actual type is assignable...
virtual I* create () = 0; ///< @note compiler will check if the actual type is assignable...
virtual void destroy (I* pSi) = 0;
};