mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-09-01 13:59:19 +02:00
refactor: moving Train to separate directory
This commit is contained in:
851
vehicle/train/TrainCommandsDoors.cpp
Normal file
851
vehicle/train/TrainCommandsDoors.cpp
Normal file
@@ -0,0 +1,851 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "vehicle/Train.h"
|
||||
|
||||
#include "simulation/simulation.h"
|
||||
#include "world/Event.h"
|
||||
#include "simulation/simulationtime.h"
|
||||
#include "utilities/Logs.h"
|
||||
#include "model/Model3d.h"
|
||||
#include "vehicle/Driver.h"
|
||||
#include "vehicle/DynObj.h"
|
||||
#include "rendering/renderer.h"
|
||||
#include <future>
|
||||
|
||||
void TTrain::OnCommand_doorlocktoggle(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Train->ggDoorSignallingButton.SubModel == nullptr)
|
||||
{
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
WriteLog("Door Lock switch is missing, or wasn't defined");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// only reacting to press, so the sound can loop uninterrupted
|
||||
if (false == Train->mvOccupied->Doors.lock_enabled)
|
||||
{
|
||||
// turn on
|
||||
// TODO: door lock command to send through consist
|
||||
Train->mvOccupied->LockDoors(true);
|
||||
// visual feedback
|
||||
Train->ggDoorSignallingButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
// turn off
|
||||
// TODO: door lock command to send through consist
|
||||
Train->mvOccupied->LockDoors(false);
|
||||
// visual feedback
|
||||
Train->ggDoorSignallingButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_doortoggleleft(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// NOTE: test how the door state check works with consists where the occupied vehicle doesn't have opening doors
|
||||
if (false == (Train->ggDoorLeftButton.GetDesiredValue() > 0.5 || Train->ggDoorLeftOnButton.GetDesiredValue() > 0.5))
|
||||
{
|
||||
// open
|
||||
OnCommand_dooropenleft(Train, Command);
|
||||
}
|
||||
else
|
||||
{
|
||||
// close
|
||||
if (Train->ggDoorAllOffButton.SubModel != nullptr && Train->ggDoorLeftOffButton.SubModel == nullptr)
|
||||
{
|
||||
// OnCommand_doorcloseall( Train, Command );
|
||||
// if two-button setup lacks dedicated closing button require the user to press appropriate button manually
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
OnCommand_doorcloseleft(Train, Command);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
|
||||
if (true == (Train->ggDoorLeftButton.GetDesiredValue() > 0.5 || Train->ggDoorLeftOnButton.GetDesiredValue() > 0.5))
|
||||
{
|
||||
// open
|
||||
if (Train->mvOccupied->Doors.has_autowarning && Train->mvOccupied->DepartureSignal)
|
||||
{
|
||||
// complete closing the doors
|
||||
if (Train->ggDoorAllOffButton.SubModel != nullptr && Train->ggDoorLeftOffButton.SubModel == nullptr)
|
||||
{
|
||||
// OnCommand_doorcloseall( Train, Command );
|
||||
// if two-button setup lacks dedicated closing button require the user to press appropriate button manually
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
OnCommand_doorcloseleft(Train, Command);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
OnCommand_dooropenleft(Train, Command);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// close
|
||||
if (Train->ggDoorAllOffButton.SubModel != nullptr && Train->ggDoorLeftOffButton.SubModel == nullptr)
|
||||
{
|
||||
// OnCommand_doorcloseall( Train, Command );
|
||||
// if two-button setup lacks dedicated closing button require the user to press appropriate button manually
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
OnCommand_doorcloseleft(Train, Command);
|
||||
}
|
||||
}
|
||||
// visual feedback
|
||||
// dedicated closing buttons are presumed to be impulse switches and return automatically to neutral position
|
||||
// NOTE: temporary arrangement, can be removed when LD system is in place
|
||||
if (Train->ggDoorLeftOffButton.SubModel)
|
||||
Train->ggDoorLeftOffButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
if (Train->ggDoorLeftOnButton.SubModel)
|
||||
Train->ggDoorLeftOnButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_doorpermitleft(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_REPEAT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (false == Train->mvOccupied->Doors.permit_presets.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto const side{(Train->cab_to_end() == end::front ? side::left : side::right)};
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
|
||||
if (Train->ggDoorLeftPermitButton.is_push())
|
||||
{
|
||||
// impulse switch
|
||||
Train->mvOccupied->PermitDoors(side);
|
||||
// visual feedback
|
||||
Train->ggDoorLeftPermitButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
// start potential timer for remote door control
|
||||
Train->m_doorpermittimers[side] = Train->mvOccupied->DoorsOpenWithPermitAfter;
|
||||
}
|
||||
else
|
||||
{
|
||||
// two-state switch
|
||||
auto const newstate{!(Train->ggDoorLeftPermitButton.GetDesiredValue() > 0.5)};
|
||||
|
||||
Train->mvOccupied->PermitDoors(side, newstate);
|
||||
// visual feedback
|
||||
Train->ggDoorLeftPermitButton.UpdateValue(newstate ? 1.0 : 0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE && Train->ggDoorLeftPermitButton.is_push())
|
||||
{
|
||||
|
||||
// impulse switch
|
||||
// visual feedback
|
||||
Train->ggDoorLeftPermitButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
// reset potential remote door control timer
|
||||
Train->m_doorpermittimers[side] = -1.f;
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_doorpermitright(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_REPEAT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (false == Train->mvOccupied->Doors.permit_presets.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto const side{(Train->cab_to_end() == end::front ? side::right : side::left)};
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
|
||||
if (Train->ggDoorRightPermitButton.type() == TGaugeType::push)
|
||||
{
|
||||
// impulse switch
|
||||
Train->mvOccupied->PermitDoors(side);
|
||||
// visual feedback
|
||||
Train->ggDoorRightPermitButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
// start potential timer for remote door control
|
||||
Train->m_doorpermittimers[side] = Train->mvOccupied->DoorsOpenWithPermitAfter;
|
||||
}
|
||||
else
|
||||
{
|
||||
// two-state switch
|
||||
auto const newstate{!(Train->ggDoorRightPermitButton.GetDesiredValue() > 0.5)};
|
||||
|
||||
Train->mvOccupied->PermitDoors(side, newstate);
|
||||
// visual feedback
|
||||
Train->ggDoorRightPermitButton.UpdateValue(newstate ? 1.0 : 0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE && Train->ggDoorRightPermitButton.type() == TGaugeType::push)
|
||||
{
|
||||
|
||||
// impulse switch
|
||||
// visual feedback
|
||||
Train->ggDoorRightPermitButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
// reset potential remote door control timer
|
||||
Train->m_doorpermittimers[side] = -1.f;
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_doorpermitpresetactivatenext(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
|
||||
Train->mvOccupied->ChangeDoorPermitPreset(1);
|
||||
// visual feedback
|
||||
Train->ggDoorPermitPresetButton.UpdateValue(Train->mvOccupied->Doors.permit_preset, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_doorpermitpresetactivateprevious(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
|
||||
Train->mvOccupied->ChangeDoorPermitPreset(-1);
|
||||
// visual feedback
|
||||
Train->ggDoorPermitPresetButton.UpdateValue(Train->mvOccupied->Doors.permit_preset, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_dooropenleft(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
auto const remoteopencontrol{Train->mvOccupied->Doors.open_control == control_t::driver || Train->mvOccupied->Doors.open_control == control_t::mixed};
|
||||
|
||||
if (false == remoteopencontrol)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->ggDoorLeftOnButton.SubModel == nullptr && Train->ggDoorLeftButton.SubModel == nullptr)
|
||||
{
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
Train->mvOccupied->OperateDoors(Train->cab_to_end() == end::front ? side::left : side::right, true);
|
||||
// visual feedback
|
||||
if (Train->ggDoorLeftOnButton.SubModel != nullptr)
|
||||
{
|
||||
// two separate impulse switches
|
||||
Train->ggDoorLeftOnButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
// single two-state switch
|
||||
Train->ggDoorLeftButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE && Train->ggDoorLeftOnButton.SubModel != nullptr)
|
||||
{
|
||||
// visual feedback
|
||||
// two separate impulse switches
|
||||
Train->ggDoorLeftOnButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_doorcloseleft(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
auto const remoteclosecontrol{Train->mvOccupied->Doors.close_control == control_t::driver || Train->mvOccupied->Doors.close_control == control_t::mixed};
|
||||
|
||||
if (false == remoteclosecontrol)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->ggDoorLeftOffButton.SubModel == nullptr && Train->ggDoorLeftButton.SubModel == nullptr)
|
||||
{
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
|
||||
if (Train->mvOccupied->Doors.has_autowarning)
|
||||
{
|
||||
// automatic departure signal delays actual door closing until the button is released
|
||||
Train->mvOccupied->signal_departure(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: move door opening/closing to the update, so the switch animation doesn't hinge on door working
|
||||
Train->mvOccupied->OperateDoors(Train->cab_to_end() == end::front ? side::left : side::right, false);
|
||||
}
|
||||
// visual feedback
|
||||
if (Train->ggDoorLeftOffButton.SubModel != nullptr)
|
||||
{
|
||||
// two separate switches to open and close the door
|
||||
Train->ggDoorLeftOffButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
// single two-state switch
|
||||
Train->ggDoorLeftButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
|
||||
if (Train->mvOccupied->Doors.has_autowarning)
|
||||
{
|
||||
// automatic departure signal delays actual door closing until the button is released
|
||||
Train->mvOccupied->signal_departure(false);
|
||||
// now we can actually close the door
|
||||
Train->mvOccupied->OperateDoors(Train->cab_to_end() == end::front ? side::left : side::right, false);
|
||||
}
|
||||
// visual feedback
|
||||
// dedicated closing buttons are presumed to be impulse switches and return automatically to neutral position
|
||||
if (Train->ggDoorLeftOffButton.SubModel)
|
||||
Train->ggDoorLeftOffButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_doortoggleright(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// NOTE: test how the door state check works with consists where the occupied vehicle doesn't have opening doors
|
||||
if (false == (Train->ggDoorRightButton.GetDesiredValue() > 0.5 || Train->ggDoorRightOnButton.GetDesiredValue() > 0.5))
|
||||
{
|
||||
// open
|
||||
OnCommand_dooropenright(Train, Command);
|
||||
}
|
||||
else
|
||||
{
|
||||
// close
|
||||
if (Train->ggDoorAllOffButton.SubModel != nullptr && Train->ggDoorRightOffButton.SubModel == nullptr)
|
||||
{
|
||||
// OnCommand_doorcloseall( Train, Command );
|
||||
// if two-button setup lacks dedicated closing button require the user to press appropriate button manually
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
OnCommand_doorcloseright(Train, Command);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
|
||||
if (true == (Train->ggDoorRightButton.GetDesiredValue() > 0.5 || Train->ggDoorRightOnButton.GetDesiredValue() > 0.5))
|
||||
{
|
||||
// open
|
||||
if (Train->mvOccupied->Doors.has_autowarning && Train->mvOccupied->DepartureSignal)
|
||||
{
|
||||
// complete closing the doors
|
||||
if (Train->ggDoorAllOffButton.SubModel != nullptr && Train->ggDoorRightOffButton.SubModel == nullptr)
|
||||
{
|
||||
// OnCommand_doorcloseall( Train, Command );
|
||||
// if two-button setup lacks dedicated closing button require the user to press appropriate button manually
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
OnCommand_doorcloseright(Train, Command);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
OnCommand_dooropenright(Train, Command);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// close
|
||||
if (Train->ggDoorAllOffButton.SubModel != nullptr && Train->ggDoorRightOffButton.SubModel == nullptr)
|
||||
{
|
||||
// OnCommand_doorcloseall( Train, Command );
|
||||
// if two-button setup lacks dedicated closing button require the user to press appropriate button manually
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
OnCommand_doorcloseright(Train, Command);
|
||||
}
|
||||
}
|
||||
// visual feedback
|
||||
// dedicated closing buttons are presumed to be impulse switches and return automatically to neutral position
|
||||
// NOTE: temporary arrangement, can be removed when LD system is in place
|
||||
if (Train->ggDoorRightOffButton.SubModel)
|
||||
Train->ggDoorRightOffButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
if (Train->ggDoorRightOnButton.SubModel)
|
||||
Train->ggDoorRightOnButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_dooropenright(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
auto const remoteopencontrol{Train->mvOccupied->Doors.open_control == control_t::driver || Train->mvOccupied->Doors.open_control == control_t::mixed};
|
||||
|
||||
if (false == remoteopencontrol)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->ggDoorRightOnButton.SubModel == nullptr && Train->ggDoorRightButton.SubModel == nullptr)
|
||||
{
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
|
||||
Train->mvOccupied->OperateDoors(Train->cab_to_end() == end::front ? side::right : side::left, true);
|
||||
// visual feedback
|
||||
if (Train->ggDoorRightOnButton.SubModel != nullptr)
|
||||
{
|
||||
// two separate impulse switches
|
||||
Train->ggDoorRightOnButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
// single two-state switch
|
||||
Train->ggDoorRightButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE && Train->ggDoorRightOnButton.SubModel != nullptr)
|
||||
{
|
||||
// visual feedback
|
||||
// two separate impulse switches
|
||||
Train->ggDoorRightOnButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_doorcloseright(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
auto const remoteclosecontrol{Train->mvOccupied->Doors.close_control == control_t::driver || Train->mvOccupied->Doors.close_control == control_t::mixed};
|
||||
|
||||
if (false == remoteclosecontrol)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->ggDoorRightOffButton.SubModel == nullptr && Train->ggDoorRightButton.SubModel == nullptr)
|
||||
{
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
|
||||
if (Train->mvOccupied->Doors.has_autowarning)
|
||||
{
|
||||
// automatic departure signal delays actual door closing until the button is released
|
||||
Train->mvOccupied->signal_departure(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Train->mvOccupied->OperateDoors(Train->cab_to_end() == end::front ? side::right : side::left, false);
|
||||
}
|
||||
// visual feedback
|
||||
if (Train->ggDoorRightOffButton.SubModel != nullptr)
|
||||
{
|
||||
// two separate switches to open and close the door
|
||||
Train->ggDoorRightOffButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
// single two-state switch
|
||||
Train->ggDoorRightButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
|
||||
if (Train->mvOccupied->Doors.has_autowarning)
|
||||
{
|
||||
// automatic departure signal delays actual door closing until the button is released
|
||||
Train->mvOccupied->signal_departure(false);
|
||||
// now we can actually close the door
|
||||
Train->mvOccupied->OperateDoors(Train->cab_to_end() == end::front ? side::right : side::left, false);
|
||||
}
|
||||
// visual feedback
|
||||
// dedicated closing buttons are presumed to be impulse switches and return automatically to neutral position
|
||||
if (Train->ggDoorRightOffButton.SubModel)
|
||||
Train->ggDoorRightOffButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_dooropenall(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
auto const remoteopencontrol{Train->mvOccupied->Doors.open_control == control_t::driver || Train->mvOccupied->Doors.open_control == control_t::mixed};
|
||||
|
||||
if (false == remoteopencontrol)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->ggDoorAllOnButton.SubModel == nullptr)
|
||||
{
|
||||
// TODO: expand definition of cab controls so we can know if the control is present without testing for presence of 3d switch
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
WriteLog("Open All Doors switch is missing, or wasn't defined");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
|
||||
Train->mvOccupied->OperateDoors(side::right, true);
|
||||
Train->mvOccupied->OperateDoors(side::left, true);
|
||||
// visual feedback
|
||||
Train->ggDoorAllOnButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggDoorAllOnButton.UpdateValue(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_doorcloseall(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
auto const remoteclosecontrol{Train->mvOccupied->Doors.close_control == control_t::driver || Train->mvOccupied->Doors.close_control == control_t::mixed};
|
||||
|
||||
if (false == remoteclosecontrol)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->ggDoorAllOffButton.SubModel == nullptr)
|
||||
{
|
||||
// TODO: expand definition of cab controls so we can know if the control is present without testing for presence of 3d switch
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
WriteLog("Close All Doors switch is missing, or wasn't defined");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
|
||||
if (Train->mvOccupied->Doors.has_autowarning)
|
||||
{
|
||||
Train->mvOccupied->signal_departure(true);
|
||||
}
|
||||
if (Train->ggDoorAllOffButton.type() != TGaugeType::push_delayed)
|
||||
{
|
||||
// delays the action until the button is released
|
||||
Train->mvOccupied->OperateDoors(side::right, false);
|
||||
Train->mvOccupied->OperateDoors(side::left, false);
|
||||
}
|
||||
// visual feedback
|
||||
Train->ggDoorLeftButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
Train->ggDoorRightButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
if (Train->ggDoorAllOffButton.SubModel)
|
||||
Train->ggDoorAllOffButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
if (Train->mvOccupied->Doors.has_autowarning)
|
||||
{
|
||||
Train->mvOccupied->signal_departure(false);
|
||||
}
|
||||
if (Train->ggDoorAllOffButton.type() == TGaugeType::push_delayed)
|
||||
{
|
||||
// now we can actually close the door
|
||||
Train->mvOccupied->OperateDoors(side::right, false);
|
||||
Train->mvOccupied->OperateDoors(side::left, false);
|
||||
}
|
||||
// visual feedback
|
||||
if (Train->ggDoorAllOffButton.SubModel)
|
||||
Train->ggDoorAllOffButton.UpdateValue(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_doorsteptoggle(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
// TODO: move logic/visualization code to the gauge, on_command() should return hint whether it should invoke a reaction
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// effect
|
||||
if (false == Train->ggDoorStepButton.is_delayed())
|
||||
{
|
||||
Train->mvOccupied->PermitDoorStep(false == Train->mvOccupied->Doors.step_enabled);
|
||||
}
|
||||
// visual feedback
|
||||
auto const isactive{(Train->ggDoorStepButton.is_push() // always press push button
|
||||
|| Train->mvOccupied->Doors.step_enabled)}; // for toggle buttons indicate item state
|
||||
Train->ggDoorStepButton.UpdateValue(isactive ? 1 : 0);
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// effect
|
||||
if (Train->ggDoorStepButton.is_delayed())
|
||||
{
|
||||
Train->mvOccupied->PermitDoorStep(false == Train->mvOccupied->Doors.step_enabled);
|
||||
}
|
||||
// visual feedback
|
||||
if (Train->ggDoorStepButton.is_push())
|
||||
{
|
||||
Train->ggDoorStepButton.UpdateValue(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_doormodetoggle(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
Train->mvOccupied->ChangeDoorControlMode(false == Train->mvOccupied->Doors.remote_only);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_mirrorstoggle(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action != GLFW_PRESS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// only reacting to press, so the sound can loop uninterrupted
|
||||
if (false == Train->mvOccupied->MirrorForbidden)
|
||||
{
|
||||
// turn on
|
||||
Train->mvOccupied->MirrorForbidden = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// turn off
|
||||
Train->mvOccupied->MirrorForbidden = false;
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_nearestcarcouplingincrease(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (true == Command.freefly && Command.action == GLFW_PRESS)
|
||||
{
|
||||
// tryb freefly, press only
|
||||
auto coupler{-1};
|
||||
auto *vehicle{Train->DynamicObject->ABuScanNearestObject(Command.location, Train->DynamicObject->GetTrack(), 1, 1500, coupler)};
|
||||
if (vehicle == nullptr)
|
||||
vehicle = Train->DynamicObject->ABuScanNearestObject(Command.location, Train->DynamicObject->GetTrack(), -1, 1500, coupler);
|
||||
|
||||
if (coupler != -1 && vehicle != nullptr)
|
||||
{
|
||||
|
||||
vehicle->couple(coupler);
|
||||
}
|
||||
if (Train->DynamicObject->Mechanik)
|
||||
{
|
||||
// aktualizacja flag kierunku w składzie
|
||||
Train->DynamicObject->Mechanik->CheckVehicles(Connect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_nearestcarcouplingdisconnect(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (true == Command.freefly && Command.action == GLFW_PRESS)
|
||||
{
|
||||
// tryb freefly, press only
|
||||
auto coupler{-1};
|
||||
auto *vehicle{Train->DynamicObject->ABuScanNearestObject(Command.location, Train->DynamicObject->GetTrack(), 1, 1500, coupler)};
|
||||
if (vehicle == nullptr)
|
||||
vehicle = Train->DynamicObject->ABuScanNearestObject(Command.location, Train->DynamicObject->GetTrack(), -1, 1500, coupler);
|
||||
|
||||
if (coupler != -1 && vehicle != nullptr)
|
||||
{
|
||||
|
||||
vehicle->uncouple(coupler);
|
||||
}
|
||||
if (Train->DynamicObject->Mechanik)
|
||||
{
|
||||
// aktualizacja flag kierunku w składzie
|
||||
Train->DynamicObject->Mechanik->CheckVehicles(Disconnect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_nearestcarcoupleradapterattach(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (true == Command.freefly && Command.action == GLFW_PRESS)
|
||||
{
|
||||
// tryb freefly, press only
|
||||
auto *vehicle{std::get<TDynamicObject *>(simulation::Region->find_vehicle(Command.location, 50, false, true))};
|
||||
if (vehicle == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto const coupler =
|
||||
glm::length2(glm::vec3{vehicle->CouplerPosition(end::front)} - Command.location) < glm::length2(glm::vec3{vehicle->CouplerPosition(end::rear)} - Command.location) ? end::front : end::rear;
|
||||
|
||||
vehicle->attach_coupler_adapter(coupler);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_nearestcarcoupleradapterremove(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (true == Command.freefly && Command.action == GLFW_PRESS)
|
||||
{
|
||||
// tryb freefly, press only
|
||||
auto *vehicle{std::get<TDynamicObject *>(simulation::Region->find_vehicle(Command.location, 50, false, true))};
|
||||
if (vehicle == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto const coupler =
|
||||
glm::length2(glm::vec3{vehicle->CouplerPosition(end::front)} - Command.location) < glm::length2(glm::vec3{vehicle->CouplerPosition(end::rear)} - Command.location) ? end::front : end::rear;
|
||||
|
||||
vehicle->remove_coupler_adapter(coupler);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_occupiedcarcouplingdisconnect(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
// if( false == Train->m_controlmapper.contains( "couplingdisconnect_sw:" ) ) { return; }
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// visual feedback
|
||||
Train->m_couplingdisconnect = true;
|
||||
|
||||
if (Train->iCabn == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->DynamicObject)
|
||||
{
|
||||
Train->DynamicObject->uncouple(Train->cab_to_end());
|
||||
if (Train->DynamicObject->Mechanik)
|
||||
{
|
||||
// aktualizacja flag kierunku w składzie
|
||||
Train->DynamicObject->Mechanik->CheckVehicles(Disconnect);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// visual feedback
|
||||
Train->m_couplingdisconnect = false;
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_occupiedcarcouplingdisconnectback(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
// if( false == Train->m_controlmapper.contains( "couplingdisconnect_sw:" ) ) { return; }
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// visual feedback
|
||||
Train->m_couplingdisconnectback = true;
|
||||
|
||||
if (Train->iCabn == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->DynamicObject)
|
||||
{
|
||||
Train->DynamicObject->uncouple(1 - Train->cab_to_end());
|
||||
if (Train->DynamicObject->Mechanik)
|
||||
{
|
||||
// aktualizacja flag kierunku w składzie
|
||||
Train->DynamicObject->Mechanik->CheckVehicles(Disconnect);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// visual feedback
|
||||
Train->m_couplingdisconnectback = false;
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_departureannounce(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Train->ggDepartureSignalButton.SubModel == nullptr)
|
||||
{
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
WriteLog("Departure Signal button is missing, or wasn't defined");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// only reacting to press, so the sound can loop uninterrupted
|
||||
if (false == Train->mvOccupied->DepartureSignal)
|
||||
{
|
||||
// turn on
|
||||
Train->mvOccupied->signal_departure(true);
|
||||
// visual feedback
|
||||
Train->ggDepartureSignalButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// turn off
|
||||
Train->mvOccupied->signal_departure(false);
|
||||
// visual feedback
|
||||
Train->ggDepartureSignalButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user