Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions include/ECFMP/flowmeasure/AirportFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,10 @@ namespace ECFMP::FlowMeasure {
* Returns the type of airport filter
*/
[[nodiscard]] virtual auto Type() const noexcept -> AirportFilterType = 0;

/**
* Returns a string representation of the filter.
*/
[[nodiscard]] virtual auto FilterDescription() const noexcept -> std::string = 0;
};
}// namespace ECFMP::FlowMeasure
5 changes: 5 additions & 0 deletions include/ECFMP/flowmeasure/EventFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,10 @@ namespace ECFMP::FlowMeasure {
* Returns true if the event participation is "Participating in"
*/
[[nodiscard]] virtual auto IsParticipating() const noexcept -> bool = 0;

/**
* Returns a description of the filter.
*/
[[nodiscard]] virtual auto FilterDescription() const noexcept -> std::string = 0;
};
}// namespace ECFMP::FlowMeasure
5 changes: 5 additions & 0 deletions include/ECFMP/flowmeasure/FlowMeasureFilters.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,10 @@ namespace ECFMP::FlowMeasure {
[[nodiscard]] virtual auto
FirstRangeToDestinationFilter(const std::function<bool(const RangeToDestinationFilter&)>& callback
) const noexcept -> std::shared_ptr<RangeToDestinationFilter> = 0;

/**
* Convenience method to return string description of the filters.
*/
[[nodiscard]] virtual auto FilterDescriptions() const noexcept -> std::vector<std::string> = 0;
};
}// namespace ECFMP::FlowMeasure
5 changes: 5 additions & 0 deletions include/ECFMP/flowmeasure/LevelRangeFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,10 @@ namespace ECFMP::FlowMeasure {
* Helper method to determine, given a particular altitude (e.g. 35000), does this filter apply.
*/
[[nodiscard]] virtual auto ApplicableToAltitude(int level) const noexcept -> bool = 0;

/**
* Description of the filter.
*/
[[nodiscard]] virtual auto FilterDescription() const noexcept -> std::string = 0;
};
}// namespace ECFMP::FlowMeasure
5 changes: 5 additions & 0 deletions include/ECFMP/flowmeasure/Measure.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,10 @@ namespace ECFMP::FlowMeasure {
* Throws an IllegalFlowMeasureValueException exception otherwise.
*/
[[nodiscard]] virtual auto SetValue() const -> const std::set<std::string>& = 0;

/**
* Returns a string representation of the measure.
*/
[[nodiscard]] virtual auto MeasureDescription() const noexcept -> std::string = 0;
};
}// namespace ECFMP::FlowMeasure
5 changes: 5 additions & 0 deletions include/ECFMP/flowmeasure/MultipleLevelFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,10 @@ namespace ECFMP::FlowMeasure {
* Helper method to determine, given a particular altitude (e.g. 35000), does this filter apply.
*/
[[nodiscard]] virtual auto ApplicableToAltitude(int level) const noexcept -> bool = 0;

/**
* Description of the filter
*/
[[nodiscard]] virtual auto FilterDescription() const noexcept -> std::string = 0;
};
}// namespace ECFMP::FlowMeasure
7 changes: 6 additions & 1 deletion include/ECFMP/flowmeasure/RangeToDestinationFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,16 @@ namespace ECFMP::FlowMeasure {
class RangeToDestinationFilter : public ChecksAircraftApplicability
{
public:
virtual ~RangeToDestinationFilter() = default;
~RangeToDestinationFilter() override = default;

/**
* Returns the range to destination.
*/
[[nodiscard]] virtual auto Range() const noexcept -> int = 0;

/**
* Description of the filter
*/
[[nodiscard]] virtual auto FilterDescription() const noexcept -> std::string = 0;
};
}// namespace ECFMP::FlowMeasure
10 changes: 10 additions & 0 deletions include/ECFMP/flowmeasure/RouteFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ namespace ECFMP::FlowMeasure {
{
public:
virtual ~RouteFilter() = default;

/**
* Returns the set of route strings that this filter pertains to.
* @return
*/
[[nodiscard]] virtual auto RouteStrings() const noexcept -> const std::set<std::string>& = 0;

/**
* Description of the filter.
*/
[[nodiscard]] virtual auto FilterDescription() const noexcept -> std::string = 0;
};
}// namespace ECFMP::FlowMeasure
1 change: 1 addition & 0 deletions include/mock/AirportFilterMock.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace ECFMP::Mock::FlowMeasure {
MOCK_METHOD(ECFMP::FlowMeasure::AirportFilterType, Type, (), (const, noexcept, override));
MOCK_METHOD(bool, ApplicableToAirport, (const std::string&), (const, noexcept, override));
MOCK_METHOD(bool, ApplicableToAircraft, (const Euroscope::EuroscopeAircraft&), (const, noexcept, override));
MOCK_METHOD(std::string, FilterDescription, (), (const, noexcept, override));
};

}// namespace ECFMP::Mock::FlowMeasure
1 change: 1 addition & 0 deletions include/mock/EventFilterMock.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace ECFMP::Mock::FlowMeasure {
MOCK_METHOD(ECFMP::FlowMeasure::EventParticipation, Participation, (), (const, noexcept, override));
MOCK_METHOD(bool, IsParticipating, (), (const, noexcept, override));
MOCK_METHOD(bool, ApplicableToAircraft, (const Euroscope::EuroscopeAircraft&), (const, noexcept, override));
MOCK_METHOD(std::string, FilterDescription, (), (const, noexcept, override));
};

}// namespace ECFMP::Mock::FlowMeasure
1 change: 1 addition & 0 deletions include/mock/FlowMeasureFiltersMock.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ namespace ECFMP::Mock::FlowMeasure {
(const std::function<bool(const ECFMP::FlowMeasure::RangeToDestinationFilter&)>&),
(const, noexcept, override)
);
MOCK_METHOD(std::vector<std::string>, FilterDescriptions, (), (const, noexcept, override));
};

}// namespace ECFMP::Mock::FlowMeasure
1 change: 1 addition & 0 deletions include/mock/LevelRangeFilterMock.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ namespace ECFMP::Mock::FlowMeasure {
MOCK_METHOD(bool, ApplicableToAltitude, (int), (const, noexcept, override));
MOCK_METHOD(bool, ApplicableToLevel, (int), (const, noexcept, override));
MOCK_METHOD(bool, ApplicableToAircraft, (const Euroscope::EuroscopeAircraft&), (const, noexcept, override));
MOCK_METHOD(std::string, FilterDescription, (), (const, noexcept, override));
};

}// namespace ECFMP::Mock::FlowMeasure
1 change: 1 addition & 0 deletions include/mock/MeasureMock.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace ECFMP::Mock::FlowMeasure {
MOCK_METHOD(int, IntegerValue, (), (const, override));
MOCK_METHOD(double, DoubleValue, (), (const, override));
MOCK_METHOD(const std::set<std::string>&, SetValue, (), (const, override));
MOCK_METHOD(std::string, MeasureDescription, (), (const, noexcept, override));
};

}// namespace ECFMP::Mock::FlowMeasure
1 change: 1 addition & 0 deletions include/mock/MultipleLevelFilterMock.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace ECFMP::Mock::FlowMeasure {
MOCK_METHOD(bool, ApplicableToAltitude, (int), (const, noexcept, override));
MOCK_METHOD(bool, ApplicableToLevel, (int), (const, noexcept, override));
MOCK_METHOD(bool, ApplicableToAircraft, (const Euroscope::EuroscopeAircraft&), (const, noexcept, override));
MOCK_METHOD(std::string, FilterDescription, (), (const, noexcept, override));
};

}// namespace ECFMP::Mock::FlowMeasure
1 change: 1 addition & 0 deletions include/mock/RangeToDestinationFilterMock.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ namespace ECFMP::Mock::FlowMeasure {
bool, ApplicableToAircraft, (const ECFMP::Euroscope::EuroscopeAircraft&), (const, noexcept, override)
);
MOCK_METHOD(int, Range, (), (const, noexcept, override));
MOCK_METHOD(std::string, FilterDescription, (), (const, noexcept, override));
};
}// namespace ECFMP::Mock::FlowMeasure
1 change: 1 addition & 0 deletions include/mock/RouteFilterMock.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace ECFMP::Mock::FlowMeasure {
public:
MOCK_METHOD(const std::set<std::string>&, RouteStrings, (), (const, noexcept, override));
MOCK_METHOD(bool, ApplicableToAircraft, (const Euroscope::EuroscopeAircraft&), (const, noexcept, override));
MOCK_METHOD(std::string, FilterDescription, (), (const, noexcept, override));
};

}// namespace ECFMP::Mock::FlowMeasure
14 changes: 14 additions & 0 deletions src/flowmeasure/ConcreteAirportFilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,18 @@ namespace ECFMP::FlowMeasure {
type == AirportFilterType::Departure ? aircraft.DepartureAirport() : aircraft.DestinationAirport()
);
}

std::string ConcreteAirportFilter::FilterDescription() const noexcept
{
std::string description = type == AirportFilterType::Departure ? "Departing: " : "Arriving: ";

for (const auto& airportString: airportStrings) {
const auto isWildcard = airportString.find(WILDCARD_CHAR) != std::string::npos;
description += isWildcard ? "Any of: " + airportString : airportString;
description += ", ";
}

// Trim the trailing ", "
return description.substr(0, description.length() - 2);
}
}// namespace ECFMP::FlowMeasure
4 changes: 3 additions & 1 deletion src/flowmeasure/ConcreteAirportFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ namespace ECFMP::FlowMeasure {
[[nodiscard]] auto AirportStrings() const noexcept -> const std::set<std::string>& override;
[[nodiscard]] auto ApplicableToAirport(const std::string& airport) const noexcept -> bool override;
[[nodiscard]] auto Type() const noexcept -> AirportFilterType override;
auto ApplicableToAircraft(const Euroscope::EuroscopeAircraft& aircraft) const noexcept -> bool override;
[[nodiscard]] auto ApplicableToAircraft(const Euroscope::EuroscopeAircraft& aircraft) const noexcept
-> bool override;
[[nodiscard]] auto FilterDescription() const noexcept -> std::string override;

private:
// The strings for the airport filter, may contain wildcards (*)
Expand Down
5 changes: 5 additions & 0 deletions src/flowmeasure/ConcreteEventFilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,9 @@ namespace ECFMP::FlowMeasure {

return (IsParticipating() && isParticipating) || (!IsParticipating() && !isParticipating);
}

auto ConcreteEventFilter::FilterDescription() const noexcept -> std::string
{
return (IsParticipating() ? "Participating in event: " : "Not participating in event: ") + event->Name();
}
}// namespace ECFMP::FlowMeasure
1 change: 1 addition & 0 deletions src/flowmeasure/ConcreteEventFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace ECFMP::FlowMeasure {
[[nodiscard]] auto Participation() const noexcept -> EventParticipation override;
[[nodiscard]] auto IsParticipating() const noexcept -> bool override;
auto ApplicableToAircraft(const Euroscope::EuroscopeAircraft& aircraft) const noexcept -> bool override;
[[nodiscard]] auto FilterDescription() const noexcept -> std::string override;

private:
// The event in question
Expand Down
48 changes: 48 additions & 0 deletions src/flowmeasure/ConcreteFlowMeasureFilters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,4 +251,52 @@ namespace ECFMP::FlowMeasure {

return passesRangeToDestinationFilters;
}

auto ConcreteFlowMeasureFilters::FilterDescriptions() const noexcept -> std::vector<std::string>
{
std::vector<std::string> descriptions;
descriptions.reserve(
airportFilters.size() + eventFilters.size() + levelFilters.size() + multipleLevelFilters.size()
+ routeFilters.size() + rangeToDestinationFilters.size()
);

std::transform(
airportFilters.cbegin(), airportFilters.cend(), std::back_inserter(descriptions),
[](const auto& filter) {
return filter->FilterDescription();
}
);
std::transform(
eventFilters.cbegin(), eventFilters.cend(), std::back_inserter(descriptions),
[](const auto& filter) {
return filter->FilterDescription();
}
);
std::transform(
levelFilters.cbegin(), levelFilters.cend(), std::back_inserter(descriptions),
[](const auto& filter) {
return filter->FilterDescription();
}
);
std::transform(
multipleLevelFilters.cbegin(), multipleLevelFilters.cend(), std::back_inserter(descriptions),
[](const auto& filter) {
return filter->FilterDescription();
}
);
std::transform(
routeFilters.cbegin(), routeFilters.cend(), std::back_inserter(descriptions),
[](const auto& filter) {
return filter->FilterDescription();
}
);
std::transform(
rangeToDestinationFilters.cbegin(), rangeToDestinationFilters.cend(), std::back_inserter(descriptions),
[](const auto& filter) {
return filter->FilterDescription();
}
);

return descriptions;
}
}// namespace ECFMP::FlowMeasure
1 change: 1 addition & 0 deletions src/flowmeasure/ConcreteFlowMeasureFilters.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ namespace ECFMP::FlowMeasure {
[[nodiscard]] auto
FirstRangeToDestinationFilter(const std::function<bool(const RangeToDestinationFilter&)>& callback
) const noexcept -> std::shared_ptr<RangeToDestinationFilter> override;
[[nodiscard]] auto FilterDescriptions() const noexcept -> std::vector<std::string> override;

private:
// All the airport filters
Expand Down
6 changes: 6 additions & 0 deletions src/flowmeasure/ConcreteLevelRangeFilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,10 @@ namespace ECFMP::FlowMeasure {
{
return ApplicableToAltitude(aircraft.CruiseAltitude());
}

auto ConcreteLevelRangeFilter::FilterDescription() const noexcept -> std::string
{
return type == LevelRangeFilterType::AtOrBelow ? "At or below: FL" + std::to_string(filterLevel)
: "At or above: FL" + std::to_string(filterLevel);
}
}// namespace ECFMP::FlowMeasure
1 change: 1 addition & 0 deletions src/flowmeasure/ConcreteLevelRangeFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ namespace ECFMP::FlowMeasure {
[[nodiscard]] auto ApplicableToLevel(int level) const noexcept -> bool override;
[[nodiscard]] auto ApplicableToAltitude(int level) const noexcept -> bool override;
auto ApplicableToAircraft(const Euroscope::EuroscopeAircraft& aircraft) const noexcept -> bool override;
[[nodiscard]] auto FilterDescription() const noexcept -> std::string override;

private:
// The type of level filter this is
Expand Down
88 changes: 88 additions & 0 deletions src/flowmeasure/ConcreteMeasure.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
#include "ConcreteMeasure.h"
#include "ECFMP/flowmeasure/Measure.h"
#include <stdexcept>
#include <string>

namespace ECFMP::FlowMeasure {

Expand Down Expand Up @@ -49,4 +52,89 @@ namespace ECFMP::FlowMeasure {
throw IllegalFlowMeasureValueException();
}
}

auto ConcreteMeasure::MeasureDescription() const noexcept -> std::string
{
// No value type associated with these
if (type == MeasureType::GroundStop || type == MeasureType::Prohibit) {
return MeasureTypeToString(type);
}

return MeasureTypeToString(type) + ": " + MeasureValueToString(type);
}

auto ConcreteMeasure::MeasureTypeToString(MeasureType type) -> std::string
{
switch (type) {
case MeasureType::MinimumDepartureInterval:
return "Minimum Departure Interval";
case MeasureType::AverageDepartureInterval:
return "Average Departure Interval";
case MeasureType::PerHour:
return "Per Hour";
case MeasureType::MilesInTrail:
return "Miles in Trail";
case MeasureType::MaxIndicatedAirspeed:
return "Max IAS";
case MeasureType::IndicatedAirspeedReduction:
return "IAS Reduction";
case MeasureType::MaxMach:
return "Max Mach";
case MeasureType::MachReduction:
return "Mach Reduction";
case MeasureType::MandatoryRoute:
return "Mandatory Route(s)";
case MeasureType::Prohibit:
return "Prohibit";
case MeasureType::GroundStop:
return "Ground Stop";
default:
return "Unknown";
}
}

auto ConcreteMeasure::MeasureValueToString(MeasureType measureType) const -> std::string
{
switch (measureType) {
case MeasureType::MinimumDepartureInterval:
case MeasureType::AverageDepartureInterval: {
const auto extraSeconds = intValue % 60;
const auto minutes = intValue / 60;

if (minutes == 0) {
return std::to_string(extraSeconds) + " seconds";
}

if (extraSeconds == 0) {
return std::to_string(minutes) + " minutes";
}

return std::to_string(minutes) + " minutes " + std::to_string(extraSeconds) + " seconds";
}
case MeasureType::PerHour:
case MeasureType::MilesInTrail:
return std::to_string(intValue);
case MeasureType::MaxIndicatedAirspeed:
case MeasureType::IndicatedAirspeedReduction:
return std::to_string(intValue) + "kts";
case MeasureType::MaxMach:
case MeasureType::MachReduction: {
std::stringstream stream;
stream << std::fixed << std::setprecision(2) << doubleValue;
return stream.str();
}
case MeasureType::MandatoryRoute: {
std::string routeString;
for (const auto& route: setValue) {
routeString += route + ", ";
}
return routeString.substr(0, routeString.size() - 2);
}
case MeasureType::Prohibit:
case MeasureType::GroundStop:
throw std::logic_error("MeasureType::Prohibit and MeasureType::GroundStop have no value");
}

return "Unknown";
}
}// namespace ECFMP::FlowMeasure
Loading