Skip to content

Commit 8a6fe31

Browse files
author
Andy Ford
authored
Merge pull request #13 from ECFMP/measure-applicability
Measure applicability
2 parents a8fdec6 + d421128 commit 8a6fe31

71 files changed

Lines changed: 5492 additions & 187 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ on:
99
jobs:
1010
build:
1111
name: Build
12-
runs-on: windows-latest
12+
runs-on: windows-2019
1313
concurrency:
1414
group: flow-sdk-build-${{ github.ref }}
1515
cancel-in-progress: true

README.md

Lines changed: 74 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,79 @@ A Software Development Kit (SDK) for the ECFMP Flow Control API
44

55
## Integrating With The SDK
66

7-
Coming soon!
7+
### Create a HTTP Client
88

9-
## Building
9+
Rather than ship with an opinionated viewpoint as to what you should use for HTTP requests, this SDK
10+
provides an interface `HttpClient` that the HTTP client of your choice must implement.
11+
12+
### Create a logger
13+
14+
You can optionally pass the SDK a logging class that implements the `Logger` interface. This will allow you to log
15+
messages from the SDK.
16+
17+
### Create an instance of the SDK
18+
19+
To create an instance of the SDK, you must use the `SDKFactory` class. This class will allow you to configure the SDK,
20+
and
21+
then create an instance of it.
22+
23+
```c++
24+
#include "ECFMP/SDKFactory.h"
25+
#include "ECFMP/SDK.h"
26+
27+
auto http = std::make_shared<MyHttpClient>();
28+
auto logger = std::make_shared<MyLogger>();
29+
auto ecfmp = ECFMP::Plugin::SdkFactory::Build()
30+
.WithLogger(logger)
31+
.WithHttpClient(std::move(http)).Instance();
32+
```
33+
34+
### Add the SDK to EuroScopes timer event
35+
36+
The SDK needs to be called periodically to process events. To do this, you must add the call to the EuroScopes timer
37+
event. This is necessary because EuroScope requires that calls to its internal classes are made from the plugin thread
38+
(as opposed to something asynchronous.)
39+
40+
```c++
41+
void MyPlugin::OnTimer(int time)
42+
{
43+
ecfmp.OnEuroscopeTimerTick();
44+
}
45+
```
46+
47+
### Register event handlers
48+
49+
You can register event handlers with the SDK. These event handlers will be called when the SDK processes an event.
50+
These listeners must implement the `EventListener` interface.
51+
52+
```c++
53+
auto eventListener = std::make_shared<MyListener<ECFMP::Plugin::FlowMeasureActivatedEvent>>();
54+
ecfmp.EventBus().Subscribe<ECFMP::Plugin::FlowMeasureActivatedEvent>(eventListener);
55+
```
56+
57+
## Testing Your Integration
58+
59+
You can test your integration by making use of the mocks provided by the SDK. These mocks will allow you to simulate
60+
events that would be sent by the ECFMP SDK.
61+
62+
You can find the mocks in `include/mock`.
63+
64+
## Known Limitations
65+
66+
At the moment, the SDK has the following limitations:
67+
68+
- The SDK does not support Event Participation filters on Flow Measures. This is because EuroScope does not provide
69+
the CID of the aircraft that is being filtered on, and thus a way around this needs to be devised.
70+
71+
## Development
72+
73+
### Building
1074

1175
This project builds using CMake. You can build using a command similar to below
1276

1377
`cmake -DCMAKE_BUILD_TYPE=<Release|Debug> -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_DEPENDS_USE_COMPILER=FALSE -G Ninja -Bbuild`
1478

15-
## Running Tests
79+
### Running Tests
1680

1781
Tests can be run using the `ctest` command, from the build directory:
1882

@@ -24,8 +88,13 @@ The SDK has the following design rationale.
2488

2589
### Event Driven
2690

27-
Similar to how EuroScope is event driven, so is this SDK. Integrations can register a series of event handlers with the SDK, which will pass on events, such as new Flow Measures for processing.
91+
Similar to how EuroScope is event driven, so is this SDK. Integrations can register a series of event handlers with the
92+
SDK, which will pass on events, such as new Flow Measures for processing.
93+
94+
The SDK itself is also event driven, and uses an internal event bus to handle events.
2895

2996
### Async
3097

31-
EuroScope is a single-threaded application when it comes to plugins, therefore, anything that may take a while (e.g. HTTP requests) will be done aysynchronously. The results of these operations will be deferred for when the EuroScope thread comes back around, as EuroScope sometimes doesn't like things interacting with it asynchronously.
98+
EuroScope is a single-threaded application when it comes to plugins, therefore, anything that may take a while (e.g.
99+
HTTP requests) will be done asynchronously. The results of these operations will be deferred for when the EuroScope
100+
thread comes back around, as EuroScope sometimes doesn't like things interacting with it asynchronously.

include/ECFMP/flowmeasure/AirportFilter.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#pragma once
2+
#include "ChecksAircraftApplicability.h"
23

34
namespace ECFMP::FlowMeasure {
45

@@ -11,7 +12,7 @@ namespace ECFMP::FlowMeasure {
1112
/**
1213
* A filter that pertains to arrival or departure airports
1314
*/
14-
class AirportFilter
15+
class AirportFilter : public ChecksAircraftApplicability
1516
{
1617
public:
1718
virtual ~AirportFilter() = default;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#pragma once
2+
3+
namespace ECFMP::Euroscope {
4+
class EuroscopeAircraft;
5+
}// namespace ECFMP::Euroscope
6+
7+
namespace ECFMP::FlowMeasure {
8+
class ChecksAircraftApplicability
9+
{
10+
public:
11+
virtual ~ChecksAircraftApplicability() = default;
12+
13+
/**
14+
* Returns whether the given aircraft is applicable to this filter.
15+
*/
16+
[[nodiscard]] virtual auto ApplicableToAircraft(const Euroscope::EuroscopeAircraft& aircraft) const noexcept
17+
-> bool = 0;
18+
};
19+
}// namespace ECFMP::FlowMeasure

include/ECFMP/flowmeasure/EventFilter.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#pragma once
2+
#include "ChecksAircraftApplicability.h"
23

34
namespace ECFMP::Event {
45
class Event;
@@ -19,7 +20,7 @@ namespace ECFMP::FlowMeasure {
1920
/**
2021
* A filter that pertains to participation in an event.
2122
*/
22-
class EventFilter
23+
class EventFilter : public ChecksAircraftApplicability
2324
{
2425
public:
2526
virtual ~EventFilter() = default;

include/ECFMP/flowmeasure/FlowMeasure.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ namespace ECFMP {
1010
}// namespace FlightInformationRegion
1111
}// namespace ECFMP
1212

13+
namespace EuroScopePlugIn {
14+
class CFlightPlan;
15+
class CRadarTarget;
16+
}// namespace EuroScopePlugIn
17+
1318
namespace ECFMP::FlowMeasure {
1419
class FlowMeasureFilters;
1520
class Measure;
@@ -115,5 +120,13 @@ namespace ECFMP::FlowMeasure {
115120

116121
// Information about the canonical nature of the flow measure
117122
[[nodiscard]] virtual auto CanonicalInformation() const noexcept -> const CanonicalFlowMeasureInfo& = 0;
123+
124+
/**
125+
* Returns true if the flow measure is applicable to the given aircraft. It will be applicable if all
126+
* of the filters are applicable.
127+
*/
128+
[[nodiscard]] virtual auto ApplicableToAircraft(
129+
const EuroScopePlugIn::CFlightPlan& flightplan, const EuroScopePlugIn::CRadarTarget& radarTarget
130+
) const -> bool = 0;
118131
};
119132
}// namespace ECFMP::FlowMeasure

include/ECFMP/flowmeasure/FlowMeasureFilters.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ namespace ECFMP::FlightInformationRegion {
44
class FlightInformationRegion;
55
}// namespace ECFMP::FlightInformationRegion
66

7+
namespace EuroScopePlugIn {
8+
class CFlightPlan;
9+
class CRadarTarget;
10+
}// namespace EuroScopePlugIn
11+
712
namespace ECFMP::FlowMeasure {
813

914
class AirportFilter;
@@ -27,6 +32,14 @@ namespace ECFMP::FlowMeasure {
2732
*/
2833
[[nodiscard]] virtual auto ApplicableToAirport(const std::string& airfield) const noexcept -> bool = 0;
2934

35+
/**
36+
* Returns true if the flow measure is applicable to the given aircraft. It will be applicable if all
37+
* of the filters are applicable.
38+
*/
39+
[[nodiscard]] virtual auto ApplicableToAircraft(
40+
const EuroScopePlugIn::CFlightPlan& flightplan, const EuroScopePlugIn::CRadarTarget& radarTarget
41+
) const -> bool = 0;
42+
3043
/**
3144
* Methods that allow for iteration of the filters.
3245
*/

include/ECFMP/flowmeasure/LevelRangeFilter.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#pragma once
2+
#include "ChecksAircraftApplicability.h"
23

34
namespace ECFMP::FlowMeasure {
45

@@ -11,7 +12,7 @@ namespace ECFMP::FlowMeasure {
1112
/**
1213
* A filter that pertains to the cruising level of the aircraft.
1314
*/
14-
class LevelRangeFilter
15+
class LevelRangeFilter : public ChecksAircraftApplicability
1516
{
1617
public:
1718
virtual ~LevelRangeFilter() = default;

include/ECFMP/flowmeasure/MultipleLevelFilter.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
#pragma once
2+
#include "ChecksAircraftApplicability.h"
23

34
namespace ECFMP::FlowMeasure {
45
/**
56
* A filter that pertains to the cruising level of the aircraft.
67
*/
7-
class MultipleLevelFilter
8+
class MultipleLevelFilter : public ChecksAircraftApplicability
89
{
910
public:
1011
virtual ~MultipleLevelFilter() = default;

include/ECFMP/flowmeasure/RangeToDestinationFilter.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
#pragma once
2+
#include "ChecksAircraftApplicability.h"
23

34
namespace ECFMP::FlowMeasure {
45
/**
56
* A filter that pertains to arrival or departure airports
67
*/
7-
class RangeToDestinationFilter
8+
class RangeToDestinationFilter : public ChecksAircraftApplicability
89
{
910
public:
1011
virtual ~RangeToDestinationFilter() = default;

0 commit comments

Comments
 (0)