There is now sort-of an "application realm", which doesn’t belong strictly to
one of the Layers. It serves the purpose of pullig up and tearing down the
application in a controlled fashion. And additionally, it provides the Interface
and Config core services. Within the application, we find a small number of
Subsystems, which are more or less independent. These subsystems are
conceptual entities and don’t correspond 1:1 to a layer, an interface, a class
or a plugin. These subsystems are of no relevance outside the mentioned
"application realm". When the application is in normal operational mode, we have
the usual components, interfaces, services, aggregated into the three Layers.
Currently I’ve identified the following subsystems:
-
Engine
-
Builder
-
Session
-
Lumiera GUI
-
Script runner
-
Renderfarm node server
To deal with those subsystems, I’ve created an Interface to definesthe
operations and liabilities of a subsystem. Additionally, I assume that for each
subsystem there is a Facade, which the subsystem is free to implement as it
sees fit. Typically, this facade will load plugins, register and provide further
"business interfaces", and especially set up the Layer separation interfaces
which canalise any communication going on between the layers.
The code from my "startup" branch has meanwhile been merged to master. Look
here
for the code mentioned in the following discussion.
-
common/subsys.hpp contains the mentioned subsystem interface.
-
lumiera/main.cpp uses the subsystem instances provided by the facades, and
additionally the services of lumiera::AppState (common/appstate.hpp)
-
AppState represents the state as relevant for the "application realm", i.e.
it performs global initialisation and shutdown. See especially AppState::init()
-
see backend/enginefacade.hpp|cpp as an (unimplemented) facade skeleton. backend::EngineFacade::getDescriptor()
yields the subsytem interface
-
the GuiFacade is somewhat special, because we want to load the GUI from a
shared libary. This facade is basically completed and working, but it currently
just loads a dummy plugin. The implementation of the GuiFacade needs to be in
core (because it pulls the plugin); that’s why I’ve put it into
common/guifacade.cpp, while the interface is in gui/guifacade.hpp as usual.
-
as an example for a Layer separation interface, I’ve implemented the
GuiNotificationFacade, which will be used by the lower layers to push
informations into the gui (and finally to request the GUI to shut down). Layer
separation interfaces are considered part of the public Lumiera API, thus the
headers go into src/include/**
-
include/guinotification.h (C/C combined header) defines an C interface (abstract class) and a CLI interface.
-
embedded into the interface is a factory, i.e. by gui::GuiNotification::facade() you get an instance…
-
which actually is a proxy and routes any call through the instance of the
accompaning CLI interface which is defined within the interface/plugin system
-
this in turn forwards to the implementation class in
gui/guinotificationfacade.cpp, which is assumed to live within the GUI
(shared lib)