a long standing TODO to document the actual start-up sequence, which is implemented this way since a long time now. There was an unwritten section in the "Linking and Application Structure", which seems the apropriate place for this kind of intricate techincal details. Last week, Benny Lyons was here on visit in munich and he was pondering the idea of an experimental secondary build system, as a way to learn more about the source structure of Lumiera. This reminded me to fill some missing parts of the documentation. Possibly this is also the right moment to land the GTK-3 transition?
148 lines
4.5 KiB
C++
148 lines
4.5 KiB
C++
/*
|
|
APPSTATE.hpp - application initialisation and behaviour
|
|
|
|
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 appstate.hpp
|
|
** Registering and managing primary application-global services.
|
|
** This can be considered the "main" object of the Lumiera application
|
|
** Besides encapsulating the logic to start up the fundamental parts of
|
|
** the application, there is a mechanism for registering \em subsystems
|
|
** to be brought up and shut down in order. AppState will issue the global
|
|
** application lifecycle events (where other parts may have registered
|
|
** callbacks) and provides the top-level catch-all error handling.
|
|
**
|
|
** @see LifecycleHook
|
|
** @see BasicSetup
|
|
** @see Subsys
|
|
** @see main.cpp
|
|
** @see logging.h
|
|
*/
|
|
|
|
|
|
#ifndef LUMIERA_APPSTATE_H
|
|
#define LUMIERA_APPSTATE_H
|
|
|
|
#include "lib/symbol.hpp"
|
|
#include "common/option.hpp"
|
|
#include "common/subsys.hpp"
|
|
#include "common/basic-setup.hpp"
|
|
|
|
#include <boost/noncopyable.hpp>
|
|
#include <boost/scoped_ptr.hpp>
|
|
#include <string>
|
|
#include <map>
|
|
|
|
|
|
|
|
namespace lumiera {
|
|
|
|
using std::string;
|
|
using boost::scoped_ptr;
|
|
using boost::noncopyable;
|
|
|
|
class SubsystemRunner;
|
|
|
|
|
|
/**
|
|
* The Lumiera Application state and basic initialisation.
|
|
* Singleton to hold global flags directing the overall application behaviour,
|
|
* for triggering lifecycle events and performing early initialisation tasks.
|
|
* AppState services are available already from static initialisation code.
|
|
* @warning don't use AppState in destructors.
|
|
*/
|
|
class AppState
|
|
: private noncopyable
|
|
{
|
|
private:
|
|
AppState ();
|
|
|
|
~AppState ();
|
|
friend void boost::checked_delete<AppState>(AppState*);
|
|
|
|
|
|
public:
|
|
/** get the (single) AppState instance.
|
|
* @warning don't use it after the end of main()! */
|
|
static AppState& instance();
|
|
|
|
|
|
/** evaluate the result of option parsing and maybe additional configuration
|
|
* such as to be able to determine the further behaviour of the application.
|
|
* Set the internal state within this object accordingly. */
|
|
void init (lumiera::Option& options);
|
|
|
|
|
|
/** access basic application setup values (from \c setup.ini) */
|
|
string fetchSetupValue (lib::Literal key);
|
|
|
|
|
|
/** building on the state determined by #init, decide if the given Subsys
|
|
* needs to be pulled up and, if necessary, register the Subsys and its
|
|
* prerequisites to be maintained throughout the application's lifetime.
|
|
*/
|
|
void maybeStart (lumiera::Subsys&);
|
|
|
|
|
|
enum ExitCode {
|
|
NORMAL_EXIT,
|
|
CLEAN_EXIT_AFTER_ERROR,
|
|
CLEAN_EMERGENCY_EXIT,
|
|
FAILED_EMERGENCY_EXIT
|
|
};
|
|
|
|
/** put the main thread of the application into a wait state, as long as some
|
|
* subsystem(s) registered with #maybeStart still need to be maintained.
|
|
* On termination of one of those components, tear down the remaining
|
|
* components and initiate a normal or emergency shutdown of the
|
|
* application, depending on the triggering component's
|
|
* mode of termination (exit or exception).
|
|
* @return global application exit code
|
|
*/
|
|
ExitCode maybeWait();
|
|
|
|
|
|
/** initiate the controlled error shutdown sequence
|
|
* @param problem causing exception */
|
|
ExitCode abort (lumiera::Error& problem);
|
|
|
|
|
|
/** initiate an fatal emergency shutdown,
|
|
* caused by an unforeseen error condition */
|
|
ExitCode abort () throw();
|
|
|
|
|
|
|
|
private:
|
|
typedef scoped_ptr<SubsystemRunner> PSub;
|
|
|
|
BasicSetup setup_;
|
|
|
|
PSub subsystems_;
|
|
|
|
bool emergency_;
|
|
bool core_up_;
|
|
|
|
};
|
|
|
|
|
|
} // namespace lumiera
|
|
|
|
#endif
|