18
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-11-15 15:14:09 +01:00
Files
maszyna/tests/unit/test_lights_programmer.cpp
jerrrrycho 19b500f9be fix(lights): darken the coupled end with the light programmer from either cab (eu07/maszyna#395)
SetLights() gives RaLightsSet() the lights for the vehicle's end towards
the head of the consist and the end towards its tail, whichever way the
occupied cab faces. The coupling that switches an end off was looked up
at the opposite end whenever the cab faced the tail of the consist
(e.g. 6Dg driven from its second cab position), so the free end went
dark and the end with the train was lit.

The per-vehicle choice moves to lights_programmer::vehicle_lights() in
vehicle/lightsprogrammer.h, which checks the coupling at the same end
it lights, with unit tests for both cabs, both orientations and the
train at either end. Driving from a cab facing the head of the consist
gives the same lights as before. No data change needed.
2026-11-07 17:58:20 +01:00

94 lines
3.9 KiB
C++

#include "stdafx.h"
#include "doctest.h"
#include "vehicle/lightsprogrammer.h"
// the lights the light preset selector (programmer) of the occupied cab gives the vehicles of the consist,
// TDynamicObject::SetLights(): the cab's front lights at the end the cab faces, its back lights at the other
// end, and no lights at an end with another vehicle coupled
namespace {
int const pc1{light::headlight_left | light::headlight_upper | light::headlight_right};
int const tailmarkers{light::redmarker_left | light::redmarker_right};
std::array<int, 2> const cablights{pc1, tailmarkers}; // Lights[end::front], Lights[end::rear]
// the lights at the vehicle's own end, placed the way TDynamicObject::RaLightsSet() places them
int lights_at(lights_programmer::consist_lights const &Lights, int const Direction, end const Side) {
auto const headend{Direction > 0 ? end::front : end::rear};
return Side == headend ? Lights.head : Lights.rear;
}
struct setup {
int cab; // CabOccupied of the vehicle with the programmer
int direction; // its iDirection
std::array<bool, 2> coupled; // vehicle coupled at its end::front / end::rear
};
lights_programmer::consist_lights lights_for(setup const &Setup) {
// TDynamicObject::SetLights(): the cab faces the head of the consist when CabOccupied * DirectionGet() >= 0
auto const cabfacinghead{Setup.cab * (Setup.direction > 0 ? 1 : -1) >= 0};
return lights_programmer::vehicle_lights(cablights, cabfacinghead, Setup.direction, Setup.coupled);
}
} // namespace
TEST_CASE("lights programmer: a lone vehicle gets the cab's front lights ahead of the cab and its back lights behind it") {
for (auto const direction : {0, 1}) {
CAPTURE(direction);
// cab 1 faces end::front
auto const fromcab1{lights_for({1, direction, {false, false}})};
CHECK(lights_at(fromcab1, direction, end::front) == pc1);
CHECK(lights_at(fromcab1, direction, end::rear) == tailmarkers);
// cab -1 faces end::rear
auto const fromcab2{lights_for({-1, direction, {false, false}})};
CHECK(lights_at(fromcab2, direction, end::rear) == pc1);
CHECK(lights_at(fromcab2, direction, end::front) == tailmarkers);
}
}
TEST_CASE("lights programmer: the end with the train coupled goes dark, not the other one (eu07/maszyna#395)") {
// a locomotive driven from either cab, with the train coupled at either end, either way round in the consist.
// the end with the train goes dark, the free end shows the lights meant for it
for (auto const direction : {0, 1}) {
for (auto const cab : {1, -1}) {
for (auto const trainend : {end::front, end::rear}) {
CAPTURE(direction);
CAPTURE(cab);
CAPTURE(trainend);
std::array<bool, 2> coupled{false, false};
coupled[trainend] = true;
auto const freeend{trainend == end::front ? end::rear : end::front};
auto const cabfront{cab > 0 ? end::front : end::rear};
auto const lights{lights_for({cab, direction, coupled})};
CHECK(lights_at(lights, direction, trainend) == 0);
CHECK(lights_at(lights, direction, freeend) == (freeend == cabfront ? pc1 : tailmarkers));
}
}
}
}
TEST_CASE("lights programmer: 6Dg driven backwards from its second cab position pulls the train with its head lights lit (eu07/maszyna#395)") {
// the reported case: the train coupled behind the driver (end::front, which cab -1 has at its back), the
// locomotive running towards end::rear, the train in tow. the head lights stay lit, the end with the train goes dark;
// before the fix the couplings were looked up at the swapped ends and it was the other way round
auto const lights{lights_for({-1, 1, {true, false}})};
CHECK(lights_at(lights, 1, end::rear) == pc1);
CHECK(lights_at(lights, 1, end::front) == 0);
}
TEST_CASE("lights programmer: a vehicle coupled at both ends stays dark") {
for (auto const direction : {0, 1}) {
for (auto const cab : {1, -1}) {
CAPTURE(direction);
CAPTURE(cab);
auto const lights{lights_for({cab, direction, {true, true}})};
CHECK(lights.head == 0);
CHECK(lights.rear == 0);
}
}
}