Hemera::Application Class Referenceabstract

The base class for Hemera applications and daemons. More...

Inheritance diagram for Hemera::Application:

Public Slots

void start ()
 Triggers a safe start of the application. More...
 
void stop ()
 Triggers a safe stop of the application. More...
 
void quit ()
 Triggers a safe quit of the application. More...
 
Hemera::OperationrequestOrbitSwitchInhibition (const QString &reason=QString())
 Requests an inhibition for orbit switching. More...
 
Hemera::OperationreleaseOrbitSwitchInhibition ()
 Releases a previously set inhibition. More...
 
- Public Slots inherited from Hemera::AsyncInitObject
Hemera::Operationinit ()
 

Signals

void applicationStatusChanged (Hemera::Application::ApplicationStatus status)
 Emitted when the application's status changes. More...
 
- Signals inherited from Hemera::AsyncInitObject
void ready ()
 

Protected Types

enum  OperationResult : quint8 { OperationResult::Success, OperationResult::Failed, OperationResult::Fatal }
 Defines the result of a state transition. More...
 

Protected Slots

virtual void startImpl ()=0
 Implementation of the start procedure. More...
 
virtual void stopImpl ()=0
 Implementation of the stop procedure. More...
 
virtual void prepareForShutdown ()
 Implementation of the shutdown procedure. More...
 
void setStarted (OperationResult result=OperationResult::Success, const QString &errorName=QString(), const QString &errorMessage=QString())
 Marks a start operation as finished and completes the transition. More...
 
void setStopped (OperationResult result=OperationResult::Success, const QString &errorName=QString(), const QString &errorMessage=QString())
 Marks a stop operation as finished and completes the transition. More...
 
void setReadyForShutdown (OperationResult result=OperationResult::Success, const QString &errorName=QString(), const QString &errorMessage=QString())
 Marks a prepareForShutdown operation as finished and completes the transition. More...
 
- Protected Slots inherited from Hemera::AsyncInitObject
virtual void initImpl ()=0
 
void setReady ()
 
void setInitError (const QString &errorName, const QString &message=QString())
 
void setOnePartIsReady ()
 

Additional Inherited Members

- Protected Member Functions inherited from Hemera::AsyncInitObject
void setParts (uint parts)
 

Detailed Description

The base class for Hemera applications and daemons.

Application is the base class for any Hemera application. It cannot be subclassed directly: GuiApplication, WidgetsApplication, HeadlessApplication or one of their subclasses should be subclassed instead, depending on the type of your application.

Application is a state machine based on AsyncInitObject, hence it has an initialization cycle which can be controlled by the developer. Once initialized, it is automatically exposed over its Orbit's bus, identified by its ID.

The communication over the Orbit bus is always kept fully transparent, and is a mere detail to the developer: the SDK takes care of all the needed IPC logic under the hood for communicating with Hemera components.

.ha files and Application properties
.ha files are descriptors for the Application (more on ha files: Qt5ApplicationHowTo). The most important information they carry at runtime is the Application's id.
The ID is in a reverse domain name notation, or more specifically a well-known DBus service name. The application will be uniquely identified over the whole system with its id.
As .ha files are in QML and need a JavaScript engine to be brought up, ha are never parsed at runtime for performance reasons. Instead, a ApplicationProperties subclass is generated at compile-time, parsing the .ha file and injecting all the needed runtime information straight into the Application's binary. Whenever an application is constructed, it requires to be given an ApplicationProperties instance. Such a class is automatically generated by hemera_add_application_properties CMake Macro, or by your ha buildsystem without the need for you to do anything.
Creating an Application
Hemera Applications do not need a main method - instead, they rely on a set of macros which automatically generate the needed startup logic. As such, your cpp file will look something like this:
MyApplication::MyApplication()
: Hemera::HeadlessApplication(new MyApplicationProperties)
{
[...]
The HEMERA_HEADLESS_APPLICATION_MAIN macro takes care of creating a main method, starting the main loop and triggering the initialization logic of the application. Other macros are available for starting application with a GUI.
An Application's lifecycle
As an application initializes, it immediately connects to the Orbit bus, allowing for easy IPC, but most of all for access Hemera Orbit Control. In fact, Gravity handles the Application's execution state entirely, whereas the application should not interfere with it.
For this reason, access to start, stop and quit is unallowed to any call which isn't coming from the bus. The auto generated policy for the DBus and application-level checks carries the warranty that only Gravity will be capable of calling into those methods. Of course, the application developer shouldn't interact with QCoreApplication to avoid any possible interference.

Member Enumeration Documentation

enum Hemera::Application::OperationResult : quint8
strongprotected

Defines the result of a state transition.

When trying to start, stop or shutdown the Application, some errors can occur. This enum can be fed to setStarted and others to notify whether the operation has failed, and if the failure was critical.

Please note that if the failure is critical, the application will transition to FailedStatus and will be shutdown right after. If the fatal error happened during setReadyForShutdown, the application will instead be killed immediately.

If the failure is not critical, the application will be rolled back to the previous status instead.

See also
setStarted
setStopped
setReadyForShutdown
Enumerator
Success 

The transition was successful. applicationStatus will transition to the next state.

Failed 

The transition was not successful. applicationStatus will rollback to the previous state.

Fatal 

The transition was not successful, and triggered a critical error. applicationStatus will transition to FailedStatus and will be shutdown right after, or shutdown immediately if the failure happened while transitioning to ReadyForShutdownStatus.

Member Function Documentation

void Hemera::Application::start ( )
slot

Triggers a safe start of the application.

This method triggers a safe start of the application, ensuring it is ready to start up and rejecting the call otherwise. The hard requirement is for the application to be initialized and stopped - that is, the application should be in StoppedStatus.

Once in StoppedStatus, it transitions to StartingStatus to allow the application to perform the startup procedure asynchronously. When the applicaton is ready, the status transitions to RunningStatus, and should be ready to process requests. GUI applications should show their main interface when this status is reached.

Note
This method can be called only from Gravity - any other caller will be rejected, including direct callers. Developers subclassing Application should reimplement startImpl instead, allowing them to define their own startup procedure safely.
See also
startImpl
void Hemera::Application::stop ( )
slot

Triggers a safe stop of the application.

This method triggers a safe stop of the application, ensuring it is ready to stop and rejecting the call otherwise. The hard requirement is for the application to be initialized and running - that is, the application should be in RunningStatus.

Once in RunningStatus, it transitions to StoppingStatus to allow the application to perform the stop procedure asynchronously. When the applicaton is ready, the status transitions to StoppedStatus, and should be ready to process requests. GUI applications should hide their main interface when this status is reached.

Returns
Whether the request has succeeded or not.
Note
This method can be called only from Gravity - any other caller will be rejected, including direct callers. Developers subclassing Application should reimplement stopImpl instead, allowing them to define their own stopping procedure safely.
See also
stopImpl
void Hemera::Application::quit ( )
slot

Triggers a safe quit of the application.

This method triggers a safe quit of the application, ensuring it has been stopped and unloaded successfully. It heavily affects the state machine - once quit is called, the application is first stopped, if not stopped already.

Once in StoppedState, it transitions to ShuttingDownStatus to allow the application to perform a cleanup, if needed. Done that, it finally reaches ReadyForShutdownStatus and the process is automatically killed by the event loop.

Returns
Whether the request has succeeded or not.
Note
This method can be called only from Gravity - any other caller will be rejected, including direct callers. Developers subclassing Application should reimplement prepareForShutdown instead, allowing them to hook into the shutdown procedure to perform a last minute cleanup before exit.
Operation * Hemera::Application::requestOrbitSwitchInhibition ( const QString &  reason = QString())
slot

Requests an inhibition for orbit switching.

This method triggers a request to Gravity to prevent switching the active orbit on the current handler until the inhibition is released. Each Application, if allowed, can inhibit only once. While the inhibition is in place, the application won't be shutdown, unless the system is being shutdown as well.

You should use inhibition in case your application is performing a critical operation, such as a software update or a long disk write.

reason The reason for inhibition, to be displayed by Gravity in case any actor requests an Orbit switch.

Returns
An operation representing the request to Gravity.
See also
releaseOrbitSwitchInhibition
Operation * Hemera::Application::releaseOrbitSwitchInhibition ( )
slot

Releases a previously set inhibition.

As a counterpart to requestOrbitSwitchInhibition, this method releases a previously requested and obtained inhibition.

Returns
An operation representing the request to Gravity.
See also
requestOrbitSwitchInhibition
virtual void Hemera::Application::startImpl ( )
protectedpure virtualslot

Implementation of the start procedure.

Application developers must reimplement this method to perform the needed operations to start up the application.

From within this method, setStarted should be called once the starting routine has been completed. Failure in doing so will cause the application to wait forever.

Once started, the application should show its main interface if it's a GuiApplication, or start its business logic if it's a HeadlessApplication. The application will be considered as Running once setStarted is called.

Note
It is guaranteed that when this method is called, the application is transitioning from a StoppedStatus
See also
setStarted
OperationResult
ApplicationStatus
virtual void Hemera::Application::stopImpl ( )
protectedpure virtualslot

Implementation of the stop procedure.

Application developers must reimplement this method to perform the needed operations to stop the application.

From within this method, setStopped should be called once the stopping routine has been completed. Failure in doing so will cause the application to wait forever.

Once stopped, the application should hide its main interface if it's a GuiApplication, or stop its business logic if it's a HeadlessApplication. The application will be considered as stopped or paused once setStarted is called, and it's expected not to react actively to any event.

Note
It is guaranteed that when this method is called, the application is transitioning from a StartedStatus
See also
setStarted
OperationResult
ApplicationStatus
void Hemera::Application::prepareForShutdown ( )
protectedvirtualslot

Implementation of the shutdown procedure.

Application developers can reimplement this method to perform any cleanup before the application quits. It is not compulsory to reimplement this method - its default implementation simply calls setReadyForShutdown, skipping any cleanup phase.

From within this method, setStopped should be called once the stopping routine has been completed. Failure in doing so will cause the application to wait forever.

Once stopped, the application should hide its main interface if it's a GuiApplication, or stop its business logic if it's a HeadlessApplication. The application will be considered as stopped or paused once setStarted is called, and it's expected not to react actively to any event.

Note
It is guaranteed that when this method is called, the application is transitioning from a StoppedStatus
See also
setStarted
OperationResult
ApplicationStatus
void Hemera::Application::setStarted ( OperationResult  result = OperationResult::Success,
const QString &  errorName = QString(),
const QString &  errorMessage = QString() 
)
protectedslot

Marks a start operation as finished and completes the transition.

setStarted can be called only from a subclass of Application and in the context of a startImpl call. Hence, the Application must be in StartingStatus for this method to take any effect.

setStarted can also be used to notify a failure in the starting procedure. See OperationResult for further details.

result The result of the transition. Defaults to SuccessOperationResult. errorName If the result of the transition was not SuccessOperationResult, carries the name of the error occurred. errorMessage If the result of the transition was not SuccessOperationResult, carries the message of the error occurred, if any.

See also
Hemera::Literals::Errors
startImpl
OperationResult
void Hemera::Application::setStopped ( OperationResult  result = OperationResult::Success,
const QString &  errorName = QString(),
const QString &  errorMessage = QString() 
)
protectedslot

Marks a stop operation as finished and completes the transition.

setStopped can be called only from a subclass of Application and in the context of a stopImpl call. Hence, the Application must be in StoppingStatus for this method to take any effect.

setStopped can also be used to notify a failure in the stop procedure. See OperationResult for further details.

result The result of the transition. Defaults to SuccessOperationResult. errorName If the result of the transition was not SuccessOperationResult, carries the name of the error occurred. errorMessage If the result of the transition was not SuccessOperationResult, carries the message of the error occurred, if any.

See also
Hemera::Literals::Errors
stopImpl
OperationResult
void Hemera::Application::setReadyForShutdown ( OperationResult  result = OperationResult::Success,
const QString &  errorName = QString(),
const QString &  errorMessage = QString() 
)
protectedslot

Marks a prepareForShutdown operation as finished and completes the transition.

setReadyForShutdown can be called only from a subclass of Application and in the context of a prepareForShutdown call. Hence, the Application must be in ShuttingDownStatus for this method to take any effect.

setReadyForShutdown can also be used to notify a failure in the shutdown procedure. See OperationResult for further details. Please note that, in the specific case of this method, passing FatalOperationResult will cause the application to abort and quit immediately.

result The result of the transition. Defaults to SuccessOperationResult. errorName If the result of the transition was not SuccessOperationResult, carries the name of the error occurred. errorMessage If the result of the transition was not SuccessOperationResult, carries the message of the error occurred, if any.

See also
Hemera::Literals::Errors
prepareForShutdown
OperationResult
void Hemera::Application::applicationStatusChanged ( Hemera::Application::ApplicationStatus  status)
signal

Emitted when the application's status changes.

Whenever applicationStatus changes, this status is emitted. Useful for keeping track of the state machine changes, even though from the developer perspective, the machine should be handled from a reimpl perspective.

Parameters
statusThe new status the Application has transitioned to.