Skip to content

Commit

Permalink
Merge pull request #15 from EvenAR/custom-labels
Browse files Browse the repository at this point in the history
Custom labels + closeable window
  • Loading branch information
EvenAR authored Jun 10, 2021
2 parents 118f290 + d7c81a7 commit b4013b7
Show file tree
Hide file tree
Showing 21 changed files with 416 additions and 223 deletions.
1 change: 1 addition & 0 deletions Aman/Aman.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\..\..\..\..\Program Files (x86)\EuroScope\PlugInEnvironment\EuroScopePlugIn.h" />
<ClInclude Include="AmanTagItem.h" />
<ClInclude Include="EventEmitter.h" />
<ClInclude Include="Aman.h" />
<ClInclude Include="AmanAircraft.h" />
Expand Down
3 changes: 3 additions & 0 deletions Aman/Aman.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@
<ClInclude Include="MenuBar.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="AmanTagItem.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Aman.rc">
Expand Down
1 change: 1 addition & 0 deletions Aman/AmanAircraft.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class AmanAircraft {
std::string arrivalRunway;
std::string icaoType;
std::string nextFix;
std::string scratchPad;

int viaFixIndex;

Expand Down
26 changes: 19 additions & 7 deletions Aman/AmanController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@

AmanController::AmanController(AmanPlugIn* plugin) {
this->amanModel = plugin;
this->amanWindow = NULL;
this->amanWindow = std::make_shared<AmanWindow>(this);
}

AmanController::~AmanController() {}
Expand All @@ -22,9 +20,7 @@ void AmanController::modelUpdated() {
}

void AmanController::toggleTimeline(const std::string& id) {
bool isActive = std::find(activeTimelines.begin(), activeTimelines.end(), id) != activeTimelines.end();

if (isActive) {
if (isTimelineActive(id)) {
activeTimelines.erase(
std::remove(activeTimelines.begin(), activeTimelines.end(), id),
activeTimelines.end()
Expand All @@ -35,11 +31,27 @@ void AmanController::toggleTimeline(const std::string& id) {
modelUpdated();
}

bool AmanController::isTimelineActive(const std::string& id) {
return std::find(activeTimelines.begin(), activeTimelines.end(), id) != activeTimelines.end();
}

void AmanController::reloadProfiles() {
this->amanModel->requestReload();
}

void AmanController::setTimelineHorizon(const std::string& id, uint32_t minutes) {
this->amanWindow->setTimelineHorizon(id, minutes);
bool AmanController::openWindow() {
if (this->amanWindow == nullptr) {
this->amanWindow = std::make_shared<AmanWindow>(this);
return true;
}
}

bool AmanController::closeWindow() {
if (this->amanWindow == nullptr) {
return false;
} else {
this->amanWindow.reset();
return true;
}
}

4 changes: 3 additions & 1 deletion Aman/AmanController.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ class AmanController {
AmanController(AmanPlugIn* model);
void modelUpdated();
void toggleTimeline(const std::string& id);
bool isTimelineActive(const std::string& id);
void reloadProfiles();
void setTimelineHorizon(const std::string& id, uint32_t minutes);
bool openWindow();
bool closeWindow();

~AmanController();

Expand Down
114 changes: 78 additions & 36 deletions Aman/AmanPlugIn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "AmanPlugIn.h"
#include "AmanTimeline.h"
#include "AmanWindow.h"
#include "AmanTagItem.h"
#include "stdafx.h"
#include "windows.h"
#include "rapidjson/document.h"
Expand All @@ -17,6 +18,7 @@
#include <string>
#include <vector>
#include <fstream>
#include <map>

#define TO_UPPERCASE(str) std::transform(str.begin(), str.end(), str.begin(), ::toupper);
#define REMOVE_EMPTY(strVec, output) \
Expand All @@ -26,26 +28,24 @@
str.pop_back();
#define DISPLAY_WARNING(str) DisplayUserMessage("Aman", "Warning", str, true, true, true, true, false);

AmanPlugIn::AmanPlugIn() : CPlugIn(COMPATIBILITY_CODE, "Arrival Manager", "2.1.0", "https://git.io/Jt3S8", "Open source") {
AmanPlugIn::AmanPlugIn() : CPlugIn(COMPATIBILITY_CODE, "Arrival Manager", "3.0.1", "https://git.io/Jt3S8", "Open source") {
// Find directory of this .dll
char fullPluginPath[_MAX_PATH];
GetModuleFileNameA((HINSTANCE)&__ImageBase, fullPluginPath, sizeof(fullPluginPath));
std::string fullPluginPathStr(fullPluginPath);
pluginDirectory = fullPluginPathStr.substr(0, fullPluginPathStr.find_last_of("\\"));

amanController = std::make_shared<AmanController>(this);

loadTimelines("aman-config.json");

amanController->modelUpdated();
}

AmanPlugIn::~AmanPlugIn() {

}

std::set<std::string> AmanPlugIn::getAvailableIds() {
std::set<std::string> set;
for (auto timeline : timelines) {
for (auto& timeline : timelines) {
set.insert(timeline->getIdentifier());
}
return set;
Expand Down Expand Up @@ -115,6 +115,7 @@ std::vector<AmanAircraft> AmanPlugIn::getInboundsForFix(const std::string& fixNa
ac.eta = timeNow + timeToFix - rt.GetPosition().GetReceivedTime();
ac.distLeft = findRemainingDist(rt, route, targetFixIndex);
ac.secondsBehindPreceeding = 0; // Updated in the for-loop below
ac.scratchPad = rt.GetCorrelatedFlightPlan().GetControllerAssignedData().GetScratchPadString();
aircraftList.push_back(ac);
}
}
Expand All @@ -138,9 +139,19 @@ void AmanPlugIn::OnTimer(int Counter) {
amanController->modelUpdated();
}

bool AmanPlugIn::OnCompileCommand(const char* sCommandLine) {
if (strcmp(sCommandLine, ".aman open") == 0) {
return this->amanController->openWindow();
} else if (strcmp(sCommandLine, ".aman close") == 0) {
return this->amanController->closeWindow();
}
return false;
}

void AmanPlugIn::loadTimelines(const std::string& filename) {
std::ifstream file(pluginDirectory + "\\" + filename);
std::string fileContent((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
std::map<std::string, std::vector<std::shared_ptr<TagItem>>> tagLayouts;

if (fileContent.empty()) {
DISPLAY_WARNING((filename + ": the JSON-file was not found or is empty").c_str());
Expand All @@ -159,44 +170,75 @@ void AmanPlugIn::loadTimelines(const std::string& filename) {
return;
}

for (auto& v : document["timelines"].GetArray()) {
auto object = v.GetObjectA();

std::vector<std::string> targetFixes;
for (auto& fix : object["targetFixes"].GetArray()) {
targetFixes.push_back(fix.GetString());
if (document.HasMember("tagLayouts") && document["tagLayouts"].IsObject()) {
for (auto property = document["tagLayouts"].MemberBegin(); property != document["tagLayouts"].MemberEnd(); ++property) {
auto layoutId = property->name.GetString();
std::vector<std::shared_ptr<TagItem>> tagItems;
for (auto& tagItemObj : property->value.GetArray()) {
auto dataSource = tagItemObj.HasMember("source") ? tagItemObj["source"].GetString() : "";
auto width = tagItemObj.HasMember("width") ? tagItemObj["width"].GetUint() : 1;
auto defaultValue = tagItemObj.HasMember("defaultValue") ? tagItemObj["defaultValue"].GetString() : "";
auto alignRight = tagItemObj.HasMember("rightAligned") && tagItemObj["rightAligned"].GetBool();
auto isViaFixIndicator = tagItemObj.HasMember("isViaFixIndicator") && tagItemObj["isViaFixIndicator"].GetBool();

tagItems.push_back(std::make_shared<TagItem>(dataSource, defaultValue, width, alignRight, isViaFixIndicator));
}
tagLayouts[layoutId] = tagItems;
}
}

if (document.HasMember("timelines") && document["timelines"].IsObject()) {
for (auto property = document["timelines"].MemberBegin(); property != document["timelines"].MemberEnd(); ++property) {
auto object = property->value.GetObjectA();

std::vector<std::string> viaFixes;
if (object.HasMember("viaFixes") && object["viaFixes"].IsArray()) {
for (auto& fix : object["viaFixes"].GetArray()) {
viaFixes.push_back(fix.GetString());
std::vector<std::string> targetFixes;
for (auto& fix : object["targetFixes"].GetArray()) {
targetFixes.push_back(fix.GetString());
}
}

std::vector<std::string> destinationAirports;
if (object.HasMember("destinationAirports") && object["destinationAirports"].IsArray()) {
for (auto& destination : object["destinationAirports"].GetArray()) {
destinationAirports.push_back(destination.GetString());
std::vector<std::string> viaFixes;
if (object.HasMember("viaFixes") && object["viaFixes"].IsArray()) {
for (auto& fix : object["viaFixes"].GetArray()) {
viaFixes.push_back(fix.GetString());
}
}
}

std::string alias;
if (object.HasMember("alias") && object["alias"].IsString()) {
alias = object["alias"].GetString();
} else {
alias = "";
for (const auto& piece : targetFixes) alias += piece + "/";
alias = alias.substr(0, alias.size() - 1);
}
std::vector<std::string> destinationAirports;
if (object.HasMember("destinationAirports") && object["destinationAirports"].IsArray()) {
for (auto& destination : object["destinationAirports"].GetArray()) {
destinationAirports.push_back(destination.GetString());
}
}

uint32_t startHorizon;
if (object.HasMember("startHorizon") && object["startHorizon"].IsUint()) {
startHorizon = object["startHorizon"].GetUint();
amanController->setTimelineHorizon(alias, startHorizon);
std::vector<std::shared_ptr<TagItem>> tagItems;
if (object.HasMember("tagLayout") && object["tagLayout"].IsString()) {
tagItems = tagLayouts[object["tagLayout"].GetString()];
} else {
tagItems = {};
}

uint32_t defaultTimeSpan;
if (object.HasMember("defaultTimeSpan") && object["defaultTimeSpan"].IsUint()) {
defaultTimeSpan = object["defaultTimeSpan"].GetUint();
} else {
defaultTimeSpan = 30;
}

timelines.push_back(std::make_shared<AmanTimeline>(targetFixes, viaFixes, destinationAirports, tagItems, property->name.GetString(), defaultTimeSpan));
}
}

timelines.push_back(std::make_shared<AmanTimeline>(targetFixes, viaFixes, destinationAirports, alias));
auto makeSureWindowIsOpen = document.HasMember("openAutomatically") ? document["openAutomatically"].GetBool() : true;
if (makeSureWindowIsOpen) {
this->amanController->openWindow();
}

// If only one timeline, open it automatically:
if (timelines.size() == 1) {
auto onlyTimelineId = timelines.at(0)->getIdentifier();
if (!this->amanController->isTimelineActive(onlyTimelineId)) {
this->amanController->toggleTimeline(onlyTimelineId);
}
}
}

Expand Down Expand Up @@ -250,8 +292,8 @@ std::shared_ptr<std::vector<std::shared_ptr<AmanTimeline>>> AmanPlugIn::getTimel

pAircraftList->clear();
for each (auto finalFix in fixes) {
auto var = getInboundsForFix(finalFix, viaFixes, timeline->getDestinationAirports());
pAircraftList->insert(pAircraftList->end(), var.begin(), var.end());
auto inbounds = getInboundsForFix(finalFix, viaFixes, timeline->getDestinationAirports());
pAircraftList->insert(pAircraftList->end(), inbounds.begin(), inbounds.end());
}

result->push_back(timeline);
Expand Down
1 change: 1 addition & 0 deletions Aman/AmanPlugIn.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class AmanPlugIn : public CPlugIn {
std::string pluginDirectory;

virtual void OnTimer(int Counter);
virtual bool OnCompileCommand(const char* sCommandLine);

bool hasCorrectDestination(CFlightPlanData fpd, std::vector<std::string> destinationAirports);
int getFixIndexByName(CFlightPlanExtractedRoute extractedRoute, const std::string& fixName);
Expand Down
24 changes: 24 additions & 0 deletions Aman/AmanTagItem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once
#include <string>

class TagItem {
public:
TagItem(const std::string& source, const std::string& defaultValue, uint32_t width, bool rightAligned, bool isViaFixIndicator) {
this->source = source;
this->width = width;
this->rightAligned = rightAligned;
this->defaultValue = defaultValue;
this->isViaFixIndicator = isViaFixIndicator;
}
std::string getSource() { return source; };
std::string getDefaultValue() { return defaultValue; };
uint32_t getWidth() { return width; };
bool isRightAligned() { return rightAligned; };
bool getIsViaFixIndicator() { return isViaFixIndicator; };
private:
std::string source;
std::string defaultValue;
bool isViaFixIndicator;
uint32_t width;
bool rightAligned;
};
31 changes: 16 additions & 15 deletions Aman/AmanTimeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,33 @@

#include <iterator>
#include <sstream>
#include <numeric>

#include "AmanAircraft.h"
#include "AmanTimeline.h"

AmanTimeline::AmanTimeline(std::vector<std::string> fixes, std::vector<std::string> viaFixes, std::vector<std::string> destinations, const std::string& alias) {
#include "AmanTagItem.h"

AmanTimeline::AmanTimeline(
std::vector<std::string> fixes,
std::vector<std::string> viaFixes,
std::vector<std::string> destinations,
std::vector<std::shared_ptr<TagItem>> tagItems,
const std::string& alias,
uint32_t defaultTimeSpan) {
this->fixes = fixes;
this->viaFixes = viaFixes;
this->aircraftList = std::vector<AmanAircraft>();
this->destinationAirports = destinations;
this->tagItems = tagItems;
this->alias = alias;
this->defaultTimeSpan = defaultTimeSpan;

auto addWidth = [](uint32_t acc, std::shared_ptr<TagItem> tagItem) { return acc + tagItem->getWidth(); };
this->width = std::accumulate(tagItems.begin(), tagItems.end(), 0, addWidth);
}

std::string AmanTimeline::getIdentifier() {
if(!alias.empty()) return alias;
switch (fixes.size()) {
case 1:
return fixes.at(0);
case 2:
return fixes.at(0) + "/" + fixes.at(1);
default:
std::ostringstream fixesSs;
copy(fixes.begin(), fixes.end(), std::ostream_iterator<std::string>(fixesSs, "/"));
std::string output = fixesSs.str();
output.pop_back(); // Remove last '/'
return output;
}
return alias;
}

bool AmanTimeline::isDual() { return fixes.size() == 2; }
Expand Down
Loading

0 comments on commit b4013b7

Please sign in to comment.