diff --git a/server/test/zone.cpp b/server/test/zone.cpp index ae0070a2..d275430c 100644 --- a/server/test/zone.cpp +++ b/server/test/zone.cpp @@ -115,3 +115,202 @@ TEST_CASE("Zone: Assign/remove train to/from muted and no smoke zone", "[zone]") REQUIRE(blockWeak.expired()); REQUIRE(zoneWeak.expired()); } + +TEST_CASE("Zone: Assign/remove events", "[zone]") +{ + size_t trainZoneAssignedEventCount = 0; + size_t trainZoneEnteringEventCount = 0; + size_t trainZoneEnteredEventCount = 0; + size_t trainZoneLeavingEventCount = 0; + size_t trainZoneLeftEventCount = 0; + size_t trainZoneRemovedEventCount = 0; + size_t zoneTrainAssignedEventCount = 0; + size_t zoneTrainEnteringEventCount = 0; + size_t zoneTrainEnteredEventCount = 0; + size_t zoneTrainLeavingEventCount = 0; + size_t zoneTrainLeftEventCount = 0; + size_t zoneTrainRemovedEventCount = 0; + + auto world = World::create(); + std::weak_ptr worldWeak = world; + REQUIRE_FALSE(worldWeak.expired()); + + REQUIRE(world->railVehicles->length == 0); + std::weak_ptr locomotiveWeak = world->railVehicles->create(Locomotive::classId); + REQUIRE_FALSE(locomotiveWeak.expired()); + REQUIRE(world->railVehicles->length == 1); + + REQUIRE(world->trains->length == 0); + std::weak_ptr trainWeak = world->trains->create(); + REQUIRE_FALSE(trainWeak.expired()); + REQUIRE(world->trains->length == 1); + REQUIRE(trainWeak.lock()->vehicles->length == 0); + trainWeak.lock()->vehicles->add(locomotiveWeak.lock()); + REQUIRE(trainWeak.lock()->vehicles->length == 1); + + REQUIRE(world->boards->length == 0); + std::weak_ptr boardWeak = world->boards->create(); + REQUIRE_FALSE(boardWeak.expired()); + REQUIRE(world->boards->length == 1); + + REQUIRE(boardWeak.lock()->addTile(0, 0, TileRotate::Deg90, BlockRailTile::classId, false)); + std::weak_ptr blockWeak = std::dynamic_pointer_cast(boardWeak.lock()->getTile({0, 0})); + REQUIRE_FALSE(blockWeak.expired()); + + std::weak_ptr zoneWeak = world->zones->create(); + REQUIRE_FALSE(zoneWeak.expired()); + REQUIRE(zoneWeak.lock()->blocks->length == 0); + zoneWeak.lock()->blocks->add(blockWeak.lock()); + REQUIRE(zoneWeak.lock()->blocks->length == 1); + REQUIRE(zoneWeak.lock()->trains.size() == 0); + + // Setup events: + trainWeak.lock()->onZoneAssigned.connect( + [&](const std::shared_ptr& train, const std::shared_ptr& zone) + { + trainZoneAssignedEventCount++; + REQUIRE(train == trainWeak.lock()); + REQUIRE(zone == zoneWeak.lock()); + }); + trainWeak.lock()->onZoneEntering.connect( + [&](const std::shared_ptr& train, const std::shared_ptr& zone) + { + trainZoneEnteringEventCount++; + REQUIRE(train == trainWeak.lock()); + REQUIRE(zone == zoneWeak.lock()); + }); + trainWeak.lock()->onZoneEntered.connect( + [&](const std::shared_ptr& train, const std::shared_ptr& zone) + { + trainZoneEnteredEventCount++; + REQUIRE(train == trainWeak.lock()); + REQUIRE(zone == zoneWeak.lock()); + }); + trainWeak.lock()->onZoneLeaving.connect( + [&](const std::shared_ptr& train, const std::shared_ptr& zone) + { + trainZoneLeavingEventCount++; + REQUIRE(train == trainWeak.lock()); + REQUIRE(zone == zoneWeak.lock()); + }); + trainWeak.lock()->onZoneLeft.connect( + [&](const std::shared_ptr& train, const std::shared_ptr& zone) + { + trainZoneLeftEventCount++; + REQUIRE(train == trainWeak.lock()); + REQUIRE(zone == zoneWeak.lock()); + }); + trainWeak.lock()->onZoneRemoved.connect( + [&](const std::shared_ptr& train, const std::shared_ptr& zone) + { + trainZoneRemovedEventCount++; + REQUIRE(train == trainWeak.lock()); + REQUIRE(zone == zoneWeak.lock()); + }); + zoneWeak.lock()->onTrainAssigned.connect( + [&](const std::shared_ptr& train, const std::shared_ptr& zone) + { + zoneTrainAssignedEventCount++; + REQUIRE(train == trainWeak.lock()); + REQUIRE(zone == zoneWeak.lock()); + }); + zoneWeak.lock()->onTrainEntering.connect( + [&](const std::shared_ptr& train, const std::shared_ptr& zone) + { + zoneTrainEnteringEventCount++; + REQUIRE(train == trainWeak.lock()); + REQUIRE(zone == zoneWeak.lock()); + }); + zoneWeak.lock()->onTrainEntered.connect( + [&](const std::shared_ptr& train, const std::shared_ptr& zone) + { + zoneTrainEnteredEventCount++; + REQUIRE(train == trainWeak.lock()); + REQUIRE(zone == zoneWeak.lock()); + }); + zoneWeak.lock()->onTrainLeaving.connect( + [&](const std::shared_ptr& train, const std::shared_ptr& zone) + { + zoneTrainLeavingEventCount++; + REQUIRE(train == trainWeak.lock()); + REQUIRE(zone == zoneWeak.lock()); + }); + zoneWeak.lock()->onTrainLeft.connect( + [&](const std::shared_ptr& train, const std::shared_ptr& zone) + { + zoneTrainLeftEventCount++; + REQUIRE(train == trainWeak.lock()); + REQUIRE(zone == zoneWeak.lock()); + }); + zoneWeak.lock()->onTrainRemoved.connect( + [&](const std::shared_ptr& train, const std::shared_ptr& zone) + { + zoneTrainRemovedEventCount++; + REQUIRE(train == trainWeak.lock()); + REQUIRE(zone == zoneWeak.lock()); + }); + + REQUIRE(trainZoneAssignedEventCount == 0); + REQUIRE(trainZoneEnteringEventCount == 0); + REQUIRE(trainZoneEnteredEventCount == 0); + REQUIRE(trainZoneLeavingEventCount == 0); + REQUIRE(trainZoneLeftEventCount == 0); + REQUIRE(trainZoneRemovedEventCount == 0); + REQUIRE(zoneTrainAssignedEventCount == 0); + REQUIRE(zoneTrainEnteringEventCount == 0); + REQUIRE(zoneTrainEnteredEventCount == 0); + REQUIRE(zoneTrainLeavingEventCount == 0); + REQUIRE(zoneTrainLeftEventCount == 0); + REQUIRE(zoneTrainRemovedEventCount == 0); + + blockWeak.lock()->assignTrain(trainWeak.lock()); + + REQUIRE(trainZoneAssignedEventCount == 1); + REQUIRE(trainZoneEnteringEventCount == 0); + REQUIRE(trainZoneEnteredEventCount == 0); + REQUIRE(trainZoneLeavingEventCount == 0); + REQUIRE(trainZoneLeftEventCount == 0); + REQUIRE(trainZoneRemovedEventCount == 0); + REQUIRE(zoneTrainAssignedEventCount == 1); + REQUIRE(zoneTrainEnteringEventCount == 0); + REQUIRE(zoneTrainEnteredEventCount == 0); + REQUIRE(zoneTrainLeavingEventCount == 0); + REQUIRE(zoneTrainLeftEventCount == 0); + REQUIRE(zoneTrainRemovedEventCount == 0); + + blockWeak.lock()->removeTrain(trainWeak.lock()); + + REQUIRE(trainZoneAssignedEventCount == 1); + REQUIRE(trainZoneEnteringEventCount == 0); + REQUIRE(trainZoneEnteredEventCount == 0); + REQUIRE(trainZoneLeavingEventCount == 0); + REQUIRE(trainZoneLeftEventCount == 0); + REQUIRE(trainZoneRemovedEventCount == 1); + REQUIRE(zoneTrainAssignedEventCount == 1); + REQUIRE(zoneTrainEnteringEventCount == 0); + REQUIRE(zoneTrainEnteredEventCount == 0); + REQUIRE(zoneTrainLeavingEventCount == 0); + REQUIRE(zoneTrainLeftEventCount == 0); + REQUIRE(zoneTrainRemovedEventCount == 1); + + world.reset(); + + REQUIRE(worldWeak.expired()); + REQUIRE(locomotiveWeak.expired()); + REQUIRE(trainWeak.expired()); + REQUIRE(boardWeak.expired()); + REQUIRE(blockWeak.expired()); + REQUIRE(zoneWeak.expired()); + REQUIRE(trainZoneAssignedEventCount == 1); + REQUIRE(trainZoneEnteringEventCount == 0); + REQUIRE(trainZoneEnteredEventCount == 0); + REQUIRE(trainZoneLeavingEventCount == 0); + REQUIRE(trainZoneLeftEventCount == 0); + REQUIRE(trainZoneRemovedEventCount == 1); + REQUIRE(zoneTrainAssignedEventCount == 1); + REQUIRE(zoneTrainEnteringEventCount == 0); + REQUIRE(zoneTrainEnteredEventCount == 0); + REQUIRE(zoneTrainLeavingEventCount == 0); + REQUIRE(zoneTrainLeftEventCount == 0); + REQUIRE(zoneTrainRemovedEventCount == 1); +}