12 KiB
Executable File
Title: Index Authors: Mike Wille, NLE Date: 2020-08-27
Lts Developer Documentation
The Framework
The Framework is a collection of libraries and shared components, that would otherwise be implemented dozen of times, if it hadn't be outsourced into reusable components. The Framework manages e.g. all Sessions, all BaseLayout (Windows), all tabs, starting apps specified in apps.json, managing the login, etc.
Components
UiRequirements
LtsDialog
retranslate
LtsMessageDialog
LtsDialogButtonBox
LtsGlobalWaitDialog
LtsDialogOverlay
LtsNotification
LtsNotificationBox
LtsDataView
UserSettings
AppChooser
LtsMultiMonitor
OperatorApplication
The OperatorApplication (OpApp) is the executable that utilizes the Framework and packs all components together.
Parameters
The OperatorApplication can be reconfigured without having to recompile it. Via command line parameters, the OpApp's behaviour can be influenced.
| Parameter | Long Parameter | Optional | Description | Default | Example | Example Description |
|---|---|---|---|---|---|---|
| -a | --application | The application Id from apps.json to start from the specified branding / project plugin. If no parameter is specified, the App Chooser is shown and waits until a user selection. This option is overriden, if the user has a saved session after log-in. | none | -a 0 | Starts the Situation App, specified in e.g. Legatus' apps.json (see -b) |
|
| -b | --brandingPlugin | The IID of the Project Plugin to load the apps.json file and resources (like Images, etc.) from. | -b legatus | Loads the apps.json and resources of the Legatus Project Plugin | ||
| -s | --stylePlugin | The IID of the Style Plugin to load. A Style Plugin contains a CSS-like file to change the appearance of the application. | rme.light | rme.dark | Loads the Plugin of rme.light's dark style variant | |
| -u | ||||||
| -p | ||||||
| -q | ||||||
| -k | ||||||
| -m | ||||||
| -dbgmmm | ||||||
| -r | ||||||
| -l | ||||||
| -ignore-plugins | ||||||
| -projection | ||||||
| -check-requirements | ||||||
| -enable-experimental-web-platform-features |
Session
A Session manages exactly one BaseLayout and all data channels by DDS. A session can bind to one exercise and / or one replay.
Saved sessions
If the user logs out, the current session configuration is saved. It is restored on log-in. Information that is saved on log-out:
- The screen id of the screen the BaseLayout is currently on
- Special data related to an app (e.g. the Scripts App saves the currently loaded scriptId to load the last script on login if starting the Scripts App)
BaseLayout
Plugins
Plugins are shared libraries that are not linked against the target application, but dynamically loaded via dlopen to achive an application that can be configured dynamically on runtime instead of relying on recompiling the application several times for every application.
There are multiple types of plugins:
Gui Plugins
Gui Plugins are what turn the Framework into an application. The Framework manages the application per se, but the Plugins are where all the dialogs, notifications, payloads, logins, etc. come from. Plugins are built by CMake as modules, which means that they are not linkable to an executable. This is important, because the Framework consists just of the executable and can be given and taken Plugins without having to recompile everything. So you could copy just the Framework executable and its essential libraries, then copy some Plugins to it and start it. But to tell the Framework what plugins to load and how to behave, there are sub-plugins: Project Plugins
Branding / Project Plugins
Project Plugins are also modules that are not linked. They are loaded by specifying the `-b' (Branding) argument to the Operator Application (which uses the Framework). A Project Plugin contains resources (like images, svgs, etc.) and most importantly the apps.json, which tells the framework which Plugins to load and how to behave and what to show, etc.
Style Plugins
DDS Type Plugins
Usually to describe DDS types for the ddsview application.
Plugin IID
A Plugin IID is used to uniquely identify a plugin.
A Plugin IID consists of either 3 characters or 3 characters, followed by a dot and any number of characters - see Plugin IID Pattern. The first 3 characters are usually inherited by the corresponding Service (Plugin to Service relationship). So the first 3 characters specify the Service / source and the n characters after the dot specify the sub plugin. Examples for sub plugins are: opm and opm.settings. The opm plugin does the very general management of users: edit, create, remove, etc. and provides a UI to do so. The opm.settings plugin is plugin that does some more specialized workload: managing user settings [(loading & saving)(#savedsessions)], providing a UI to adjust some user settings.
Plugin to Service relationship
Usually a Plugin (Lts/Plugins) is closely related to a Service (Lts/Services). The reason is that a Service takes care of obtaining data from the server's database and sending them to the clients. E.g. the Exercise Service (short exm) obtains data from the database and then the Exercise Plugin receives the data and displays it in a Dialog, for the user to see / edit.
apps.json
The apps.json file occurs in Project Plugins describes how the OperatorApplication should behave. Most importantly it describes which apps can be started by the OpApp. There can be 1 or more apps specified. Prominent examples are the Situation and Scripts apps.
The Situation app tells the Framework to load the Map Plugin's Dialog into the main area, so that a big Map is displayed after login. The Scripts app tells the Framework to load the Script Editor into the main area, so that there is enough room for editing scripts.
The apps.json file's format is json (application/json).
The apps.json file starts with a json object.
The main apps.json file to always keep up to date is at Lts/Projects/Legatus/resources/apps.json. Only edit all the other files after Legatus' apps.json was updated.
Format Reference
Root
| Name | Type | Optional | Description | Example |
|---|---|---|---|---|
| Project | string | The name of the project the apps.json belongs to | "Legatus" | |
| AVMSkipScreen | integer | x | The screen number (determined by Qt's screens() method) to not allow a BaseLayout to exist (1 - x), screen 0 is not allowed, as this is the main screen. Otherwise the main screen will be selected randomly | 1 |
| LoginPlugin | string | x | The plugin to load first (incl. Payloads) when starting the Framework before any other plugins, etc | "opm.login" |
| Apps | array => App | Apps that can be started from this project | Apps |
Root/App
| Name | Type | Optional | Description | Example |
|---|---|---|---|---|
| Active | boolean | x | If set to false, there is no possibility to start the app. Useful if an app should be removed temporarily, without having to delete it completely from apps.json | |
| Visible | boolean | x | If set to true, the app can be visible in the Apps menu and in the App Chooser | |
| Id | integer | The unique id of the app, starting from 0, that has to be the same across all existing apps.jsons, to guarantee that the hard-coded LtsAppDescriptor::App enum in lts_app_descriptor.h resolves to the correct app. An app can be started by its id with the OperatorApplication parameter -a directly |
||
| ACLs | array => integer | x | To guarantee that our ACL system is correctly implemented, every app should be guarded by one ACL or multiple ACLs. If the ACLs array is specified, it has to contain at least 1 entry. The ACLs are generated in code (where?) and checked after the user has logged in, as then he receives all the ACLs he's got | [ 587268097, 302055426] |
| AppName | string | A human readable name of the app, just for identification reasons while reading apps.json "by human". Don't rely on the name as it might change in the future. Refer to apps by id instead. |
"Situation" | |
| Options | object | Defines how an app behaves and what it consists of | Apps |
Root/App/Options
| Name | Type | Optional | Description | Example |
|---|---|---|---|---|
| Payloads | object | x | Options & Plugins of which 'executePayload' is called from before adding actions, creating the BaseLayout, etc. | Apps |
| Actions | object | x | Options & Plugins of which 'getActions' is called from and adds the returned actions to the menu | Apps |
| Main | object | x | Options & Plugins that must be located in the Main Layout Tab. Check your plugin info for the 'main' flag to process it where you create actions or create dialogs - should be only one plugin, otherwise the main tab would be sub-tabbed | Apps |
Root/App/Options/Payloads
| Name | Type | Optional | Description | Example |
|---|---|---|---|---|
| Plugins | Plugin | The IID of the plugin | "opm.settings" |
Root/App/Options/Actions
| Name | Type | Optional | Description | Example |
|---|---|---|---|---|
| Plugins | Plugin | The IID of the plugin | "opm.settings" |
Root/App/Options/Main
| Name | Type | Optional | Description | Example |
|---|---|---|---|---|
| Plugins | Plugin | The IID of the plugin | "opm.settings" |
Plugin
| Name | Type | Optional | Description | Example |
|---|---|---|---|---|
| Plugin | string | The IIDs of Gui Plugins (excluding gui:3: - see *_gui_plugin.h) to load. Starting with the 3 character parent (service) id, and optionally followed by a dot an an at least 3 characters long Plugin identifier - see pattern |
"opm.settings" |
Plugin IID Pattern
The pattern is defined by regex: ^[a-z]{3}\\.[a-z.]{3,}|^[a-z^.]{3,}$. Starting with the 3 character parent (service) id, and optionally followed by a dot an an at least 3 characters long Plugin identifier.
Examples that match:
- exm
- opm.settings
- abc.defgh.xyzabc
Examples that don't match:
- abcd
- abcd.xyz
- ab
Examples
Apps
{
"...": "...",
"Apps":
[
{
"Active": true,
"Id": 0,
"ACLs": [ 587268097 ],
"AppName": "Situation",
"Options":
{
"Payloads":
{
"Plugins":
[
"sitmap",
"exm",
"opm.settings"
]
},
"Main":
{
"Plugins":
[
"sitmap"
]
},
"Actions":
{
"Plugins":
[
"aes.airsupport",
"aes.bccontaminations",
"aes.borderlines",
"..."
]
}
}
]
}
Misc
The source code is currently (and has to be) compatible with openSUSE 42.3, 15.1 (as of 2020-08-28).