[traintastic] fixed restart crash (out of memory)

Dieser Commit ist enthalten in:
Reinder Feenstra 2026-01-17 22:09:47 +01:00
Ursprung fd012470bc
Commit 2c9fb1bac3
33 geänderte Dateien mit 344 neuen und 85 gelöschten Zeilen

Datei anzeigen

@ -1,9 +1,8 @@
/**
* server/src/board/map/blockpath.cpp
* This file is part of Traintastic,
* see <https://github.com/traintastic/traintastic>.
*
* This file is part of the traintastic source code.
*
* Copyright (C) 2023-2024 Reinder Feenstra
* Copyright (C) 2023-2026 Reinder Feenstra
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -324,7 +323,7 @@ BlockPath::BlockPath(BlockRailTile& block, BlockSide side)
: m_fromBlock{block}
, m_fromSide{side}
, m_toSide{static_cast<BlockSide>(-1)}
, m_delayReleaseTimer{EventLoop::ioContext}
, m_delayReleaseTimer{EventLoop::ioContext()}
, m_isReserved(false)
, m_delayedReleaseScheduled(false)
{
@ -345,7 +344,7 @@ BlockPath::BlockPath(const BlockPath &other)
, m_signals(other.m_signals)
, m_nxButtonFrom(other.m_nxButtonFrom)
, m_nxButtonTo(other.m_nxButtonTo)
, m_delayReleaseTimer{EventLoop::ioContext}
, m_delayReleaseTimer{EventLoop::ioContext()}
, m_isReserved(false)
, m_delayedReleaseScheduled(false)
{

Datei anzeigen

@ -1,9 +1,8 @@
/**
* server/src/clock/clock.cpp
* This file is part of Traintastic,
* see <https://github.com/traintastic/traintastic>.
*
* This file is part of the traintastic source code.
*
* Copyright (C) 2019-2020,2022 Reinder Feenstra
* Copyright (C) 2019-2026 Reinder Feenstra
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -28,7 +27,7 @@
Clock::Clock(Object& _parent, std::string_view parentPropertyName)
: SubObject(_parent, parentPropertyName)
, m_timer{EventLoop::ioContext}
, m_timer{EventLoop::ioContext()}
, time{this, "time", 0, PropertyFlags::ReadOnly | PropertyFlags::NoStore | PropertyFlags::ScriptReadOnly}
, hour{this, "hour", 0, PropertyFlags::ReadWrite | PropertyFlags::StoreState | PropertyFlags::ScriptReadOnly}
, minute{this, "minute", 0, PropertyFlags::ReadWrite | PropertyFlags::StoreState | PropertyFlags::ScriptReadOnly}

Datei anzeigen

@ -1,9 +1,8 @@
/**
* server/src/core/eventloop.hpp
* This file is part of Traintastic,
* see <https://github.com/traintastic/traintastic>.
*
* This file is part of the traintastic source code.
*
* Copyright (C) 2019-2020,2022-2024 Reinder Feenstra
* Copyright (C) 2019-2026 Reinder Feenstra
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -35,42 +34,52 @@ class EventLoop
EventLoop(const EventLoop&) = delete;
EventLoop& operator =(const EventLoop&) = delete;
inline static std::unique_ptr<boost::asio::io_context> s_ioContext;
inline static std::shared_ptr<boost::asio::io_context::work> s_keepAlive;
public:
inline static boost::asio::io_context ioContext;
#ifdef TRAINTASTIC_TEST
inline static std::thread::id threadId;
#else
inline static const std::thread::id threadId = std::this_thread::get_id();
#endif
static boost::asio::io_context& ioContext()
{
assert(s_ioContext);
return *s_ioContext;
}
static void reset()
{
s_ioContext = std::make_unique<boost::asio::io_context>();
}
static void exec()
{
#ifdef TRAINTASTIC_TEST
threadId = std::this_thread::get_id();
#endif
if(ioContext.stopped())
{
ioContext.restart();
}
auto work = std::make_shared<boost::asio::io_context::work>(ioContext);
ioContext.run();
s_keepAlive = std::make_shared<boost::asio::io_context::work>(ioContext());
ioContext().run();
s_keepAlive.reset();
}
static void stop()
{
ioContext.stop();
s_keepAlive.reset();
}
template<typename _Callable, typename... _Args>
inline static void call(_Callable&& __f, _Args&&... __args)
{
ioContext.post(std::bind(__f, __args...));
ioContext().post(std::bind(__f, __args...));
}
template<typename T>
inline static void deleteLater(T* object)
{
ioContext.post(
ioContext().post(
[object]()
{
delete object;

Datei anzeigen

@ -42,7 +42,7 @@ LocoNetLNCVBoosterDriver::LocoNetLNCVBoosterDriver(Booster& booster, uint16_t mo
, address{this, "address", addressDefault, PropertyFlags::ReadWrite | PropertyFlags::Store | PropertyFlags::NoScript}
, pollInterval{this, "poll_interval", pollIntervalDefault, PropertyFlags::ReadWrite | PropertyFlags::Store | PropertyFlags::NoScript}
, m_moduleId{moduleId}
, m_pollTimer{EventLoop::ioContext}
, m_pollTimer{EventLoop::ioContext()}
{
Attributes::addDisplayName(address, DisplayName::Hardware::address);
Attributes::addEnabled(address, false);

Datei anzeigen

@ -2,7 +2,7 @@
* This file is part of Traintastic,
* see <https://github.com/traintastic/traintastic>.
*
* Copyright (C) 2025 Reinder Feenstra
* Copyright (C) 2025-2026 Reinder Feenstra
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -44,7 +44,7 @@ bool roundToDelayStep(uint16_t& value)
InputConsumer::InputConsumer(Object& object, const World& world)
: m_object{object}
, m_inputFilterTimer{EventLoop::ioContext}
, m_inputFilterTimer{EventLoop::ioContext()}
, interface{&object, "interface", nullptr, PropertyFlags::ReadWrite | PropertyFlags::Store | PropertyFlags::NoScript,
[this](const std::shared_ptr<InputController>& /*newValue*/)
{

Datei anzeigen

@ -1,9 +1,8 @@
/**
* server/src/main.cpp
* This file is part of Traintastic,
* see <https://github.com/traintastic/traintastic>.
*
* This file is part of the traintastic source code.
*
* Copyright (C) 2019-2025 Reinder Feenstra
* Copyright (C) 2019-2026 Reinder Feenstra
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -23,6 +22,7 @@
#include <iostream>
#include <functional>
#include "options.hpp"
#include "core/eventloop.hpp"
#include "traintastic/traintastic.hpp"
#include "log/log.hpp"
#include <traintastic/locale/locale.hpp>
@ -95,6 +95,8 @@ int main(int argc, char* argv[])
do
{
EventLoop::reset();
{
const auto localePath = getLocalePath();
try

Datei anzeigen

@ -1,9 +1,8 @@
/**
* server/src/network/clientclientconnection.cpp
* This file is part of Traintastic,
* see <https://github.com/traintastic/traintastic>.
*
* This file is part of the traintastic source code.
*
* Copyright (C) 2019-2025 Reinder Feenstra
* Copyright (C) 2019-2026 Reinder Feenstra
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -77,7 +76,7 @@ void ClientConnection::doRead()
{
EventLoop::call(std::bind(&ClientConnection::connectionLost, this));
}
else
else if(ec != boost::asio::error::operation_aborted)
{
Log::log(id, LogMessage::E1007_SOCKET_READ_FAILED_X, ec);
EventLoop::call(std::bind(&ClientConnection::disconnect, this));

Datei anzeigen

@ -1,9 +1,8 @@
/**
* server/src/network/server.cpp
* This file is part of Traintastic,
* see <https://github.com/traintastic/traintastic>.
*
* This file is part of the traintastic source code.
*
* Copyright (C) 2022-2025 Reinder Feenstra
* Copyright (C) 2022-2026 Reinder Feenstra
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -53,7 +52,7 @@
#include <resource/www/css/normalize.css.hpp>
#include <resource/shared/gfx/appicon.ico.hpp>
#define IS_SERVER_THREAD (std::this_thread::get_id() == m_thread.get_id())
#define IS_SERVER_THREAD (std::this_thread::get_id() == m_threadId)
namespace beast = boost::beast;
namespace http = beast::http;
@ -315,14 +314,6 @@ Server::Server(bool localhostOnly, uint16_t port, bool discoverable)
Log::log(id, LogMessage::N1007_LISTENING_AT_X_X, m_acceptor.local_endpoint().address().to_string(), m_acceptor.local_endpoint().port());
m_thread = std::thread(
[this]()
{
setThreadName("server");
auto work = std::make_shared<boost::asio::io_context::work>(m_ioContext);
m_ioContext.run();
});
m_ioContext.post(
[this, discoverable]()
{
@ -331,6 +322,16 @@ Server::Server(bool localhostOnly, uint16_t port, bool discoverable)
doAccept();
});
m_thread = std::thread(
[this]()
{
#ifndef NDEBUG
m_threadId = std::this_thread::get_id();
#endif
setThreadName("server");
m_ioContext.run();
});
}
Server::~Server()
@ -339,6 +340,11 @@ Server::~Server()
if(!m_ioContext.stopped())
{
for(const auto& connection : m_connections)
{
connection->disconnect();
}
m_ioContext.post(
[this]()
{
@ -350,15 +356,10 @@ Server::~Server()
m_socketUDP.close();
});
m_ioContext.stop();
}
if(m_thread.joinable())
m_thread.join();
while(!m_connections.empty())
m_connections.front()->disconnect();
}
void Server::connectionGone(const std::shared_ptr<WebSocketConnection>& connection)
@ -400,8 +401,10 @@ void Server::doReceive()
}
doReceive();
}
else
else if(ec != boost::asio::error::operation_aborted)
{
Log::log(id, LogMessage::E1003_UDP_RECEIVE_ERROR_X, ec.message());
}
});
}
@ -434,7 +437,7 @@ void Server::doAccept()
doAccept();
}
else
else if(ec != boost::asio::error::operation_aborted)
{
Log::log(id, LogMessage::E1004_TCP_ACCEPT_ERROR_X, ec.message());
}
@ -556,7 +559,7 @@ bool Server::acceptWebSocketUpgradeRequest(http::request<http::string_body>&& re
m_connections.push_back(connection);
});
}
else
else if(ec != boost::asio::error::operation_aborted)
{
Log::log(id, LogMessage::E1004_TCP_ACCEPT_ERROR_X, ec.message());
}

Datei anzeigen

@ -1,9 +1,8 @@
/**
* server/src/network/server.hpp
* This file is part of Traintastic,
* see <https://github.com/traintastic/traintastic>.
*
* This file is part of the traintastic source code.
*
* Copyright (C) 2022-2025 Reinder Feenstra
* Copyright (C) 2022-2026 Reinder Feenstra
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -46,6 +45,9 @@ class Server : public std::enable_shared_from_this<Server>
private:
boost::asio::io_context m_ioContext;
std::thread m_thread;
#ifndef NDEBUG
std::thread::id m_threadId;
#endif
boost::asio::ip::tcp::acceptor m_acceptor;
boost::asio::ip::udp::socket m_socketUDP;
std::array<char, 8> m_udpBuffer;

Datei anzeigen

@ -1,9 +1,8 @@
/**
* server/src/network/websocketconnection.cpp
* This file is part of Traintastic,
* see <https://github.com/traintastic/traintastic>.
*
* This file is part of the traintastic source code.
*
* Copyright (C) 2025 Reinder Feenstra
* Copyright (C) 2025-2026 Reinder Feenstra
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -68,7 +67,7 @@ void WebSocketConnection::disconnect()
assert(isEventLoopThread());
m_server.m_ioContext.post(
[this]()
[this, serverWeak=m_server.weak_from_this()]()
{
if(m_ws->is_open())
{
@ -77,9 +76,12 @@ void WebSocketConnection::disconnect()
}
EventLoop::call(
[this]()
[this, serverWeak]()
{
m_server.connectionGone(shared_from_this());
if(auto server = serverWeak.lock()) // server might be gone when this is processed.
{
server->connectionGone(shared_from_this());
}
});
});
}

Datei anzeigen

@ -1,9 +1,8 @@
/**
* server/src/network/webthrottleconnection.cpp
* This file is part of Traintastic,
* see <https://github.com/traintastic/traintastic>.
*
* This file is part of the traintastic source code.
*
* Copyright (C) 2025 Reinder Feenstra
* Copyright (C) 2025-2026 Reinder Feenstra
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -110,7 +109,7 @@ void WebThrottleConnection::doRead()
// Socket read failed (The WebSocket stream was gracefully closed at both endpoints)
EventLoop::call(std::bind(&WebThrottleConnection::connectionLost, this));
}
else
else if(ec != boost::asio::error::operation_aborted)
{
Log::log(id, LogMessage::E1007_SOCKET_READ_FAILED_X, ec);
EventLoop::call(std::bind(&WebThrottleConnection::disconnect, this));

Datei anzeigen

@ -1,9 +1,8 @@
/**
* server/src/train/train.cpp
* This file is part of Traintastic,
* see <https://github.com/traintastic/traintastic>.
*
* This file is part of the traintastic source code.
*
* Copyright (C) 2019-2025 Reinder Feenstra
* Copyright (C) 2019-2026 Reinder Feenstra
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -50,7 +49,7 @@ static inline bool isPowered(const RailVehicle& vehicle)
Train::Train(World& world, std::string_view _id) :
IdObject(world, _id),
m_speedTimer{EventLoop::ioContext},
m_speedTimer{EventLoop::ioContext()},
name{this, "name", id, PropertyFlags::ReadWrite | PropertyFlags::Store | PropertyFlags::ScriptReadOnly},
length{*this, "length", 0, LengthUnit::MilliMeter, PropertyFlags::ReadWrite | PropertyFlags::Store},
overrideLength{this, "override_length", false, PropertyFlags::ReadWrite | PropertyFlags::Store,

Datei anzeigen

@ -1,9 +1,8 @@
/**
* server/src/traintastic/traintastic.cpp
* This file is part of Traintastic,
* see <https://github.com/traintastic/traintastic>.
*
* This file is part of the traintastic source code.
*
* Copyright (C) 2019-2023 Reinder Feenstra
* Copyright (C) 2019-2026 Reinder Feenstra
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -69,7 +68,7 @@ std::shared_ptr<Traintastic> Traintastic::instance;
Traintastic::Traintastic(const std::filesystem::path& dataDir) :
m_restart{false},
m_dataDir{std::filesystem::absolute(dataDir)},
m_signalSet(EventLoop::ioContext),
m_signalSet(EventLoop::ioContext()),
about{this, "about", std::string(versionCopyrightAndLicense), PropertyFlags::ReadOnly},
settings{this, "settings", nullptr, PropertyFlags::ReadWrite/*ReadOnly*/},
version{this, "version", TRAINTASTIC_VERSION_FULL, PropertyFlags::ReadOnly},
@ -260,6 +259,8 @@ Traintastic::RunStatus Traintastic::run(const std::string& worldUUID, bool simul
void Traintastic::exit()
{
m_signalSet.cancel();
if(m_restart)
Log::log(*this, LogMessage::N1003_RESTARTING);
else

Datei anzeigen

@ -21,6 +21,7 @@
*/
#include <catch2/catch_template_test_macros.hpp>
#include "../src/core/eventloop.hpp"
#include "../src/world/world.hpp"
#include "../src/core/method.tpp"
#include "../src/core/objectproperty.tpp"
@ -54,6 +55,8 @@
TEST_CASE("Board: Add non existing tile", "[board][board-add]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
auto board = world->boards->create();
@ -94,6 +97,8 @@ TEMPLATE_TEST_CASE("Board: Add tile", "[board][board-add]"
, TunnelRailTile
)
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
auto board = world->boards->create();

Datei anzeigen

@ -20,6 +20,7 @@
*/
#include <catch2/catch_template_test_macros.hpp>
#include "../src/core/eventloop.hpp"
#include "../src/world/world.hpp"
#include "../src/core/method.tpp"
#include "../src/core/objectproperty.tpp"
@ -32,6 +33,8 @@
TEST_CASE("Board: Crossover create/modify/destroy", "[board]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;

Datei anzeigen

@ -21,6 +21,7 @@
*/
#include <catch2/catch_test_macros.hpp>
#include "../src/core/eventloop.hpp"
#include "../src/world/world.hpp"
#include "../src/core/method.tpp"
#include "../src/core/objectproperty.tpp"
@ -33,6 +34,8 @@
TEST_CASE("Board: Merge tile, brigde 90", "[board][board-merge]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
auto board = world->boards->create();
@ -65,6 +68,8 @@ TEST_CASE("Board: Merge tile, brigde 90", "[board][board-merge]")
TEST_CASE("Board: Merge tile, brigde 45 left", "[board][board-merge]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
auto board = world->boards->create();
@ -97,6 +102,8 @@ TEST_CASE("Board: Merge tile, brigde 45 left", "[board][board-merge]")
TEST_CASE("Board: Merge tile, brigde 45 right", "[board][board-merge]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
auto board = world->boards->create();

Datei anzeigen

@ -21,6 +21,7 @@
*/
#include <catch2/catch_test_macros.hpp>
#include "../src/core/eventloop.hpp"
#include "../src/world/world.hpp"
#include "../src/core/method.tpp"
#include "../src/core/objectproperty.tpp"
@ -31,6 +32,8 @@
TEST_CASE("Board: Move non existing tile", "[board][board-move]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
auto board = world->boards->create();
@ -50,6 +53,8 @@ TEST_CASE("Board: Move non existing tile", "[board][board-move]")
TEST_CASE("Board: Move 1x1 tile to empty location", "[board][board-move]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
auto board = world->boards->create();
@ -83,6 +88,8 @@ TEST_CASE("Board: Move 1x1 tile to empty location", "[board][board-move]")
TEST_CASE("Board: Move 1x1 tile to occupied location", "[board][board-move]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
auto board = world->boards->create();
@ -125,6 +132,8 @@ TEST_CASE("Board: Move 1x1 tile to occupied location", "[board][board-move]")
TEST_CASE("Board: Move 1x1 tile to invalid location", "[board][board-move]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
auto board = world->boards->create();
@ -176,6 +185,8 @@ TEST_CASE("Board: Move 1x1 tile to invalid location", "[board][board-move]")
TEST_CASE("Board: Move 5x1 tile to occupied location", "[board][board-move]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
auto board = world->boards->create();
@ -246,6 +257,8 @@ TEST_CASE("Board: Move 5x1 tile to occupied location", "[board][board-move]")
TEST_CASE("Board: Move 5x1 tile replace itself partly", "[board][board-move]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
auto board = world->boards->create();
@ -285,6 +298,8 @@ TEST_CASE("Board: Move 5x1 tile replace itself partly", "[board][board-move]")
TEST_CASE("Board: Move and rotate 5x1 tile replace itself partly", "[board][board-move]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
auto board = world->boards->create();

Datei anzeigen

@ -21,6 +21,7 @@
*/
#include <catch2/catch_test_macros.hpp>
#include "../../src/core/eventloop.hpp"
#include "../../src/world/world.hpp"
#include "../../src/core/method.tpp"
#include "../../src/core/objectproperty.tpp"
@ -44,6 +45,8 @@
TEST_CASE("Board: Bridge path resevation using NX", "[board][board-path]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
@ -162,6 +165,8 @@ TEST_CASE("Board: Bridge path resevation using NX", "[board][board-path]")
TEST_CASE("Board: Cross path resevation using NX", "[board][board-path]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
@ -279,6 +284,8 @@ TEST_CASE("Board: Cross path resevation using NX", "[board][board-path]")
TEST_CASE("Board: Crossover path resevation using NX", "[board][board-path]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
@ -389,6 +396,8 @@ TEST_CASE("Board: Crossover path resevation using NX", "[board][board-path]")
TEST_CASE("Board: Direction path reservation using NX and change direction state", "[board][board-path]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;

Datei anzeigen

@ -21,6 +21,7 @@
*/
#include <catch2/catch_test_macros.hpp>
#include "../src/core/eventloop.hpp"
#include "../src/world/world.hpp"
#include "../src/core/method.tpp"
#include "../src/core/objectproperty.tpp"
@ -30,6 +31,8 @@
TEST_CASE("Board: Resize non existing tile", "[board][board-resize]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
auto board = world->boards->create();
@ -49,6 +52,8 @@ TEST_CASE("Board: Resize non existing tile", "[board][board-resize]")
TEST_CASE("Board: Resize block rail tile vertical", "[board][board-resize]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
auto board = world->boards->create();
@ -128,6 +133,8 @@ TEST_CASE("Board: Resize block rail tile vertical", "[board][board-resize]")
TEST_CASE("Board: Resize block rail tile horizontal", "[board][board-resize]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
auto board = world->boards->create();

Datei anzeigen

@ -21,6 +21,7 @@
*/
#include <catch2/catch_test_macros.hpp>
#include "../src/core/eventloop.hpp"
#include "../src/world/world.hpp"
#include "../src/world/worldloader.hpp"
#include "../src/world/worldsaver.hpp"
@ -32,6 +33,8 @@
TEST_CASE("Board: Save/Load", "[board][board-saveload]")
{
EventLoop::reset();
std::filesystem::path ctw;
std::string worldUUID;
std::string boardId;

Datei anzeigen

@ -21,6 +21,7 @@
#include <catch2/catch_template_test_macros.hpp>
#include <ranges>
#include "../src/core/eventloop.hpp"
#include "../src/core/method.tpp"
#include "../src/core/objectproperty.tpp"
#include "../src/hardware/booster/drivers/boosterdrivers.hpp"
@ -29,6 +30,8 @@
TEST_CASE("Create world and booster => destroy world", "[object-create-destroy]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -49,6 +52,8 @@ TEST_CASE("Create world and booster => destroy world", "[object-create-destroy]"
TEST_CASE("Create world and booster => destroy booster", "[object-create-destroy]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -71,6 +76,8 @@ TEST_CASE("Create world and booster => destroy booster", "[object-create-destroy
TEST_CASE("Booster change driver", "[object-create-destroy]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());

Datei anzeigen

@ -21,6 +21,7 @@
*/
#include <catch2/catch_template_test_macros.hpp>
#include "../src/core/eventloop.hpp"
#include "../src/world/world.hpp"
#include "../src/core/method.tpp"
#include "../src/core/objectproperty.tpp"
@ -38,6 +39,8 @@
TEMPLATE_TEST_CASE("Assign decoder to another interface", "[interface]", INTERFACES_DECODER)
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -97,6 +100,8 @@ TEMPLATE_TEST_CASE("Assign decoder to another interface", "[interface]", INTERFA
TEMPLATE_TEST_CASE("Assign identification to another interface", "[interface]", INTERFACES_IDENTIFICATION)
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());

Datei anzeigen

@ -21,6 +21,7 @@
*/
#include <catch2/catch_test_macros.hpp>
#include "../../src/core/eventloop.hpp"
#include "../../src/core/method.tpp"
#include "../../src/core/objectproperty.tpp"
#include "../../src/world/world.hpp"
@ -38,6 +39,8 @@
TEST_CASE("OutputMap: Channel: Accessory -> ECoSObject -> Accessory", "[outputmap]")
{
EventLoop::reset();
// Create world:
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
@ -125,6 +128,8 @@ TEST_CASE("OutputMap: Channel: Accessory -> ECoSObject -> Accessory", "[outputma
TEST_CASE("OutputMap: Channel: preserve mapping", "[outputmap]")
{
EventLoop::reset();
// Create world:
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
@ -197,6 +202,8 @@ TEST_CASE("OutputMap: Channel: preserve mapping", "[outputmap]")
TEST_CASE("OutputMap: Change interface, preserve mapping", "[outputmap]")
{
EventLoop::reset();
// Create world:
auto world = World::create();
std::weak_ptr<World> worldWeak = world;

Datei anzeigen

@ -21,6 +21,8 @@
*/
#include <catch2/catch_template_test_macros.hpp>
#include "../../src/core/eventloop.hpp"
#include "../../src/lua/push.hpp"
// Enums:
@ -146,6 +148,8 @@ TEMPLATE_TEST_CASE("Lua::push<>", "[lua][lua-push]", LUA_SETS)
TEMPLATE_TEST_CASE("Lua::push<>", "[lua][lua-push]", World)
{
EventLoop::reset();
lua_State* L = luaL_newstate();
const int top = lua_gettop(L);

Datei anzeigen

@ -21,6 +21,7 @@
*/
#include <catch2/catch_test_macros.hpp>
#include "../../src/core/eventloop.hpp"
#include "../../src/world/world.hpp"
#include "../../src/core/method.tpp"
#include "../../src/core/objectproperty.tpp"
@ -28,6 +29,8 @@
TEST_CASE("Lua script: no code, start/stop, disable", "[lua][lua-script]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);

Datei anzeigen

@ -22,6 +22,7 @@
#include <catch2/catch_template_test_macros.hpp>
#include "../../hardware/interfaces.hpp"
#include "../../../src/core/eventloop.hpp"
#include "../../../src/core/method.tpp"
#include "../../../src/core/objectproperty.tpp"
#include "../../../src/hardware/interface/interfacelist.hpp"
@ -36,6 +37,8 @@
TEST_CASE("Lua script: class.get() - nil", "[lua][lua-script][lua-script-class-get]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -51,6 +54,8 @@ TEST_CASE("Lua script: class.get() - nil", "[lua][lua-script][lua-script-class-g
TEST_CASE("Lua script: class.get() - false", "[lua][lua-script][lua-script-class-get]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -65,6 +70,8 @@ TEST_CASE("Lua script: class.get() - false", "[lua][lua-script][lua-script-class
TEST_CASE("Lua script: class.get() - true", "[lua][lua-script][lua-script-class-get]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -79,6 +86,8 @@ TEST_CASE("Lua script: class.get() - true", "[lua][lua-script][lua-script-class-
TEST_CASE("Lua script: class.get() - integer", "[lua][lua-script][lua-script-class-get]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -93,6 +102,8 @@ TEST_CASE("Lua script: class.get() - integer", "[lua][lua-script][lua-script-cla
TEST_CASE("Lua script: class.get() - number", "[lua][lua-script][lua-script-class-get]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -107,6 +118,8 @@ TEST_CASE("Lua script: class.get() - number", "[lua][lua-script][lua-script-clas
TEST_CASE("Lua script: class.get() - string", "[lua][lua-script][lua-script-class-get]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -121,6 +134,8 @@ TEST_CASE("Lua script: class.get() - string", "[lua][lua-script][lua-script-clas
TEST_CASE("Lua script: class.get() - table", "[lua][lua-script][lua-script-class-get]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -135,6 +150,8 @@ TEST_CASE("Lua script: class.get() - table", "[lua][lua-script][lua-script-class
TEMPLATE_TEST_CASE("Lua script: class.get()", "[lua][lua-script][lua-script-class-get]", LUA_ENUMS)
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -151,6 +168,8 @@ TEMPLATE_TEST_CASE("Lua script: class.get()", "[lua][lua-script][lua-script-clas
TEMPLATE_TEST_CASE("Lua script: class.get()", "[lua][lua-script][lua-script-class-get]", LUA_SETS)
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -167,6 +186,8 @@ TEMPLATE_TEST_CASE("Lua script: class.get()", "[lua][lua-script][lua-script-clas
TEMPLATE_TEST_CASE("Lua script: class.get()", "[lua][lua-script][lua-script-class-get]", INTERFACES)
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto interface = world->interfaces->create(TestType::classId);

Datei anzeigen

@ -38,6 +38,7 @@ using Catch::Matchers::EndsWith;
TEST_CASE("Lua script: dead object", "[lua][lua-script][lua-script-dead-object]")
{
Log::enableMemoryLogger(100);
EventLoop::reset();
EventLoop::threadId = std::this_thread::get_id(); // else MemoryLogger will post it to the event loop
auto world = World::create();

Datei anzeigen

@ -21,6 +21,7 @@
*/
#include <catch2/catch_test_macros.hpp>
#include "../../../src/core/eventloop.hpp"
#include "../../../src/core/method.tpp"
#include "../../../src/core/objectproperty.tpp"
#include "../../../src/lua/scriptlist.hpp"
@ -33,6 +34,8 @@
TEST_CASE("Lua script: pv - save/restore - bool", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -59,6 +62,8 @@ TEST_CASE("Lua script: pv - save/restore - bool", "[lua][lua-script][lua-script-
TEST_CASE("Lua script: pv - save/restore - int", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -85,6 +90,8 @@ TEST_CASE("Lua script: pv - save/restore - int", "[lua][lua-script][lua-script-p
TEST_CASE("Lua script: pv - save/restore - float", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -111,6 +118,8 @@ TEST_CASE("Lua script: pv - save/restore - float", "[lua][lua-script][lua-script
TEST_CASE("Lua script: pv - save/restore - string", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -137,6 +146,8 @@ TEST_CASE("Lua script: pv - save/restore - string", "[lua][lua-script][lua-scrip
TEST_CASE("Lua script: pv - save/restore - enum", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -163,6 +174,8 @@ TEST_CASE("Lua script: pv - save/restore - enum", "[lua][lua-script][lua-script-
TEST_CASE("Lua script: pv - save/restore - set", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -189,6 +202,8 @@ TEST_CASE("Lua script: pv - save/restore - set", "[lua][lua-script][lua-script-p
TEST_CASE("Lua script: pv - save/restore - object", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -215,6 +230,8 @@ TEST_CASE("Lua script: pv - save/restore - object", "[lua][lua-script][lua-scrip
TEST_CASE("Lua script: pv - save/restore - vector property", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -245,6 +262,8 @@ TEST_CASE("Lua script: pv - save/restore - vector property", "[lua][lua-script][
TEST_CASE("Lua script: pv - save/restore - method", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -271,6 +290,8 @@ TEST_CASE("Lua script: pv - save/restore - method", "[lua][lua-script][lua-scrip
TEST_CASE("Lua script: pv - save/restore - event", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -297,6 +318,8 @@ TEST_CASE("Lua script: pv - save/restore - event", "[lua][lua-script][lua-script
TEST_CASE("Lua script: pv - unsupported - function", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -314,6 +337,8 @@ TEST_CASE("Lua script: pv - unsupported - function", "[lua][lua-script][lua-scri
TEST_CASE("Lua script: pv - save/restore - table, empty", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -340,6 +365,8 @@ TEST_CASE("Lua script: pv - save/restore - table, empty", "[lua][lua-script][lua
TEST_CASE("Lua script: pv - save/restore - table, array like", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -366,6 +393,8 @@ TEST_CASE("Lua script: pv - save/restore - table, array like", "[lua][lua-script
TEST_CASE("Lua script: pv - save/restore - table, array length", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -392,6 +421,8 @@ TEST_CASE("Lua script: pv - save/restore - table, array length", "[lua][lua-scri
TEST_CASE("Lua script: pv - save/restore - table, map like", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -418,6 +449,8 @@ TEST_CASE("Lua script: pv - save/restore - table, map like", "[lua][lua-script][
TEST_CASE("Lua script: pv - save/restore - bool as key", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -444,6 +477,8 @@ TEST_CASE("Lua script: pv - save/restore - bool as key", "[lua][lua-script][lua-
TEST_CASE("Lua script: pv - save/restore - float as key", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -470,6 +505,8 @@ TEST_CASE("Lua script: pv - save/restore - float as key", "[lua][lua-script][lua
TEST_CASE("Lua script: pv - save/restore - enum key as key", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -496,6 +533,8 @@ TEST_CASE("Lua script: pv - save/restore - enum key as key", "[lua][lua-script][
TEST_CASE("Lua script: pv - save/restore - set as key", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -522,6 +561,8 @@ TEST_CASE("Lua script: pv - save/restore - set as key", "[lua][lua-script][lua-s
TEST_CASE("Lua script: pv - save/restore - object as key", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -548,6 +589,8 @@ TEST_CASE("Lua script: pv - save/restore - object as key", "[lua][lua-script][lu
TEST_CASE("Lua script: pv - save/restore - vector property as key", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -578,6 +621,8 @@ TEST_CASE("Lua script: pv - save/restore - vector property as key", "[lua][lua-s
TEST_CASE("Lua script: pv - save/restore - method as key", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -604,6 +649,8 @@ TEST_CASE("Lua script: pv - save/restore - method as key", "[lua][lua-script][lu
TEST_CASE("Lua script: pv - save/restore - event as key", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -630,6 +677,8 @@ TEST_CASE("Lua script: pv - save/restore - event as key", "[lua][lua-script][lua
TEST_CASE("Lua script: pv - unsupported - function as key", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -647,6 +696,8 @@ TEST_CASE("Lua script: pv - unsupported - function as key", "[lua][lua-script][l
TEST_CASE("Lua script: pv - unsupported - table as key", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -664,6 +715,8 @@ TEST_CASE("Lua script: pv - unsupported - table as key", "[lua][lua-script][lua-
TEST_CASE("Lua script: pv - unsupported - table recursion", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -684,6 +737,8 @@ TEST_CASE("Lua script: pv - unsupported - table recursion", "[lua][lua-script][l
TEST_CASE("Lua script: pv - unsupported - table recursion 2", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -709,6 +764,8 @@ TEST_CASE("Lua script: pv - unsupported - table recursion 2", "[lua][lua-script]
TEST_CASE("Lua script: pv - pairs()", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -742,6 +799,8 @@ TEST_CASE("Lua script: pv - pairs()", "[lua][lua-script][lua-script-pv]")
TEST_CASE("Lua script: pv - ipairs()", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -783,6 +842,8 @@ TEST_CASE("Lua script: pv - ipairs()", "[lua][lua-script][lua-script-pv]")
TEST_CASE("Lua script: pv - clear", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
auto world = World::create();
REQUIRE(world);
auto script = world->luaScripts->create();
@ -817,6 +878,8 @@ TEST_CASE("Lua script: pv - clear", "[lua][lua-script][lua-script-pv]")
TEST_CASE("Lua script: pv - save/load", "[lua][lua-script][lua-script-pv]")
{
EventLoop::reset();
static const std::string code =
"pv.bool = true\n"
"pv.int = 42\n"

Datei anzeigen

@ -21,6 +21,7 @@
*/
#include <catch2/catch_template_test_macros.hpp>
#include "../src/core/eventloop.hpp"
#include "../src/world/world.hpp"
#include "../src/core/method.tpp"
#include "../src/core/objectproperty.tpp"
@ -44,6 +45,8 @@
TEST_CASE("Create world => destroy world", "[object-create-destroy]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -54,6 +57,8 @@ TEST_CASE("Create world => destroy world", "[object-create-destroy]")
TEST_CASE("Create world and board => destroy world", "[object-create-destroy]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -71,6 +76,8 @@ TEST_CASE("Create world and board => destroy world", "[object-create-destroy]")
TEST_CASE("Create world and board => destroy board", "[object-create-destroy]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -90,6 +97,8 @@ TEST_CASE("Create world and board => destroy board", "[object-create-destroy]")
TEMPLATE_TEST_CASE("Create world and interface => destroy world", "[object-create-destroy]", INTERFACES)
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -105,6 +114,8 @@ TEMPLATE_TEST_CASE("Create world and interface => destroy world", "[object-creat
TEMPLATE_TEST_CASE("Create world and interface => destroy interface", "[object-create-destroy]", INTERFACES)
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -124,6 +135,8 @@ TEMPLATE_TEST_CASE("Create world and interface => destroy interface", "[object-c
TEST_CASE("Create world, locomotive, decoder and function => destroy world", "[object-create-destroy]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -153,6 +166,8 @@ TEST_CASE("Create world, locomotive, decoder and function => destroy world", "[o
TEST_CASE("Create world, locomotive, decoder and function => destroy locomotive", "[object-create-destroy]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -187,6 +202,8 @@ TEST_CASE("Create world, locomotive, decoder and function => destroy locomotive"
TEST_CASE("Create world, locomotive, decoder and function => delete decoder", "[object-create-destroy]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -223,6 +240,8 @@ TEST_CASE("Create world, locomotive, decoder and function => delete decoder", "[
TEST_CASE("Create world, locomotive, decoder and function => destroy function", "[object-create-destroy]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -256,6 +275,8 @@ TEST_CASE("Create world, locomotive, decoder and function => destroy function",
TEMPLATE_TEST_CASE("Create world, interface, locomotive and decoder => destroy interface", "[object-create-destroy]", INTERFACES_DECODER)
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -294,6 +315,8 @@ TEMPLATE_TEST_CASE("Create world, interface, locomotive and decoder => destroy i
TEMPLATE_TEST_CASE("Create world, interface, locomotive and decoder => destroy locomotive", "[object-create-destroy]", INTERFACES_DECODER)
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -333,6 +356,8 @@ TEMPLATE_TEST_CASE("Create world, interface, locomotive and decoder => destroy l
TEMPLATE_TEST_CASE("Create world, interface, locomotive and decoder => delete decoder", "[object-create-destroy]", INTERFACES_DECODER)
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -372,6 +397,8 @@ TEMPLATE_TEST_CASE("Create world, interface, locomotive and decoder => delete de
TEMPLATE_TEST_CASE("Create world and rail vehicle => destroy world", "[object-create-destroy]", RAIL_VEHICLES)
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -387,6 +414,8 @@ TEMPLATE_TEST_CASE("Create world and rail vehicle => destroy world", "[object-cr
TEMPLATE_TEST_CASE("Create world and rail vehicle => destroy rail vehicle", "[object-create-destroy]", RAIL_VEHICLES)
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -406,6 +435,8 @@ TEMPLATE_TEST_CASE("Create world and rail vehicle => destroy rail vehicle", "[ob
TEST_CASE("Create world and train => destroy world", "[object-create-destroy]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -423,6 +454,8 @@ TEST_CASE("Create world and train => destroy world", "[object-create-destroy]")
TEST_CASE("Create world and train => destroy train", "[object-create-destroy]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -442,6 +475,8 @@ TEST_CASE("Create world and train => destroy train", "[object-create-destroy]")
TEST_CASE("Create world and zone => destroy world", "[object-create-destroy]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -457,6 +492,8 @@ TEST_CASE("Create world and zone => destroy world", "[object-create-destroy]")
TEST_CASE("Create world and zone => destroy zone", "[object-create-destroy]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -476,6 +513,8 @@ TEST_CASE("Create world and zone => destroy zone", "[object-create-destroy]")
TEST_CASE("Create world, board, block and zone => destroy world", "[object-create-destroy]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -511,6 +550,8 @@ TEST_CASE("Create world, board, block and zone => destroy world", "[object-creat
TEST_CASE("Create world, board, block and zone => destroy board", "[object-create-destroy]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -551,6 +592,8 @@ TEST_CASE("Create world, board, block and zone => destroy board", "[object-creat
TEST_CASE("Create world, board, block and zone => destroy block", "[object-create-destroy]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -592,6 +635,8 @@ TEST_CASE("Create world, board, block and zone => destroy block", "[object-creat
TEST_CASE("Create world, board, block and zone => destroy zone", "[object-create-destroy]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());

Datei anzeigen

@ -20,6 +20,7 @@
*/
#include <catch2/catch_test_macros.hpp>
#include "../src/core/eventloop.hpp"
#include "../src/world/world.hpp"
#include "../src/world/worldloader.hpp"
#include "../src/world/worldsaver.hpp"
@ -34,6 +35,8 @@
TEST_CASE("Train: Save/Load", "[train][train-saveload]")
{
EventLoop::reset();
std::filesystem::path ctw;
std::string worldUUID;

Datei anzeigen

@ -21,6 +21,7 @@
*/
#include <catch2/catch_test_macros.hpp>
#include "../../src/core/eventloop.hpp"
#include "../../src/core/objectproperty.tpp"
#include "../../src/core/method.tpp"
#include "../../src/world/world.hpp"
@ -34,6 +35,8 @@
TEST_CASE("Activate empty train", "[train]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -50,6 +53,8 @@ TEST_CASE("Activate empty train", "[train]")
TEST_CASE("Delete active train", "[train]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -82,6 +87,8 @@ TEST_CASE("Delete active train", "[train]")
TEST_CASE("Delete inactive train", "[train]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -113,6 +120,8 @@ TEST_CASE("Delete inactive train", "[train]")
TEST_CASE("Delete rail vehicle in active train", "[train]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -147,6 +156,8 @@ TEST_CASE("Delete rail vehicle in active train", "[train]")
TEST_CASE("Delete rail vehicle in inactive train", "[train]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());

Datei anzeigen

@ -25,6 +25,8 @@
TEST_CASE("Create worldlist and model => destroy worldlist", "[worldlist]")
{
EventLoop::reset();
const auto path = std::filesystem::temp_directory_path() / "traintastic-8emltd";
{
auto worldList = std::make_shared<WorldList>(path);
@ -47,6 +49,8 @@ TEST_CASE("Create worldlist and model => destroy worldlist", "[worldlist]")
TEST_CASE("Create worldlist and model => destroy model", "[worldlist]")
{
EventLoop::reset();
const auto path = std::filesystem::temp_directory_path() / "traintastic-27oz9v";
{
auto worldList = std::make_shared<WorldList>(path);

Datei anzeigen

@ -22,6 +22,7 @@
#include <catch2/catch_test_macros.hpp>
#include <catch2/catch_approx.hpp>
#include "../src/core/attributes.hpp"
#include "../src/core/eventloop.hpp"
#include "../src/core/method.tpp"
#include "../src/core/objectproperty.tpp"
#include "../src/board/board.hpp"
@ -43,6 +44,8 @@
TEST_CASE("Zone: Assign/remove train to/from muted, no smoke and speed limited zone", "[zone]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -127,6 +130,8 @@ TEST_CASE("Zone: Assign/remove train to/from muted, no smoke and speed limited z
TEST_CASE("Zone: Assign/remove events", "[zone]")
{
EventLoop::reset();
size_t trainZoneAssignedEventCount = 0;
size_t trainZoneEnteringEventCount = 0;
size_t trainZoneEnteredEventCount = 0;
@ -326,6 +331,8 @@ TEST_CASE("Zone: Assign/remove events", "[zone]")
TEST_CASE("Zone: Toggle mute/noSmoke/speedLimit with train in zone", "[zone]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -418,8 +425,9 @@ TEST_CASE("Zone: Toggle mute/noSmoke/speedLimit with train in zone", "[zone]")
TEST_CASE("Zone: Check class id's", "[zone]")
{
// class id's may NOT be changed, it will break saved worlds and might break client stuff.
EventLoop::reset();
// class id's may NOT be changed, it will break saved worlds and might break client stuff.
REQUIRE(BlockZoneList::classId == "list.block_zone");
REQUIRE(Zone::classId == "zone");
REQUIRE(ZoneBlockList::classId == "list.zone_block");
@ -454,6 +462,8 @@ TEST_CASE("Zone: Check class id's", "[zone]")
TEST_CASE("Zone: Check enabled attribute", "[zone]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -515,6 +525,8 @@ TEST_CASE("Zone: Check enabled attribute", "[zone]")
TEST_CASE("Zone: zone list table model", "[zone]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -564,6 +576,8 @@ TEST_CASE("Zone: zone list table model", "[zone]")
TEST_CASE("Zone: block zone list table model", "[zone]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -619,6 +633,8 @@ TEST_CASE("Zone: block zone list table model", "[zone]")
TEST_CASE("Zone: zone block list table model", "[zone]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -675,6 +691,8 @@ TEST_CASE("Zone: zone block list table model", "[zone]")
TEST_CASE("Zone: delete zone with block assigned", "[zone]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -706,6 +724,8 @@ TEST_CASE("Zone: delete zone with block assigned", "[zone]")
TEST_CASE("Zone: delete block with zone assigned", "[zone]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());
@ -736,6 +756,8 @@ TEST_CASE("Zone: delete block with zone assigned", "[zone]")
TEST_CASE("Zone: delete board with block with zone assigned", "[zone]")
{
EventLoop::reset();
auto world = World::create();
std::weak_ptr<World> worldWeak = world;
REQUIRE_FALSE(worldWeak.expired());