#include <config.h>
#include <utils/xml/SUMOXMLDefinitions.h>
#include <microsim/MSNet.h>
#include <microsim/actions/Command_SaveTLSState.h>
#include <microsim/actions/Command_SaveTLSSwitches.h>
#include <microsim/actions/Command_SaveTLSSwitchStates.h>
#include <microsim/actions/Command_SaveTLSProgram.h>
#include <microsim/MSEventControl.h>
#include <microsim/traffic_lights/MSTLLogicControl.h>
#include <microsim/traffic_lights/MSTrafficLightLogic.h>
#include <utils/common/FileHelpers.h>
#include <utils/common/UtilExceptions.h>
#include <utils/iodevices/OutputDevice.h>
#include "NLDiscreteEventBuilder.h"
NLDiscreteEventBuilder::NLDiscreteEventBuilder(MSNet& net)
: myNet(net) {
myActions["SaveTLSStates"] = EV_SAVETLSTATE;
myActions["SaveTLSSwitchTimes"] = EV_SAVETLSWITCHES;
myActions["SaveTLSSwitchStates"] = EV_SAVETLSWITCHSTATES;
myActions["SaveTLSProgram"] = EV_SAVETLSPROGRAM;
}
NLDiscreteEventBuilder::~NLDiscreteEventBuilder() {}
void
NLDiscreteEventBuilder::addAction(const SUMOSAXAttributes& attrs,
const std::string& basePath) {
bool ok = true;
const std::string type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, nullptr, ok, "");
if (type == "" || !ok) {
throw InvalidArgument("An action's type is not given.");
}
KnownActions::iterator i = myActions.find(type);
if (i == myActions.end()) {
throw InvalidArgument("The action type '" + type + "' is not known.");
}
switch ((*i).second) {
case EV_SAVETLSTATE:
buildSaveTLStateCommand(attrs, basePath);
break;
case EV_SAVETLSWITCHES:
buildSaveTLSwitchesCommand(attrs, basePath);
break;
case EV_SAVETLSWITCHSTATES:
buildSaveTLSwitchStatesCommand(attrs, basePath);
break;
case EV_SAVETLSPROGRAM:
buildSaveTLSProgramCommand(attrs, basePath);
break;
}
}
void
NLDiscreteEventBuilder::buildSaveTLStateCommand(const SUMOSAXAttributes& attrs,
const std::string& basePath) {
bool ok = true;
const std::string dest = attrs.getOpt<std::string>(SUMO_ATTR_DEST, nullptr, ok, "");
const std::string source = attrs.getOpt<std::string>(SUMO_ATTR_SOURCE, nullptr, ok, "");
const bool saveDetectors = attrs.getOpt<bool>(SUMO_ATTR_SAVE_DETECTORS, nullptr, ok, false);
const bool saveConditions = attrs.getOpt<bool>(SUMO_ATTR_SAVE_CONDITIONS, nullptr, ok, false);
if (dest == "" || !ok) {
throw InvalidArgument("Incomplete description of an 'SaveTLSState'-action occurred.");
}
if (source == "") {
const std::vector<std::string> ids = myNet.getTLSControl().getAllTLIds();
for (std::vector<std::string>::const_iterator tls = ids.begin(); tls != ids.end(); ++tls) {
const MSTLLogicControl::TLSLogicVariants& logics = myNet.getTLSControl().get(*tls);
new Command_SaveTLSState(logics, OutputDevice::getDevice(FileHelpers::checkForRelativity(dest, basePath)),
saveDetectors, saveConditions);
}
} else {
if (!myNet.getTLSControl().knows(source)) {
throw InvalidArgument("The traffic light logic to save (" + source + ") is not known.");
}
const MSTLLogicControl::TLSLogicVariants& logics = myNet.getTLSControl().get(source);
new Command_SaveTLSState(logics, OutputDevice::getDevice(FileHelpers::checkForRelativity(dest, basePath)),
saveDetectors, saveConditions);
}
}
void
NLDiscreteEventBuilder::buildSaveTLSwitchesCommand(const SUMOSAXAttributes& attrs,
const std::string& basePath) {
bool ok = true;
const std::string dest = attrs.getOpt<std::string>(SUMO_ATTR_DEST, nullptr, ok, "");
const std::string source = attrs.getOpt<std::string>(SUMO_ATTR_SOURCE, nullptr, ok, "");
if (dest == "" || !ok) {
throw InvalidArgument("Incomplete description of an 'SaveTLSSwitchTimes'-action occurred.");
}
if (source == "") {
const std::vector<std::string> ids = myNet.getTLSControl().getAllTLIds();
for (std::vector<std::string>::const_iterator tls = ids.begin(); tls != ids.end(); ++tls) {
const MSTLLogicControl::TLSLogicVariants& logics = myNet.getTLSControl().get(*tls);
new Command_SaveTLSSwitches(logics, OutputDevice::getDevice(FileHelpers::checkForRelativity(dest, basePath)));
}
} else {
if (!myNet.getTLSControl().knows(source)) {
throw InvalidArgument("The traffic light logic to save (" + source + ") is not known.");
}
const MSTLLogicControl::TLSLogicVariants& logics = myNet.getTLSControl().get(source);
new Command_SaveTLSSwitches(logics, OutputDevice::getDevice(FileHelpers::checkForRelativity(dest, basePath)));
}
}
void
NLDiscreteEventBuilder::buildSaveTLSwitchStatesCommand(const SUMOSAXAttributes& attrs,
const std::string& basePath) {
bool ok = true;
const std::string dest = attrs.getOpt<std::string>(SUMO_ATTR_DEST, nullptr, ok, "");
const std::string source = attrs.getOpt<std::string>(SUMO_ATTR_SOURCE, nullptr, ok, "");
if (dest == "" || !ok) {
throw InvalidArgument("Incomplete description of an 'SaveTLSSwitchStates'-action occurred.");
}
if (source == "") {
const std::vector<std::string> ids = myNet.getTLSControl().getAllTLIds();
for (std::vector<std::string>::const_iterator tls = ids.begin(); tls != ids.end(); ++tls) {
const MSTLLogicControl::TLSLogicVariants& logics = myNet.getTLSControl().get(*tls);
new Command_SaveTLSSwitchStates(logics, OutputDevice::getDevice(FileHelpers::checkForRelativity(dest, basePath)));
}
} else {
if (!myNet.getTLSControl().knows(source)) {
throw InvalidArgument("The traffic light logic to save (" + source + ") is not known.");
}
const MSTLLogicControl::TLSLogicVariants& logics = myNet.getTLSControl().get(source);
new Command_SaveTLSSwitchStates(logics, OutputDevice::getDevice(FileHelpers::checkForRelativity(dest, basePath)));
}
}
void
NLDiscreteEventBuilder::buildSaveTLSProgramCommand(const SUMOSAXAttributes& attrs,
const std::string& basePath) {
bool ok = true;
const std::string dest = attrs.getOpt<std::string>(SUMO_ATTR_DEST, nullptr, ok, "");
const std::string source = attrs.getOpt<std::string>(SUMO_ATTR_SOURCE, nullptr, ok, "");
if (dest == "" || !ok) {
throw InvalidArgument("Incomplete description of an 'SaveTLSProgram'-action occurred.");
}
if (source == "") {
const std::vector<std::string> ids = myNet.getTLSControl().getAllTLIds();
for (std::vector<std::string>::const_iterator tls = ids.begin(); tls != ids.end(); ++tls) {
const MSTLLogicControl::TLSLogicVariants& logics = myNet.getTLSControl().get(*tls);
new Command_SaveTLSProgram(logics, OutputDevice::getDevice(FileHelpers::checkForRelativity(dest, basePath)));
}
} else {
if (!myNet.getTLSControl().knows(source)) {
throw InvalidArgument("The traffic light logic to save (" + source + ") is not known.");
}
const MSTLLogicControl::TLSLogicVariants& logics = myNet.getTLSControl().get(source);
new Command_SaveTLSProgram(logics, OutputDevice::getDevice(FileHelpers::checkForRelativity(dest, basePath)));
}
}