refactor: moved common kernel stuff to KernelBase #WIP
Dieser Commit ist enthalten in:
Ursprung
aff3bd5c11
Commit
6670c774de
@ -96,6 +96,8 @@ file(GLOB SOURCES
|
||||
"src/hardware/output/map/*.cpp"
|
||||
"src/hardware/programming/lncv/*.hpp"
|
||||
"src/hardware/programming/lncv/*.cpp"
|
||||
"src/hardware/protocol/*.hpp"
|
||||
"src/hardware/protocol/*.cpp"
|
||||
"src/hardware/protocol/dccplusplus/*.hpp"
|
||||
"src/hardware/protocol/dccplusplus/*.cpp"
|
||||
"src/hardware/protocol/dccplusplus/iohandler/*.hpp"
|
||||
|
||||
@ -28,10 +28,7 @@
|
||||
IdObject::IdObject(World& world, std::string_view _id) :
|
||||
m_world{world},
|
||||
id{this, "id", std::string(_id.data(), _id.size()), PropertyFlags::ReadWrite | PropertyFlags::Store | PropertyFlags::ScriptReadOnly,
|
||||
[this](const std::string& value)
|
||||
{
|
||||
idChanged(value);
|
||||
},
|
||||
nullptr,
|
||||
[this](std::string& value)
|
||||
{
|
||||
if(!isValidObjectId(value))
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019-2020 Reinder Feenstra
|
||||
* Copyright (C) 2019-2020,2023 Reinder Feenstra
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -62,7 +62,6 @@ class IdObject : public Object
|
||||
void destroying() override;
|
||||
virtual void addToWorld();
|
||||
void worldEvent(WorldState state, WorldEvent event) override;
|
||||
virtual void idChanged(const std::string& /*newId*/) {}
|
||||
|
||||
public:
|
||||
Property<std::string> id;
|
||||
|
||||
@ -185,16 +185,15 @@ bool DCCPlusPlusInterface::setOnline(bool& value, bool simulation)
|
||||
{
|
||||
if(simulation)
|
||||
{
|
||||
m_kernel = DCCPlusPlus::Kernel::create<DCCPlusPlus::SimulationIOHandler>(dccplusplus->config());
|
||||
m_kernel = DCCPlusPlus::Kernel::create<DCCPlusPlus::SimulationIOHandler>(id.value(), dccplusplus->config());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_kernel = DCCPlusPlus::Kernel::create<DCCPlusPlus::SerialIOHandler>(dccplusplus->config(), device.value(), baudrate.value(), SerialFlowControl::None);
|
||||
m_kernel = DCCPlusPlus::Kernel::create<DCCPlusPlus::SerialIOHandler>(id.value(), dccplusplus->config(), device.value(), baudrate.value(), SerialFlowControl::None);
|
||||
}
|
||||
|
||||
setState(InterfaceState::Initializing);
|
||||
|
||||
m_kernel->setLogId(id.value());
|
||||
m_kernel->setOnStarted(
|
||||
[this]()
|
||||
{
|
||||
@ -216,6 +215,12 @@ bool DCCPlusPlusInterface::setOnline(bool& value, bool simulation)
|
||||
if(powerOn)
|
||||
m_kernel->powerOn();
|
||||
});
|
||||
m_kernel->setOnError(
|
||||
[this]()
|
||||
{
|
||||
setState(InterfaceState::Error);
|
||||
online = false; // communication no longer possible
|
||||
});
|
||||
m_kernel->setOnPowerOnChanged(
|
||||
[this](bool powerOn)
|
||||
{
|
||||
@ -340,12 +345,6 @@ void DCCPlusPlusInterface::checkDecoder(const Decoder& decoder) const
|
||||
}
|
||||
}
|
||||
|
||||
void DCCPlusPlusInterface::idChanged(const std::string& newId)
|
||||
{
|
||||
if(m_kernel)
|
||||
m_kernel->setLogId(newId);
|
||||
}
|
||||
|
||||
void DCCPlusPlusInterface::updateEnabled()
|
||||
{
|
||||
const bool editable = contains(m_world.state, WorldState::Edit);
|
||||
|
||||
@ -61,8 +61,6 @@ class DCCPlusPlusInterface final
|
||||
void check() const;
|
||||
void checkDecoder(const Decoder& decoder) const;
|
||||
|
||||
void idChanged(const std::string& newId) final;
|
||||
|
||||
void updateEnabled();
|
||||
|
||||
protected:
|
||||
|
||||
@ -156,18 +156,23 @@ bool ECoSInterface::setOnline(bool& value, bool simulation)
|
||||
try
|
||||
{
|
||||
if(simulation)
|
||||
m_kernel = ECoS::Kernel::create<ECoS::SimulationIOHandler>(ecos->config(), m_simulation);
|
||||
m_kernel = ECoS::Kernel::create<ECoS::SimulationIOHandler>(id.value(), ecos->config(), m_simulation);
|
||||
else
|
||||
m_kernel = ECoS::Kernel::create<ECoS::TCPIOHandler>(ecos->config(), hostname.value());
|
||||
m_kernel = ECoS::Kernel::create<ECoS::TCPIOHandler>(id.value(), ecos->config(), hostname.value());
|
||||
|
||||
setState(InterfaceState::Initializing);
|
||||
|
||||
m_kernel->setLogId(id.value());
|
||||
m_kernel->setOnStarted(
|
||||
[this]()
|
||||
{
|
||||
setState(InterfaceState::Online);
|
||||
});
|
||||
m_kernel->setOnError(
|
||||
[this]()
|
||||
{
|
||||
setState(InterfaceState::Error);
|
||||
online = false; // communication no longer possible
|
||||
});
|
||||
m_kernel->setOnEmergencyStop(
|
||||
[this]()
|
||||
{
|
||||
@ -327,9 +332,3 @@ void ECoSInterface::worldEvent(WorldState state, WorldEvent event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ECoSInterface::idChanged(const std::string& newId)
|
||||
{
|
||||
if(m_kernel)
|
||||
m_kernel->setLogId(newId);
|
||||
}
|
||||
|
||||
@ -59,8 +59,6 @@ class ECoSInterface final
|
||||
void save(WorldSaver& saver, nlohmann::json& data, nlohmann::json& state) const final;
|
||||
void worldEvent(WorldState state, WorldEvent event) final;
|
||||
|
||||
void idChanged(const std::string& newId) final;
|
||||
|
||||
void typeChanged();
|
||||
|
||||
protected:
|
||||
|
||||
@ -269,26 +269,26 @@ bool LocoNetInterface::setOnline(bool& value, bool simulation)
|
||||
{
|
||||
if(simulation)
|
||||
{
|
||||
m_kernel = LocoNet::Kernel::create<LocoNet::SimulationIOHandler>(loconet->config());
|
||||
m_kernel = LocoNet::Kernel::create<LocoNet::SimulationIOHandler>(id.value(), loconet->config());
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case LocoNetInterfaceType::Serial:
|
||||
m_kernel = LocoNet::Kernel::create<LocoNet::SerialIOHandler>(loconet->config(), device.value(), baudrate.value(), flowControl.value());
|
||||
m_kernel = LocoNet::Kernel::create<LocoNet::SerialIOHandler>(id.value(), loconet->config(), device.value(), baudrate.value(), flowControl.value());
|
||||
break;
|
||||
|
||||
case LocoNetInterfaceType::TCPBinary:
|
||||
m_kernel = LocoNet::Kernel::create<LocoNet::TCPBinaryIOHandler>(loconet->config(), hostname.value(), port.value());
|
||||
m_kernel = LocoNet::Kernel::create<LocoNet::TCPBinaryIOHandler>(id.value(), loconet->config(), hostname.value(), port.value());
|
||||
break;
|
||||
|
||||
case LocoNetInterfaceType::LBServer:
|
||||
m_kernel = LocoNet::Kernel::create<LocoNet::LBServerIOHandler>(loconet->config(), hostname.value(), port.value());
|
||||
m_kernel = LocoNet::Kernel::create<LocoNet::LBServerIOHandler>(id.value(), loconet->config(), hostname.value(), port.value());
|
||||
break;
|
||||
|
||||
case LocoNetInterfaceType::Z21:
|
||||
m_kernel = LocoNet::Kernel::create<LocoNet::Z21IOHandler>(loconet->config(), hostname.value());
|
||||
m_kernel = LocoNet::Kernel::create<LocoNet::Z21IOHandler>(id.value(), loconet->config(), hostname.value());
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -299,7 +299,6 @@ bool LocoNetInterface::setOnline(bool& value, bool simulation)
|
||||
|
||||
setState(InterfaceState::Initializing);
|
||||
|
||||
m_kernel->setLogId(id.value());
|
||||
m_kernel->setOnStarted(
|
||||
[this]()
|
||||
{
|
||||
@ -447,12 +446,6 @@ void LocoNetInterface::worldEvent(WorldState state, WorldEvent event)
|
||||
}
|
||||
}
|
||||
|
||||
void LocoNetInterface::idChanged(const std::string& newId)
|
||||
{
|
||||
if(m_kernel)
|
||||
m_kernel->setLogId(newId);
|
||||
}
|
||||
|
||||
void LocoNetInterface::typeChanged()
|
||||
{
|
||||
const bool serialVisible = isSerial(type);
|
||||
|
||||
@ -64,8 +64,6 @@ class LocoNetInterface final
|
||||
void destroying() final;
|
||||
void worldEvent(WorldState state, WorldEvent event) final;
|
||||
|
||||
void idChanged(const std::string& newId) final;
|
||||
|
||||
void typeChanged();
|
||||
|
||||
protected:
|
||||
|
||||
@ -193,23 +193,23 @@ bool MarklinCANInterface::setOnline(bool& value, bool simulation)
|
||||
{
|
||||
if(simulation)
|
||||
{
|
||||
m_kernel = MarklinCAN::Kernel::create<MarklinCAN::SimulationIOHandler>(marklinCAN->config());
|
||||
m_kernel = MarklinCAN::Kernel::create<MarklinCAN::SimulationIOHandler>(id.value(), marklinCAN->config());
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(type.value())
|
||||
{
|
||||
case MarklinCANInterfaceType::NetworkTCP:
|
||||
m_kernel = MarklinCAN::Kernel::create<MarklinCAN::TCPIOHandler>(marklinCAN->config(), hostname.value());
|
||||
m_kernel = MarklinCAN::Kernel::create<MarklinCAN::TCPIOHandler>(id.value(), marklinCAN->config(), hostname.value());
|
||||
break;
|
||||
|
||||
case MarklinCANInterfaceType::NetworkUDP:
|
||||
m_kernel = MarklinCAN::Kernel::create<MarklinCAN::UDPIOHandler>(marklinCAN->config(), hostname.value());
|
||||
m_kernel = MarklinCAN::Kernel::create<MarklinCAN::UDPIOHandler>(id.value(), marklinCAN->config(), hostname.value());
|
||||
break;
|
||||
|
||||
case MarklinCANInterfaceType::SocketCAN:
|
||||
#ifdef __linux__
|
||||
m_kernel = MarklinCAN::Kernel::create<MarklinCAN::SocketCANIOHandler>(marklinCAN->config(), interface.value());
|
||||
m_kernel = MarklinCAN::Kernel::create<MarklinCAN::SocketCANIOHandler>(id.value(), marklinCAN->config(), interface.value());
|
||||
break;
|
||||
#else
|
||||
setState(InterfaceState::Error);
|
||||
@ -217,7 +217,7 @@ bool MarklinCANInterface::setOnline(bool& value, bool simulation)
|
||||
return false;
|
||||
#endif
|
||||
case MarklinCANInterfaceType::Serial:
|
||||
m_kernel = MarklinCAN::Kernel::create<MarklinCAN::SerialIOHandler>(marklinCAN->config(), device.value(), baudrate.value(), flowControl.value());
|
||||
m_kernel = MarklinCAN::Kernel::create<MarklinCAN::SerialIOHandler>(id.value(), marklinCAN->config(), device.value(), baudrate.value(), flowControl.value());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -225,8 +225,6 @@ bool MarklinCANInterface::setOnline(bool& value, bool simulation)
|
||||
|
||||
setState(InterfaceState::Initializing);
|
||||
|
||||
m_kernel->setLogId(id.value());
|
||||
|
||||
m_kernel->setOnStarted(
|
||||
[this]()
|
||||
{
|
||||
@ -344,12 +342,6 @@ void MarklinCANInterface::worldEvent(WorldState state, WorldEvent event)
|
||||
}
|
||||
}
|
||||
|
||||
void MarklinCANInterface::idChanged(const std::string& newId)
|
||||
{
|
||||
if(m_kernel)
|
||||
m_kernel->setLogId(newId);
|
||||
}
|
||||
|
||||
void MarklinCANInterface::typeChanged()
|
||||
{
|
||||
Attributes::setVisible(hostname, isNetwork(type));
|
||||
|
||||
@ -59,7 +59,6 @@ class MarklinCANInterface final
|
||||
void destroying() final;
|
||||
void worldEvent(WorldState state, WorldEvent event) final;
|
||||
|
||||
void idChanged(const std::string& newId) final;
|
||||
void typeChanged();
|
||||
|
||||
protected:
|
||||
|
||||
@ -133,18 +133,18 @@ bool TraintasticDIYInterface::setOnline(bool& value, bool simulation)
|
||||
{
|
||||
if(simulation)
|
||||
{
|
||||
m_kernel = TraintasticDIY::Kernel::create<TraintasticDIY::SimulationIOHandler>(m_world, traintasticDIY->config());
|
||||
m_kernel = TraintasticDIY::Kernel::create<TraintasticDIY::SimulationIOHandler>(id.value(), m_world, traintasticDIY->config());
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case TraintasticDIYInterfaceType::Serial:
|
||||
m_kernel = TraintasticDIY::Kernel::create<TraintasticDIY::SerialIOHandler>(m_world, traintasticDIY->config(), device.value(), baudrate.value(), flowControl.value());
|
||||
m_kernel = TraintasticDIY::Kernel::create<TraintasticDIY::SerialIOHandler>(id.value(), m_world, traintasticDIY->config(), device.value(), baudrate.value(), flowControl.value());
|
||||
break;
|
||||
|
||||
case TraintasticDIYInterfaceType::NetworkTCP:
|
||||
m_kernel = TraintasticDIY::Kernel::create<TraintasticDIY::TCPIOHandler>(m_world, traintasticDIY->config(), hostname.value(), port.value());
|
||||
m_kernel = TraintasticDIY::Kernel::create<TraintasticDIY::TCPIOHandler>(id.value(), m_world, traintasticDIY->config(), hostname.value(), port.value());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -157,13 +157,17 @@ bool TraintasticDIYInterface::setOnline(bool& value, bool simulation)
|
||||
|
||||
setState(InterfaceState::Initializing);
|
||||
|
||||
m_kernel->setLogId(id.value());
|
||||
m_kernel->setOnStarted(
|
||||
[this]()
|
||||
{
|
||||
setState(InterfaceState::Online);
|
||||
});
|
||||
|
||||
m_kernel->setOnError(
|
||||
[this]()
|
||||
{
|
||||
setState(InterfaceState::Error);
|
||||
online = false; // communication no longer possible
|
||||
});
|
||||
m_kernel->setInputController(this);
|
||||
m_kernel->setOutputController(this);
|
||||
m_kernel->start();
|
||||
@ -218,12 +222,6 @@ void TraintasticDIYInterface::destroying()
|
||||
Interface::destroying();
|
||||
}
|
||||
|
||||
void TraintasticDIYInterface::idChanged(const std::string& newId)
|
||||
{
|
||||
if(m_kernel)
|
||||
m_kernel->setLogId(newId);
|
||||
}
|
||||
|
||||
void TraintasticDIYInterface::updateVisible()
|
||||
{
|
||||
const bool isSerial = (type == TraintasticDIYInterfaceType::Serial);
|
||||
|
||||
@ -56,8 +56,6 @@ class TraintasticDIYInterface final
|
||||
void loaded() final;
|
||||
void destroying() final;
|
||||
|
||||
void idChanged(const std::string& newId) final;
|
||||
|
||||
void updateVisible();
|
||||
|
||||
protected:
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2022 Reinder Feenstra
|
||||
* Copyright (C) 2022-2023 Reinder Feenstra
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -86,17 +86,21 @@ bool WiThrottleInterface::setOnline(bool& value, bool simulation)
|
||||
|
||||
try
|
||||
{
|
||||
m_kernel = WiThrottle::Kernel::create<WiThrottle::TCPIOHandler>(wiThrottle->config(), port.value());
|
||||
m_kernel = WiThrottle::Kernel::create<WiThrottle::TCPIOHandler>(id.value(), wiThrottle->config(), port.value());
|
||||
|
||||
setState(InterfaceState::Initializing);
|
||||
|
||||
m_kernel->setLogId(id.value());
|
||||
|
||||
m_kernel->setOnStarted(
|
||||
[this]()
|
||||
{
|
||||
setState(InterfaceState::Online);
|
||||
});
|
||||
m_kernel->setOnError(
|
||||
[this]()
|
||||
{
|
||||
setState(InterfaceState::Error);
|
||||
online = false; // communication no longer possible
|
||||
});
|
||||
|
||||
m_kernel->setClock(world().clock.value());
|
||||
m_kernel->setThrottleController(this);
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019-2022 Reinder Feenstra
|
||||
* Copyright (C) 2019-2023 Reinder Feenstra
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -66,12 +66,6 @@ void WlanMausInterface::worldEvent(WorldState state, WorldEvent event)
|
||||
}
|
||||
}
|
||||
|
||||
void WlanMausInterface::idChanged(const std::string& newId)
|
||||
{
|
||||
if(m_kernel)
|
||||
m_kernel->setLogId(newId);
|
||||
}
|
||||
|
||||
bool WlanMausInterface::setOnline(bool& value, bool simulation)
|
||||
{
|
||||
if(simulation)
|
||||
@ -84,17 +78,21 @@ bool WlanMausInterface::setOnline(bool& value, bool simulation)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_kernel = Z21::ServerKernel::create<Z21::UDPServerIOHandler>(z21->config(), m_world.decoders.value());
|
||||
m_kernel = Z21::ServerKernel::create<Z21::UDPServerIOHandler>(id.value(), z21->config(), m_world.decoders.value());
|
||||
|
||||
setState(InterfaceState::Initializing);
|
||||
|
||||
m_kernel->setLogId(id.value());
|
||||
m_kernel->setOnStarted(
|
||||
[this]()
|
||||
{
|
||||
setState(InterfaceState::Online);
|
||||
});
|
||||
|
||||
m_kernel->setOnError(
|
||||
[this]()
|
||||
{
|
||||
setState(InterfaceState::Error);
|
||||
online = false; // communication no longer possible
|
||||
});
|
||||
m_kernel->setOnTrackPowerOff(
|
||||
[this]()
|
||||
{
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019-2022 Reinder Feenstra
|
||||
* Copyright (C) 2019-2023 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,7 +46,6 @@ class WlanMausInterface : public Interface
|
||||
|
||||
protected:
|
||||
void worldEvent(WorldState state, WorldEvent event) final;
|
||||
void idChanged(const std::string& newId) final;
|
||||
bool setOnline(bool& value, bool simulation) final;
|
||||
|
||||
public:
|
||||
|
||||
@ -231,7 +231,7 @@ bool XpressNetInterface::setOnline(bool& value, bool simulation)
|
||||
{
|
||||
if(simulation)
|
||||
{
|
||||
m_kernel = XpressNet::Kernel::create<XpressNet::SimulationIOHandler>(xpressnet->config());
|
||||
m_kernel = XpressNet::Kernel::create<XpressNet::SimulationIOHandler>(id.value(), xpressnet->config());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -243,22 +243,22 @@ bool XpressNetInterface::setOnline(bool& value, bool simulation)
|
||||
case XpressNetSerialInterfaceType::LenzLI100:
|
||||
case XpressNetSerialInterfaceType::LenzLI100F:
|
||||
case XpressNetSerialInterfaceType::LenzLI101F:
|
||||
m_kernel = XpressNet::Kernel::create<XpressNet::SerialIOHandler>(xpressnet->config(), device.value(), baudrate.value(), flowControl.value());
|
||||
m_kernel = XpressNet::Kernel::create<XpressNet::SerialIOHandler>(id.value(), xpressnet->config(), device.value(), baudrate.value(), flowControl.value());
|
||||
break;
|
||||
|
||||
case XpressNetSerialInterfaceType::RoSoftS88XPressNetLI:
|
||||
m_kernel = XpressNet::Kernel::create<XpressNet::RoSoftS88XPressNetLIIOHandler>(xpressnet->config(), device.value(), baudrate.value(), flowControl.value(), s88StartAddress.value(), s88ModuleCount.value());
|
||||
m_kernel = XpressNet::Kernel::create<XpressNet::RoSoftS88XPressNetLIIOHandler>(id.value(), xpressnet->config(), device.value(), baudrate.value(), flowControl.value(), s88StartAddress.value(), s88ModuleCount.value());
|
||||
break;
|
||||
|
||||
case XpressNetSerialInterfaceType::LenzLIUSB:
|
||||
case XpressNetSerialInterfaceType::DigikeijsDR5000:
|
||||
m_kernel = XpressNet::Kernel::create<XpressNet::LIUSBIOHandler>(xpressnet->config(), device.value(), baudrate.value(), flowControl.value());
|
||||
m_kernel = XpressNet::Kernel::create<XpressNet::LIUSBIOHandler>(id.value(), xpressnet->config(), device.value(), baudrate.value(), flowControl.value());
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case XpressNetInterfaceType::Network:
|
||||
m_kernel = XpressNet::Kernel::create<XpressNet::TCPIOHandler>(xpressnet->config(), hostname.value(), port.value());
|
||||
m_kernel = XpressNet::Kernel::create<XpressNet::TCPIOHandler>(id.value(), xpressnet->config(), hostname.value(), port.value());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -271,7 +271,6 @@ bool XpressNetInterface::setOnline(bool& value, bool simulation)
|
||||
|
||||
setState(InterfaceState::Initializing);
|
||||
|
||||
m_kernel->setLogId(id.value());
|
||||
m_kernel->setOnStarted(
|
||||
[this]()
|
||||
{
|
||||
@ -403,12 +402,6 @@ void XpressNetInterface::worldEvent(WorldState state, WorldEvent event)
|
||||
}
|
||||
}
|
||||
|
||||
void XpressNetInterface::idChanged(const std::string& newId)
|
||||
{
|
||||
if(m_kernel)
|
||||
m_kernel->setLogId(newId);
|
||||
}
|
||||
|
||||
void XpressNetInterface::updateVisible()
|
||||
{
|
||||
const bool isSerial = (type == XpressNetInterfaceType::Serial);
|
||||
|
||||
@ -60,8 +60,6 @@ class XpressNetInterface final
|
||||
void destroying() final;
|
||||
void worldEvent(WorldState state, WorldEvent event) final;
|
||||
|
||||
void idChanged(const std::string& newId) final;
|
||||
|
||||
void updateVisible();
|
||||
|
||||
protected:
|
||||
|
||||
@ -162,18 +162,23 @@ bool Z21Interface::setOnline(bool& value, bool simulation)
|
||||
try
|
||||
{
|
||||
if(simulation)
|
||||
m_kernel = Z21::ClientKernel::create<Z21::SimulationIOHandler>(z21->config());
|
||||
m_kernel = Z21::ClientKernel::create<Z21::SimulationIOHandler>(id.value(), z21->config());
|
||||
else
|
||||
m_kernel = Z21::ClientKernel::create<Z21::UDPClientIOHandler>(z21->config(), hostname.value(), port.value());
|
||||
m_kernel = Z21::ClientKernel::create<Z21::UDPClientIOHandler>(id.value(), z21->config(), hostname.value(), port.value());
|
||||
|
||||
setState(InterfaceState::Initializing);
|
||||
|
||||
m_kernel->setLogId(id.value());
|
||||
m_kernel->setOnStarted(
|
||||
[this]()
|
||||
{
|
||||
setState(InterfaceState::Online);
|
||||
});
|
||||
m_kernel->setOnError(
|
||||
[this]()
|
||||
{
|
||||
setState(InterfaceState::Error);
|
||||
online = false; // communication no longer possible
|
||||
});
|
||||
m_kernel->setOnSerialNumberChanged(
|
||||
[this](uint32_t newValue)
|
||||
{
|
||||
@ -305,9 +310,3 @@ void Z21Interface::worldEvent(WorldState state, WorldEvent event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Z21Interface::idChanged(const std::string& newId)
|
||||
{
|
||||
if(m_kernel)
|
||||
m_kernel->setLogId(newId);
|
||||
}
|
||||
|
||||
@ -55,8 +55,6 @@ class Z21Interface final
|
||||
void destroying() final;
|
||||
void worldEvent(WorldState state, WorldEvent event) final;
|
||||
|
||||
void idChanged(const std::string& newId) final;
|
||||
|
||||
void updateVisible();
|
||||
|
||||
protected:
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2021-2022 Reinder Feenstra
|
||||
* Copyright (C) 2021-2023 Reinder Feenstra
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -67,8 +67,8 @@ void SerialIOHandler::read()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E2002_SERIAL_READ_FAILED_X, ec);
|
||||
// TODO interface status -> error
|
||||
Log::log(m_kernel.logId, LogMessage::E2002_SERIAL_READ_FAILED_X, ec);
|
||||
m_kernel.error();
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -95,8 +95,8 @@ void SerialIOHandler::write()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E2001_SERIAL_WRITE_FAILED_X, ec);
|
||||
// TODO interface status -> error
|
||||
Log::log(m_kernel.logId, LogMessage::E2001_SERIAL_WRITE_FAILED_X, ec);
|
||||
m_kernel.error();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@ -36,17 +36,15 @@
|
||||
|
||||
namespace DCCPlusPlus {
|
||||
|
||||
Kernel::Kernel(const Config& config, bool simulation)
|
||||
: m_ioContext{1}
|
||||
Kernel::Kernel(std::string logId_, const Config& config, bool simulation)
|
||||
: KernelBase(std::move(logId_))
|
||||
, m_ioContext{1}
|
||||
, m_simulation{simulation}
|
||||
, m_startupDelayTimer{m_ioContext}
|
||||
, m_decoderController{nullptr}
|
||||
, m_inputController{nullptr}
|
||||
, m_outputController{nullptr}
|
||||
, m_config{config}
|
||||
#ifndef NDEBUG
|
||||
, m_started{false}
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
@ -119,7 +117,7 @@ void Kernel::receive(std::string_view message)
|
||||
EventLoop::call(
|
||||
[this, msg=std::string(rtrim(message, '\n'))]()
|
||||
{
|
||||
Log::log(m_logId, LogMessage::D2002_RX_X, msg);
|
||||
Log::log(logId, LogMessage::D2002_RX_X, msg);
|
||||
});
|
||||
|
||||
if(message.size() > 1 && message[0] == '<')
|
||||
@ -387,7 +385,7 @@ void Kernel::send(std::string_view message)
|
||||
EventLoop::call(
|
||||
[this, msg=std::string(rtrim(message, '\n'))]()
|
||||
{
|
||||
Log::log(m_logId, LogMessage::D2001_TX_X, msg);
|
||||
Log::log(logId, LogMessage::D2001_TX_X, msg);
|
||||
});
|
||||
}
|
||||
else
|
||||
@ -399,7 +397,7 @@ void Kernel::startupDelayExpired(const boost::system::error_code& ec)
|
||||
if(ec)
|
||||
return;
|
||||
|
||||
m_onStarted();
|
||||
started();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
#ifndef TRAINTASTIC_SERVER_HARDWARE_PROTOCOL_DCCPLUSPLUS_KERNEL_HPP
|
||||
#define TRAINTASTIC_SERVER_HARDWARE_PROTOCOL_DCCPLUSPLUS_KERNEL_HPP
|
||||
|
||||
#include "../kernelbase.hpp"
|
||||
#include <array>
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
@ -43,7 +44,7 @@ namespace DCCPlusPlus {
|
||||
|
||||
struct Message;
|
||||
|
||||
class Kernel
|
||||
class Kernel : public ::KernelBase
|
||||
{
|
||||
public:
|
||||
static constexpr uint32_t idMin = 0;
|
||||
@ -75,9 +76,7 @@ class Kernel
|
||||
std::unique_ptr<IOHandler> m_ioHandler;
|
||||
const bool m_simulation;
|
||||
std::thread m_thread;
|
||||
std::string m_logId;
|
||||
boost::asio::steady_timer m_startupDelayTimer;
|
||||
std::function<void()> m_onStarted;
|
||||
|
||||
TriState m_powerOn;
|
||||
TriState m_emergencyStop;
|
||||
@ -91,11 +90,8 @@ class Kernel
|
||||
OutputController* m_outputController;
|
||||
|
||||
Config m_config;
|
||||
#ifndef NDEBUG
|
||||
bool m_started;
|
||||
#endif
|
||||
|
||||
Kernel(const Config& config, bool simulation);
|
||||
Kernel(std::string logId_, const Config& config, bool simulation);
|
||||
|
||||
void setIOHandler(std::unique_ptr<IOHandler> handler);
|
||||
|
||||
@ -131,10 +127,10 @@ class Kernel
|
||||
* @return The kernel instance
|
||||
*/
|
||||
template<class IOHandlerType, class... Args>
|
||||
static std::unique_ptr<Kernel> create(const Config& config, Args... args)
|
||||
static std::unique_ptr<Kernel> create(std::string logId_, const Config& config, Args... args)
|
||||
{
|
||||
static_assert(std::is_base_of_v<IOHandler, IOHandlerType>);
|
||||
std::unique_ptr<Kernel> kernel{new Kernel(config, isSimulation<IOHandlerType>())};
|
||||
std::unique_ptr<Kernel> kernel{new Kernel(std::move(logId_), config, isSimulation<IOHandlerType>())};
|
||||
kernel->setIOHandler(std::make_unique<IOHandlerType>(*kernel, std::forward<Args>(args)...));
|
||||
return kernel;
|
||||
}
|
||||
@ -152,22 +148,6 @@ class Kernel
|
||||
return static_cast<T&>(*m_ioHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
inline const std::string& logId() { return m_logId; }
|
||||
|
||||
/**
|
||||
* @brief Set object id used for log messages
|
||||
*
|
||||
* @param[in] value The object id
|
||||
*/
|
||||
inline void setLogId(std::string value)
|
||||
{
|
||||
m_logId = std::move(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set DCC++ configuration
|
||||
*
|
||||
@ -175,18 +155,6 @@ class Kernel
|
||||
*/
|
||||
void setConfig(const Config& config);
|
||||
|
||||
/**
|
||||
* @brief ...
|
||||
*
|
||||
* @param[in] callback ...
|
||||
* @note This function may not be called when the kernel is running.
|
||||
*/
|
||||
inline void setOnStarted(std::function<void()> callback)
|
||||
{
|
||||
assert(!m_started);
|
||||
m_onStarted = std::move(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ...
|
||||
*
|
||||
|
||||
@ -98,8 +98,8 @@ void TCPIOHandler::read()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E2008_SOCKET_READ_FAILED_X, ec);
|
||||
// TODO interface status -> error
|
||||
Log::log(m_kernel.logId, LogMessage::E2008_SOCKET_READ_FAILED_X, ec);
|
||||
m_kernel.error();
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -209,8 +209,8 @@ void TCPIOHandler::write()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E2007_SOCKET_WRITE_FAILED_X, ec);
|
||||
// TODO interface status -> error
|
||||
Log::log(m_kernel.logId, LogMessage::E2007_SOCKET_WRITE_FAILED_X, ec);
|
||||
m_kernel.error();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@ -72,16 +72,14 @@ static constexpr DecoderProtocol toDecoderProtocol(LocomotiveProtocol locomotive
|
||||
return DecoderProtocol::None;
|
||||
}
|
||||
|
||||
Kernel::Kernel(const Config& config, bool simulation)
|
||||
: m_ioContext{1}
|
||||
Kernel::Kernel(std::string logId_, const Config& config, bool simulation)
|
||||
: KernelBase(std::move(logId_))
|
||||
, m_ioContext{1}
|
||||
, m_simulation{simulation}
|
||||
, m_decoderController{nullptr}
|
||||
, m_inputController{nullptr}
|
||||
, m_outputController{nullptr}
|
||||
, m_config{config}
|
||||
#ifndef NDEBUG
|
||||
, m_started{false}
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
@ -94,12 +92,6 @@ void Kernel::setConfig(const Config& config)
|
||||
});
|
||||
}
|
||||
|
||||
void Kernel::setOnStarted(std::function<void()> callback)
|
||||
{
|
||||
assert(!m_started);
|
||||
m_onStarted = std::move(callback);
|
||||
}
|
||||
|
||||
void Kernel::setOnEmergencyStop(std::function<void()> callback)
|
||||
{
|
||||
assert(!m_started);
|
||||
@ -156,8 +148,8 @@ void Kernel::start()
|
||||
EventLoop::call(
|
||||
[this, e]()
|
||||
{
|
||||
Log::log(logId(), e.message(), e.args());
|
||||
//! \todo error();
|
||||
Log::log(logId, e.message(), e.args());
|
||||
error();
|
||||
});
|
||||
return;
|
||||
}
|
||||
@ -167,12 +159,7 @@ void Kernel::start()
|
||||
m_objects.add(std::make_unique<SwitchManager>(*this));
|
||||
m_objects.add(std::make_unique<FeedbackManager>(*this));
|
||||
|
||||
if(m_onStarted)
|
||||
EventLoop::call(
|
||||
[this]()
|
||||
{
|
||||
m_onStarted();
|
||||
});
|
||||
started();
|
||||
});
|
||||
|
||||
#ifndef NDEBUG
|
||||
@ -231,7 +218,7 @@ void Kernel::receive(std::string_view message)
|
||||
{
|
||||
std::string msg{rtrim(message, {'\r', '\n'})};
|
||||
std::replace_if(msg.begin(), msg.end(), [](char c){ return c == '\r' || c == '\n'; }, ';');
|
||||
EventLoop::call([this, msg](){ Log::log(m_logId, LogMessage::D2002_RX_X, msg); });
|
||||
EventLoop::call([this, msg](){ Log::log(logId, LogMessage::D2002_RX_X, msg); });
|
||||
}
|
||||
|
||||
if(Reply reply; parseReply(message, reply))
|
||||
@ -247,7 +234,7 @@ void Kernel::receive(std::string_view message)
|
||||
it->second->receiveEvent(event);
|
||||
}
|
||||
else
|
||||
{}// EventLoop::call([this]() { Log::log(m_logId, LogMessage::E2018_ParseError); });
|
||||
{}// EventLoop::call([this]() { Log::log(logId, LogMessage::E2018_ParseError); });
|
||||
}
|
||||
|
||||
ECoS& Kernel::ecos()
|
||||
@ -550,7 +537,7 @@ void Kernel::send(std::string_view message)
|
||||
EventLoop::call(
|
||||
[this, msg=std::string(rtrim(message, '\n'))]()
|
||||
{
|
||||
Log::log(m_logId, LogMessage::D2001_TX_X, msg);
|
||||
Log::log(logId, LogMessage::D2001_TX_X, msg);
|
||||
});
|
||||
}
|
||||
else
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
#ifndef TRAINTASTIC_SERVER_HARDWARE_PROTOCOL_ECOS_KERNEL_HPP
|
||||
#define TRAINTASTIC_SERVER_HARDWARE_PROTOCOL_ECOS_KERNEL_HPP
|
||||
|
||||
#include "../kernelbase.hpp"
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
@ -48,7 +49,7 @@ class SwitchManager;
|
||||
class Feedback;
|
||||
struct Simulation;
|
||||
|
||||
class Kernel
|
||||
class Kernel : public ::KernelBase
|
||||
{
|
||||
friend class Object;
|
||||
friend class ECoS;
|
||||
@ -112,8 +113,6 @@ class Kernel
|
||||
std::unique_ptr<IOHandler> m_ioHandler;
|
||||
const bool m_simulation;
|
||||
std::thread m_thread;
|
||||
std::string m_logId;
|
||||
std::function<void()> m_onStarted;
|
||||
|
||||
Objects m_objects;
|
||||
|
||||
@ -125,11 +124,8 @@ class Kernel
|
||||
OutputController* m_outputController;
|
||||
|
||||
Config m_config;
|
||||
#ifndef NDEBUG
|
||||
bool m_started;
|
||||
#endif
|
||||
|
||||
Kernel(const Config& config, bool simulation);
|
||||
Kernel(std::string logId_, const Config& config, bool simulation);
|
||||
|
||||
void setIOHandler(std::unique_ptr<IOHandler> handler);
|
||||
|
||||
@ -169,10 +165,10 @@ class Kernel
|
||||
* @return The kernel instance
|
||||
*/
|
||||
template<class IOHandlerType, class... Args>
|
||||
static std::unique_ptr<Kernel> create(const Config& config, Args... args)
|
||||
static std::unique_ptr<Kernel> create(std::string logId_, const Config& config, Args... args)
|
||||
{
|
||||
static_assert(std::is_base_of_v<IOHandler, IOHandlerType>);
|
||||
std::unique_ptr<Kernel> kernel{new Kernel(config, isSimulation<IOHandlerType>())};
|
||||
std::unique_ptr<Kernel> kernel{new Kernel(std::move(logId_), config, isSimulation<IOHandlerType>())};
|
||||
kernel->setIOHandler(std::make_unique<IOHandlerType>(*kernel, std::forward<Args>(args)...));
|
||||
return kernel;
|
||||
}
|
||||
@ -189,34 +185,12 @@ class Kernel
|
||||
return static_cast<T&>(*m_ioHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get object id used for log messages
|
||||
* @return The object id
|
||||
*/
|
||||
inline const std::string& logId()
|
||||
{
|
||||
return m_logId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set object id used for log messages
|
||||
* @param[in] value The object id
|
||||
*/
|
||||
void setLogId(std::string value) { m_logId = std::move(value); }
|
||||
|
||||
/**
|
||||
* @brief Set ECoS configuration
|
||||
* @param[in] config The LocoNet configuration
|
||||
*/
|
||||
void setConfig(const Config& config);
|
||||
|
||||
/**
|
||||
* @brief ...
|
||||
* @param[in] callback ...
|
||||
* @note This function may not be called when the kernel is running.
|
||||
*/
|
||||
void setOnStarted(std::function<void()> callback);
|
||||
|
||||
/**
|
||||
* @brief ...
|
||||
* @param[in] callback ...
|
||||
|
||||
81
server/src/hardware/protocol/kernelbase.cpp
Normale Datei
81
server/src/hardware/protocol/kernelbase.cpp
Normale Datei
@ -0,0 +1,81 @@
|
||||
/**
|
||||
* server/src/hardware/protocol/kernelbase.cpp
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2023 Reinder Feenstra
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "kernelbase.hpp"
|
||||
#include "../../core/eventloop.hpp"
|
||||
|
||||
KernelBase::KernelBase(std::string logId_)
|
||||
: logId{logId_}
|
||||
{
|
||||
}
|
||||
|
||||
void KernelBase::setOnStarted(std::function<void()> callback)
|
||||
{
|
||||
assert(isEventLoopThread());
|
||||
assert(!m_started);
|
||||
m_onStarted = std::move(callback);
|
||||
}
|
||||
|
||||
void KernelBase::setOnError(std::function<void()> callback)
|
||||
{
|
||||
assert(isEventLoopThread());
|
||||
assert(!m_started);
|
||||
m_onError = std::move(callback);
|
||||
}
|
||||
|
||||
void KernelBase::error()
|
||||
{
|
||||
if(!m_onError) /*[[unlikely]]*/
|
||||
return;
|
||||
|
||||
if(isEventLoopThread())
|
||||
{
|
||||
m_onError();
|
||||
}
|
||||
else
|
||||
{
|
||||
EventLoop::call(
|
||||
[this]()
|
||||
{
|
||||
m_onError();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void KernelBase::started()
|
||||
{
|
||||
if(!m_onStarted) /*[[unlikely]]*/
|
||||
return;
|
||||
|
||||
if(isEventLoopThread())
|
||||
{
|
||||
m_onStarted();
|
||||
}
|
||||
else
|
||||
{
|
||||
EventLoop::call(
|
||||
[this]()
|
||||
{
|
||||
m_onStarted();
|
||||
});
|
||||
}
|
||||
}
|
||||
74
server/src/hardware/protocol/kernelbase.hpp
Normale Datei
74
server/src/hardware/protocol/kernelbase.hpp
Normale Datei
@ -0,0 +1,74 @@
|
||||
/**
|
||||
* server/src/hardware/protocol/kernelbase.hpp
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2023 Reinder Feenstra
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef TRAINTASTIC_SERVER_HARDWARE_PROTOCOL_KERNELBASE_HPP
|
||||
#define TRAINTASTIC_SERVER_HARDWARE_PROTOCOL_KERNELBASE_HPP
|
||||
|
||||
#include <string>
|
||||
#include <functional>
|
||||
|
||||
class KernelBase
|
||||
{
|
||||
private:
|
||||
std::function<void()> m_onStarted;
|
||||
std::function<void()> m_onError;
|
||||
|
||||
protected:
|
||||
#ifndef NDEBUG
|
||||
bool m_started = false;
|
||||
#endif
|
||||
|
||||
KernelBase(std::string logId_);
|
||||
|
||||
void started();
|
||||
|
||||
public:
|
||||
const std::string logId; //!< Object id for log messages.
|
||||
|
||||
/**
|
||||
* \brief ...
|
||||
*
|
||||
* \param[in] callback Handler to call when the kernel is fully started.
|
||||
* \note This function may not be called when the kernel is running.
|
||||
*/
|
||||
void setOnStarted(std::function<void()> callback);
|
||||
|
||||
/**
|
||||
* \brief Register error handler
|
||||
*
|
||||
* Once this handler is called the LocoNet communication it stopped.
|
||||
*
|
||||
* \param[in] callback Handler to call in case of an error.
|
||||
* \note This function may not be called when the kernel is running.
|
||||
*/
|
||||
void setOnError(std::function<void()> callback);
|
||||
|
||||
/**
|
||||
* \brief Report fatal error
|
||||
* Must be called by the IO handler in case of a fatal error.
|
||||
* This will put the interface in error state.
|
||||
* \note This function must run in the event loop thread.
|
||||
*/
|
||||
void error();
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -160,7 +160,7 @@ void LBServerIOHandler::read()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E2008_SOCKET_READ_FAILED_X, ec);
|
||||
Log::log(m_kernel.logId, LogMessage::E2008_SOCKET_READ_FAILED_X, ec);
|
||||
m_kernel.error();
|
||||
});
|
||||
}
|
||||
@ -179,7 +179,7 @@ void LBServerIOHandler::write()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E2007_SOCKET_WRITE_FAILED_X, ec);
|
||||
Log::log(m_kernel.logId, LogMessage::E2007_SOCKET_WRITE_FAILED_X, ec);
|
||||
m_kernel.error();
|
||||
});
|
||||
}
|
||||
|
||||
@ -97,7 +97,7 @@ void SerialIOHandler::read()
|
||||
EventLoop::call(
|
||||
[this, drop]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::W2001_RECEIVED_MALFORMED_DATA_DROPPED_X_BYTES, drop);
|
||||
Log::log(m_kernel.logId, LogMessage::W2001_RECEIVED_MALFORMED_DATA_DROPPED_X_BYTES, drop);
|
||||
});
|
||||
}
|
||||
else if(message->size() <= bytesTransferred)
|
||||
@ -121,7 +121,7 @@ void SerialIOHandler::read()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E2002_SERIAL_READ_FAILED_X, ec);
|
||||
Log::log(m_kernel.logId, LogMessage::E2002_SERIAL_READ_FAILED_X, ec);
|
||||
m_kernel.error();
|
||||
});
|
||||
}
|
||||
@ -149,7 +149,7 @@ void SerialIOHandler::write()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E2001_SERIAL_WRITE_FAILED_X, ec);
|
||||
Log::log(m_kernel.logId, LogMessage::E2001_SERIAL_WRITE_FAILED_X, ec);
|
||||
m_kernel.error();
|
||||
});
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@ void TCPBinaryIOHandler::read()
|
||||
EventLoop::call(
|
||||
[this, drop]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::W2001_RECEIVED_MALFORMED_DATA_DROPPED_X_BYTES, drop);
|
||||
Log::log(m_kernel.logId, LogMessage::W2001_RECEIVED_MALFORMED_DATA_DROPPED_X_BYTES, drop);
|
||||
});
|
||||
}
|
||||
else if(message->size() <= bytesTransferred)
|
||||
@ -114,7 +114,7 @@ void TCPBinaryIOHandler::read()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E2008_SOCKET_READ_FAILED_X, ec);
|
||||
Log::log(m_kernel.logId, LogMessage::E2008_SOCKET_READ_FAILED_X, ec);
|
||||
m_kernel.error();
|
||||
});
|
||||
}
|
||||
@ -142,7 +142,7 @@ void TCPBinaryIOHandler::write()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E2007_SOCKET_WRITE_FAILED_X, ec);
|
||||
Log::log(m_kernel.logId, LogMessage::E2007_SOCKET_WRITE_FAILED_X, ec);
|
||||
m_kernel.error();
|
||||
});
|
||||
}
|
||||
|
||||
@ -143,7 +143,7 @@ void Z21IOHandler::receive()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E2009_SOCKET_RECEIVE_FAILED_X, ec);
|
||||
Log::log(m_kernel.logId, LogMessage::E2009_SOCKET_RECEIVE_FAILED_X, ec);
|
||||
m_kernel.error();
|
||||
});
|
||||
}
|
||||
@ -180,7 +180,7 @@ void Z21IOHandler::send()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E2011_SOCKET_SEND_FAILED_X, ec);
|
||||
Log::log(m_kernel.logId, LogMessage::E2011_SOCKET_SEND_FAILED_X, ec);
|
||||
m_kernel.error();
|
||||
});
|
||||
}
|
||||
|
||||
@ -65,8 +65,9 @@ constexpr Kernel::Priority& operator ++(Kernel::Priority& value)
|
||||
return (value = static_cast<Kernel::Priority>(static_cast<std::underlying_type_t<Kernel::Priority>>(value) + 1));
|
||||
}
|
||||
|
||||
Kernel::Kernel(const Config& config, bool simulation)
|
||||
: m_ioContext{1}
|
||||
Kernel::Kernel(std::string logId_, const Config& config, bool simulation)
|
||||
: KernelBase(std::move(logId_))
|
||||
, m_ioContext{1}
|
||||
, m_simulation{simulation}
|
||||
, m_waitingForEcho{false}
|
||||
, m_waitingForEchoTimer{m_ioContext}
|
||||
@ -79,9 +80,6 @@ Kernel::Kernel(const Config& config, bool simulation)
|
||||
, m_identificationController{nullptr}
|
||||
, m_debugDir{Traintastic::instance->debugDir()}
|
||||
, m_config{config}
|
||||
#ifndef NDEBUG
|
||||
, m_started{false}
|
||||
#endif
|
||||
{
|
||||
assert(isEventLoopThread());
|
||||
}
|
||||
@ -127,7 +125,7 @@ void Kernel::setConfig(const Config& config)
|
||||
EventLoop::call(
|
||||
[this]()
|
||||
{
|
||||
Log::log(m_logId, LogMessage::N2006_LISTEN_ONLY_MODE_ACTIVATED);
|
||||
Log::log(logId, LogMessage::N2006_LISTEN_ONLY_MODE_ACTIVATED);
|
||||
});
|
||||
}
|
||||
else if(!newConfig.listenOnly && m_config.listenOnly)
|
||||
@ -135,7 +133,7 @@ void Kernel::setConfig(const Config& config)
|
||||
EventLoop::call(
|
||||
[this]()
|
||||
{
|
||||
Log::log(m_logId, LogMessage::N2007_LISTEN_ONLY_MODE_DEACTIVATED);
|
||||
Log::log(logId, LogMessage::N2007_LISTEN_ONLY_MODE_DEACTIVATED);
|
||||
});
|
||||
}
|
||||
|
||||
@ -161,20 +159,6 @@ void Kernel::setConfig(const Config& config)
|
||||
});
|
||||
}
|
||||
|
||||
void Kernel::setOnStarted(std::function<void()> callback)
|
||||
{
|
||||
assert(isEventLoopThread());
|
||||
assert(!m_started);
|
||||
m_onStarted = std::move(callback);
|
||||
}
|
||||
|
||||
void Kernel::setOnError(std::function<void()> callback)
|
||||
{
|
||||
assert(isEventLoopThread());
|
||||
assert(!m_started);
|
||||
m_onError = std::move(callback);
|
||||
}
|
||||
|
||||
void Kernel::setOnGlobalPowerChanged(std::function<void(bool)> callback)
|
||||
{
|
||||
assert(isEventLoopThread());
|
||||
@ -242,7 +226,7 @@ void Kernel::start()
|
||||
m_outputValues.fill(TriState::Undefined);
|
||||
|
||||
if(m_config.listenOnly)
|
||||
Log::log(m_logId, LogMessage::N2006_LISTEN_ONLY_MODE_ACTIVATED);
|
||||
Log::log(logId, LogMessage::N2006_LISTEN_ONLY_MODE_ACTIVATED);
|
||||
|
||||
m_thread = std::thread(
|
||||
[this]()
|
||||
@ -270,7 +254,7 @@ void Kernel::start()
|
||||
EventLoop::call(
|
||||
[this, e]()
|
||||
{
|
||||
Log::log(logId(), e.message(), e.args());
|
||||
Log::log(logId, e.message(), e.args());
|
||||
error();
|
||||
});
|
||||
return;
|
||||
@ -285,12 +269,7 @@ void Kernel::start()
|
||||
for(uint8_t slot = SLOT_LOCO_MIN; slot <= m_config.locomotiveSlots; slot++)
|
||||
send(RequestSlotData(slot), LowPriority);
|
||||
|
||||
if(m_onStarted)
|
||||
EventLoop::call(
|
||||
[this]()
|
||||
{
|
||||
m_onStarted();
|
||||
});
|
||||
started();
|
||||
});
|
||||
|
||||
#ifndef NDEBUG
|
||||
@ -332,7 +311,7 @@ void Kernel::receive(const Message& message)
|
||||
m_pcap->writeRecord(&message, message.size());
|
||||
|
||||
if(m_config.debugLogRXTX)
|
||||
EventLoop::call([this, msg=toString(message)](){ Log::log(m_logId, LogMessage::D2002_RX_X, msg); });
|
||||
EventLoop::call([this, msg=toString(message)](){ Log::log(logId, LogMessage::D2002_RX_X, msg); });
|
||||
|
||||
bool isResponse = false;
|
||||
if(m_waitingForEcho && message == lastSentMessage())
|
||||
@ -492,7 +471,7 @@ void Kernel::receive(const Message& message)
|
||||
EventLoop::call(
|
||||
[this, address=1 + inputRep.fullAddress(), value=inputRep.value()]()
|
||||
{
|
||||
Log::log(m_logId, LogMessage::D2007_INPUT_X_IS_X, address, value ? std::string_view{"1"} : std::string_view{"0"});
|
||||
Log::log(logId, LogMessage::D2007_INPUT_X_IS_X, address, value ? std::string_view{"1"} : std::string_view{"0"});
|
||||
});
|
||||
|
||||
m_inputValues[inputRep.fullAddress()] = value;
|
||||
@ -518,7 +497,7 @@ void Kernel::receive(const Message& message)
|
||||
EventLoop::call(
|
||||
[this, address=1 + switchRequest.fullAddress(), on=switchRequest.on()]()
|
||||
{
|
||||
Log::log(m_logId, LogMessage::D2008_OUTPUT_X_IS_X, address, on ? std::string_view{"1"} : std::string_view{"0"});
|
||||
Log::log(logId, LogMessage::D2008_OUTPUT_X_IS_X, address, on ? std::string_view{"1"} : std::string_view{"0"});
|
||||
});
|
||||
|
||||
m_outputValues[switchRequest.fullAddress()] = on;
|
||||
@ -615,7 +594,7 @@ void Kernel::receive(const Message& message)
|
||||
EventLoop::call(
|
||||
[this]()
|
||||
{
|
||||
Log::log(m_logId, LogMessage::C2004_CANT_GET_FREE_SLOT);
|
||||
Log::log(logId, LogMessage::C2004_CANT_GET_FREE_SLOT);
|
||||
});
|
||||
}
|
||||
else if(longAck.respondingOpCode() == OPC_RQ_SL_DATA && longAck.ack1 == 0 && lastSentMessage().opCode == OPC_RQ_SL_DATA)
|
||||
@ -627,7 +606,7 @@ void Kernel::receive(const Message& message)
|
||||
EventLoop::call(
|
||||
[this, slot]()
|
||||
{
|
||||
Log::log(m_logId, LogMessage::W2006_COMMAND_STATION_DOES_NOT_SUPPORT_LOCO_SLOT_X, slot);
|
||||
Log::log(logId, LogMessage::W2006_COMMAND_STATION_DOES_NOT_SUPPORT_LOCO_SLOT_X, slot);
|
||||
});
|
||||
}
|
||||
else if(slot == SLOT_FAST_CLOCK)
|
||||
@ -639,9 +618,9 @@ void Kernel::receive(const Message& message)
|
||||
EventLoop::call(
|
||||
[this, stoppedFastClockSyncTimer=m_config.fastClockSyncEnabled]()
|
||||
{
|
||||
Log::log(m_logId, LogMessage::W2007_COMMAND_STATION_DOES_NOT_SUPPORT_THE_FAST_CLOCK_SLOT);
|
||||
Log::log(logId, LogMessage::W2007_COMMAND_STATION_DOES_NOT_SUPPORT_THE_FAST_CLOCK_SLOT);
|
||||
if(stoppedFastClockSyncTimer)
|
||||
Log::log(m_logId, LogMessage::N2003_STOPPED_SENDING_FAST_CLOCK_SYNC);
|
||||
Log::log(logId, LogMessage::N2003_STOPPED_SENDING_FAST_CLOCK_SYNC);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -911,13 +890,6 @@ void Kernel::receive(const Message& message)
|
||||
}
|
||||
}
|
||||
|
||||
void Kernel::error()
|
||||
{
|
||||
assert(isEventLoopThread());
|
||||
if(m_onError)
|
||||
m_onError();
|
||||
}
|
||||
|
||||
void Kernel::setPowerOn(bool value)
|
||||
{
|
||||
assert(isEventLoopThread());
|
||||
@ -1401,7 +1373,7 @@ void Kernel::sendNextMessage()
|
||||
const Message& message = m_sendQueue[priority].front();
|
||||
|
||||
if(m_config.debugLogRXTX)
|
||||
EventLoop::call([this, msg=toString(message)](){ Log::log(m_logId, LogMessage::D2001_TX_X, msg); });
|
||||
EventLoop::call([this, msg=toString(message)](){ Log::log(logId, LogMessage::D2001_TX_X, msg); });
|
||||
|
||||
if(m_ioHandler->send(message))
|
||||
{
|
||||
@ -1435,7 +1407,7 @@ void Kernel::waitingForEchoTimerExpired(const boost::system::error_code& ec)
|
||||
EventLoop::call(
|
||||
[this]()
|
||||
{
|
||||
Log::log(m_logId, LogMessage::W2018_TIMEOUT_NO_ECHO_WITHIN_X_MS, m_config.echoTimeout);
|
||||
Log::log(logId, LogMessage::W2018_TIMEOUT_NO_ECHO_WITHIN_X_MS, m_config.echoTimeout);
|
||||
});
|
||||
}
|
||||
|
||||
@ -1451,7 +1423,7 @@ void Kernel::waitingForResponseTimerExpired(const boost::system::error_code& ec)
|
||||
EventLoop::call(
|
||||
[this, lncvStart=static_cast<const Uhlenbrock::LNCVStart&>(lastSentMessage())]()
|
||||
{
|
||||
Log::log(m_logId, LogMessage::N2002_NO_RESPONSE_FROM_LNCV_MODULE_X_WITH_ADDRESS_X, lncvStart.moduleId(), lncvStart.address());
|
||||
Log::log(logId, LogMessage::N2002_NO_RESPONSE_FROM_LNCV_MODULE_X_WITH_ADDRESS_X, lncvStart.moduleId(), lncvStart.address());
|
||||
|
||||
if(m_onLNCVReadResponse && m_lncvModuleId == lncvStart.moduleId())
|
||||
m_onLNCVReadResponse(false, lncvStart.address(), 0);
|
||||
@ -1464,7 +1436,7 @@ void Kernel::waitingForResponseTimerExpired(const boost::system::error_code& ec)
|
||||
EventLoop::call(
|
||||
[this]()
|
||||
{
|
||||
Log::log(m_logId, LogMessage::E2019_TIMEOUT_NO_RESPONSE_WITHIN_X_MS, m_config.responseTimeout);
|
||||
Log::log(logId, LogMessage::E2019_TIMEOUT_NO_RESPONSE_WITHIN_X_MS, m_config.responseTimeout);
|
||||
error();
|
||||
});
|
||||
}
|
||||
@ -1579,11 +1551,11 @@ void Kernel::startPCAP(PCAPOutput pcapOutput)
|
||||
{
|
||||
case PCAPOutput::File:
|
||||
{
|
||||
const auto filename = m_debugDir / m_logId += dateTimeStr() += ".pcap";
|
||||
const auto filename = m_debugDir / logId += dateTimeStr() += ".pcap";
|
||||
EventLoop::call(
|
||||
[this, filename]()
|
||||
{
|
||||
Log::log(m_logId, LogMessage::N2004_STARTING_PCAP_FILE_LOG_X, filename);
|
||||
Log::log(logId, LogMessage::N2004_STARTING_PCAP_FILE_LOG_X, filename);
|
||||
});
|
||||
m_pcap = std::make_unique<PCAPFile>(filename, DLT_USER0);
|
||||
break;
|
||||
@ -1594,12 +1566,12 @@ void Kernel::startPCAP(PCAPOutput pcapOutput)
|
||||
#ifdef WIN32
|
||||
return; //! \todo Implement
|
||||
#else // unix
|
||||
pipe = std::filesystem::temp_directory_path() / "traintastic-server" / m_logId;
|
||||
pipe = std::filesystem::temp_directory_path() / "traintastic-server" / logId;
|
||||
#endif
|
||||
EventLoop::call(
|
||||
[this, pipe]()
|
||||
{
|
||||
Log::log(m_logId, LogMessage::N2005_STARTING_PCAP_LOG_PIPE_X, pipe);
|
||||
Log::log(logId, LogMessage::N2005_STARTING_PCAP_LOG_PIPE_X, pipe);
|
||||
});
|
||||
m_pcap = std::make_unique<PCAPPipe>(std::move(pipe), DLT_USER0);
|
||||
break;
|
||||
@ -1611,7 +1583,7 @@ void Kernel::startPCAP(PCAPOutput pcapOutput)
|
||||
EventLoop::call(
|
||||
[this, what=std::string(e.what())]()
|
||||
{
|
||||
Log::log(m_logId, LogMessage::E2021_STARTING_PCAP_LOG_FAILED_X, what);
|
||||
Log::log(logId, LogMessage::E2021_STARTING_PCAP_LOG_FAILED_X, what);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
#ifndef TRAINTASTIC_SERVER_HARDWARE_PROTOCOL_LOCONET_KERNEL_HPP
|
||||
#define TRAINTASTIC_SERVER_HARDWARE_PROTOCOL_LOCONET_KERNEL_HPP
|
||||
|
||||
#include "../kernelbase.hpp"
|
||||
#include <array>
|
||||
#include <unordered_map>
|
||||
#include <thread>
|
||||
@ -50,7 +51,7 @@ namespace LocoNet {
|
||||
|
||||
struct Message;
|
||||
|
||||
class Kernel
|
||||
class Kernel : public ::KernelBase
|
||||
{
|
||||
public:
|
||||
using OnLNCVReadResponse = std::function<void(bool, uint16_t, uint16_t)>;
|
||||
@ -141,9 +142,6 @@ class Kernel
|
||||
std::unique_ptr<IOHandler> m_ioHandler;
|
||||
const bool m_simulation;
|
||||
std::thread m_thread;
|
||||
std::string m_logId;
|
||||
std::function<void()> m_onStarted;
|
||||
std::function<void()> m_onError;
|
||||
|
||||
std::array<SendQueue, 3> m_sendQueue;
|
||||
Priority m_sentMessagePriority;
|
||||
@ -187,11 +185,8 @@ class Kernel
|
||||
std::unique_ptr<PCAP> m_pcap;
|
||||
|
||||
Config m_config;
|
||||
#ifndef NDEBUG
|
||||
bool m_started;
|
||||
#endif
|
||||
|
||||
Kernel(const Config& config, bool simulation);
|
||||
Kernel(std::string logId_, const Config& config, bool simulation);
|
||||
|
||||
LocoSlot* getLocoSlot(uint8_t slot, bool sendSlotDataRequestIfNew = true);
|
||||
LocoSlot* getLocoSlotByAddress(uint16_t address);
|
||||
@ -295,10 +290,10 @@ class Kernel
|
||||
* @return The kernel instance
|
||||
*/
|
||||
template<class IOHandlerType, class... Args>
|
||||
static std::unique_ptr<Kernel> create(const Config& config, Args... args)
|
||||
static std::unique_ptr<Kernel> create(std::string logId_, const Config& config, Args... args)
|
||||
{
|
||||
static_assert(std::is_base_of_v<IOHandler, IOHandlerType>);
|
||||
std::unique_ptr<Kernel> kernel{new Kernel(config, isSimulation<IOHandlerType>())};
|
||||
std::unique_ptr<Kernel> kernel{new Kernel(std::move(logId_), config, isSimulation<IOHandlerType>())};
|
||||
kernel->setIOHandler(std::make_unique<IOHandlerType>(*kernel, std::forward<Args>(args)...));
|
||||
return kernel;
|
||||
}
|
||||
@ -316,20 +311,6 @@ class Kernel
|
||||
return static_cast<T&>(*m_ioHandler);
|
||||
}
|
||||
|
||||
/// @brief Get object id used for log messages
|
||||
/// @return The object id
|
||||
inline const std::string& logId()
|
||||
{
|
||||
return m_logId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set object id used for log messages
|
||||
*
|
||||
* @param[in] value The object id
|
||||
*/
|
||||
void setLogId(std::string value) { m_logId = std::move(value); }
|
||||
|
||||
/**
|
||||
* @brief Set LocoNet configuration
|
||||
*
|
||||
@ -337,24 +318,6 @@ class Kernel
|
||||
*/
|
||||
void setConfig(const Config& config);
|
||||
|
||||
/**
|
||||
* @brief ...
|
||||
*
|
||||
* @param[in] callback ...
|
||||
* @note This function may not be called when the kernel is running.
|
||||
*/
|
||||
void setOnStarted(std::function<void()> callback);
|
||||
|
||||
/**
|
||||
* \brief Register error handler
|
||||
*
|
||||
* Once this handler is called the LocoNet communication it stopped.
|
||||
*
|
||||
* \param[in] callback Handler to call in case of an error.
|
||||
* \note This function may not be called when the kernel is running.
|
||||
*/
|
||||
void setOnError(std::function<void()> callback);
|
||||
|
||||
/**
|
||||
* @brief ...
|
||||
*
|
||||
@ -431,11 +394,6 @@ class Kernel
|
||||
*/
|
||||
void receive(const Message& message);
|
||||
|
||||
//! Must be called by the IO handler in case of a fatal error.
|
||||
//! This will put the interface in error state
|
||||
//! \note This function must run in the event loop thread
|
||||
void error();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
|
||||
@ -72,7 +72,7 @@ void SerialIOHandler::read()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E2002_SERIAL_READ_FAILED_X, ec);
|
||||
Log::log(m_kernel.logId, LogMessage::E2002_SERIAL_READ_FAILED_X, ec);
|
||||
m_kernel.error();
|
||||
});
|
||||
}
|
||||
@ -100,7 +100,7 @@ void SerialIOHandler::write()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E2001_SERIAL_WRITE_FAILED_X, ec);
|
||||
Log::log(m_kernel.logId, LogMessage::E2001_SERIAL_WRITE_FAILED_X, ec);
|
||||
m_kernel.error();
|
||||
});
|
||||
}
|
||||
|
||||
@ -128,7 +128,7 @@ void SocketCANIOHandler::read()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E2008_SOCKET_READ_FAILED_X, ec);
|
||||
Log::log(m_kernel.logId, LogMessage::E2008_SOCKET_READ_FAILED_X, ec);
|
||||
m_kernel.error();
|
||||
});
|
||||
}
|
||||
@ -157,7 +157,7 @@ void SocketCANIOHandler::write()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E2007_SOCKET_WRITE_FAILED_X, ec);
|
||||
Log::log(m_kernel.logId, LogMessage::E2007_SOCKET_WRITE_FAILED_X, ec);
|
||||
m_kernel.error();
|
||||
});
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@ void TCPIOHandler::read()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E2008_SOCKET_READ_FAILED_X, ec);
|
||||
Log::log(m_kernel.logId, LogMessage::E2008_SOCKET_READ_FAILED_X, ec);
|
||||
m_kernel.error();
|
||||
});
|
||||
}
|
||||
@ -118,7 +118,7 @@ void TCPIOHandler::write()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E2007_SOCKET_WRITE_FAILED_X, ec);
|
||||
Log::log(m_kernel.logId, LogMessage::E2007_SOCKET_WRITE_FAILED_X, ec);
|
||||
m_kernel.error();
|
||||
});
|
||||
}
|
||||
|
||||
@ -92,7 +92,7 @@ void UDPIOHandler::read()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E2009_SOCKET_RECEIVE_FAILED_X, ec);
|
||||
Log::log(m_kernel.logId, LogMessage::E2009_SOCKET_RECEIVE_FAILED_X, ec);
|
||||
m_kernel.error();
|
||||
});
|
||||
}
|
||||
@ -124,7 +124,7 @@ void UDPIOHandler::write()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E2011_SOCKET_SEND_FAILED_X, ec);
|
||||
Log::log(m_kernel.logId, LogMessage::E2011_SOCKET_SEND_FAILED_X, ec);
|
||||
m_kernel.error();
|
||||
});
|
||||
}
|
||||
|
||||
@ -64,15 +64,13 @@ static std::tuple<bool, DecoderProtocol, uint16_t> uidToProtocolAddress(uint32_t
|
||||
return {false, DecoderProtocol::None, 0};
|
||||
}
|
||||
|
||||
Kernel::Kernel(const Config& config, bool simulation)
|
||||
: m_ioContext{1}
|
||||
Kernel::Kernel(std::string logId_, const Config& config, bool simulation)
|
||||
: KernelBase(std::move(logId_))
|
||||
, m_ioContext{1}
|
||||
, m_simulation{simulation}
|
||||
, m_statusDataConfigRequestTimer{m_ioContext}
|
||||
, m_debugDir{Traintastic::instance->debugDir()}
|
||||
, m_config{config}
|
||||
#ifndef NDEBUG
|
||||
, m_started{false}
|
||||
#endif
|
||||
{
|
||||
assert(isEventLoopThread());
|
||||
(void)m_simulation;
|
||||
@ -92,20 +90,6 @@ void Kernel::setConfig(const Config& config)
|
||||
});
|
||||
}
|
||||
|
||||
void Kernel::setOnStarted(std::function<void()> callback)
|
||||
{
|
||||
assert(isEventLoopThread());
|
||||
assert(!m_started);
|
||||
m_onStarted = std::move(callback);
|
||||
}
|
||||
|
||||
void Kernel::setOnError(std::function<void()> callback)
|
||||
{
|
||||
assert(isEventLoopThread());
|
||||
assert(!m_started);
|
||||
m_onError = std::move(callback);
|
||||
}
|
||||
|
||||
void Kernel::setOnLocomotiveListChanged(std::function<void(const std::shared_ptr<LocomotiveList>&)> callback)
|
||||
{
|
||||
assert(isEventLoopThread());
|
||||
@ -173,7 +157,7 @@ void Kernel::start()
|
||||
EventLoop::call(
|
||||
[this, e]()
|
||||
{
|
||||
Log::log(logId(), e.message(), e.args());
|
||||
Log::log(logId, e.message(), e.args());
|
||||
error();
|
||||
});
|
||||
return;
|
||||
@ -227,7 +211,7 @@ void Kernel::receive(const Message& message)
|
||||
assert(isKernelThread());
|
||||
|
||||
if(m_config.debugLogRXTX)
|
||||
EventLoop::call([this, msg=toString(message)](){ Log::log(m_logId, LogMessage::D2002_RX_X, msg); });
|
||||
EventLoop::call([this, msg=toString(message)](){ Log::log(logId, LogMessage::D2002_RX_X, msg); });
|
||||
|
||||
switch(message.command())
|
||||
{
|
||||
@ -566,13 +550,6 @@ void Kernel::receive(const Message& message)
|
||||
}
|
||||
}
|
||||
|
||||
void Kernel::error()
|
||||
{
|
||||
assert(isEventLoopThread());
|
||||
if(m_onError)
|
||||
m_onError();
|
||||
}
|
||||
|
||||
void Kernel::systemStop()
|
||||
{
|
||||
assert(isEventLoopThread());
|
||||
@ -636,7 +613,7 @@ void Kernel::decoderChanged(const Decoder& decoder, DecoderChangeFlags changes,
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::log(m_logId, LogMessage::E2024_UNKNOWN_LOCOMOTIVE_MFX_UID_X, toHex(decoder.mfxUID.value()));
|
||||
Log::log(logId, LogMessage::E2024_UNKNOWN_LOCOMOTIVE_MFX_UID_X, toHex(decoder.mfxUID.value()));
|
||||
}
|
||||
break;
|
||||
|
||||
@ -739,7 +716,7 @@ void Kernel::send(const Message& message)
|
||||
assert(isKernelThread());
|
||||
|
||||
if(m_config.debugLogRXTX)
|
||||
EventLoop::call([this, msg=toString(message)](){ Log::log(m_logId, LogMessage::D2001_TX_X, msg); });
|
||||
EventLoop::call([this, msg=toString(message)](){ Log::log(logId, LogMessage::D2001_TX_X, msg); });
|
||||
|
||||
m_ioHandler->send(message);
|
||||
}
|
||||
@ -802,7 +779,7 @@ void Kernel::receiveStatusDataConfig(uint32_t nodeUID, uint8_t index, const std:
|
||||
|
||||
void Kernel::receiveConfigData(std::unique_ptr<ConfigDataStreamCollector> configData)
|
||||
{
|
||||
const auto basename = m_debugDir / m_logId / "configstream" / configData->name;
|
||||
const auto basename = m_debugDir / logId / "configstream" / configData->name;
|
||||
if(m_config.debugConfigStream)
|
||||
{
|
||||
writeFile(std::filesystem::path(basename).concat(".bin"), configData->bytes());
|
||||
@ -964,7 +941,7 @@ void Kernel::nodeChanged(const Node& node)
|
||||
data["configurations"] = configurations;
|
||||
}
|
||||
|
||||
writeFileJSON(m_debugDir / m_logId / "statusdataconfig" / toHex(node.uid).append(".json"), data);
|
||||
writeFileJSON(m_debugDir / logId / "statusdataconfig" / toHex(node.uid).append(".json"), data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -993,12 +970,7 @@ void Kernel::changeState(State value)
|
||||
break;
|
||||
|
||||
case State::Started:
|
||||
if(m_onStarted) /*[[likely]]*/
|
||||
EventLoop::call(
|
||||
[this]()
|
||||
{
|
||||
m_onStarted();
|
||||
});
|
||||
started();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
#ifndef TRAINTASTIC_SERVER_HARDWARE_PROTOCOL_MARKLINCAN_KERNEL_HPP
|
||||
#define TRAINTASTIC_SERVER_HARDWARE_PROTOCOL_MARKLINCAN_KERNEL_HPP
|
||||
|
||||
#include "../kernelbase.hpp"
|
||||
#include <memory>
|
||||
#include <array>
|
||||
#include <map>
|
||||
@ -49,7 +50,7 @@ namespace MarklinCAN {
|
||||
struct Message;
|
||||
class LocomotiveList;
|
||||
|
||||
class Kernel
|
||||
class Kernel : public ::KernelBase
|
||||
{
|
||||
public:
|
||||
static constexpr std::string_view nodeDeviceName = "Traintastic";
|
||||
@ -113,10 +114,7 @@ class Kernel
|
||||
std::unique_ptr<IOHandler> m_ioHandler;
|
||||
const bool m_simulation;
|
||||
std::thread m_thread;
|
||||
std::string m_logId;
|
||||
State m_state = State::Initial;
|
||||
std::function<void()> m_onStarted;
|
||||
std::function<void()> m_onError;
|
||||
std::function<void(const Node& node)> m_onNodeChanged;
|
||||
std::queue<StatusDataConfigRequest> m_statusDataConfigRequestQueue; //<! UID+index to request config data from
|
||||
int m_statusDataConfigRequestRetries = statusDataConfigRequestRetryCount;
|
||||
@ -143,11 +141,8 @@ class Kernel
|
||||
const std::filesystem::path m_debugDir;
|
||||
|
||||
Config m_config;
|
||||
#ifndef NDEBUG
|
||||
bool m_started;
|
||||
#endif
|
||||
|
||||
Kernel(const Config& config, bool simulation);
|
||||
Kernel(std::string logId_, const Config& config, bool simulation);
|
||||
|
||||
void setIOHandler(std::unique_ptr<IOHandler> handler);
|
||||
|
||||
@ -194,10 +189,10 @@ class Kernel
|
||||
* \return The kernel instance
|
||||
*/
|
||||
template<class IOHandlerType, class... Args>
|
||||
static std::unique_ptr<Kernel> create(const Config& config, Args... args)
|
||||
static std::unique_ptr<Kernel> create(std::string logId_, const Config& config, Args... args)
|
||||
{
|
||||
static_assert(std::is_base_of_v<IOHandler, IOHandlerType>);
|
||||
std::unique_ptr<Kernel> kernel{new Kernel(config, isSimulation<IOHandlerType>())};
|
||||
std::unique_ptr<Kernel> kernel{new Kernel(std::move(logId_), config, isSimulation<IOHandlerType>())};
|
||||
kernel->setIOHandler(std::make_unique<IOHandlerType>(*kernel, std::forward<Args>(args)...));
|
||||
return kernel;
|
||||
}
|
||||
@ -215,22 +210,6 @@ class Kernel
|
||||
return static_cast<T&>(*m_ioHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get object id used for log messages
|
||||
* \return The object id
|
||||
*/
|
||||
inline const std::string& logId()
|
||||
{
|
||||
return m_logId;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set object id used for log messages
|
||||
*
|
||||
* \param[in] value The object id
|
||||
*/
|
||||
void setLogId(std::string value) { m_logId = std::move(value); }
|
||||
|
||||
/**
|
||||
* \brief Set configuration
|
||||
*
|
||||
@ -238,24 +217,6 @@ class Kernel
|
||||
*/
|
||||
void setConfig(const Config& config);
|
||||
|
||||
/**
|
||||
* \brief ...
|
||||
*
|
||||
* \param[in] callback ...
|
||||
* \note This function may not be called when the kernel is running.
|
||||
*/
|
||||
void setOnStarted(std::function<void()> callback);
|
||||
|
||||
/**
|
||||
* \brief Register error handler
|
||||
*
|
||||
* Once this handler is called the LocoNet communication it stopped.
|
||||
*
|
||||
* \param[in] callback Handler to call in case of an error.
|
||||
* \note This function may not be called when the kernel is running.
|
||||
*/
|
||||
void setOnError(std::function<void()> callback);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@ -309,11 +270,6 @@ class Kernel
|
||||
*/
|
||||
void receive(const Message& message);
|
||||
|
||||
//! Must be called by the IO handler in case of a fatal error.
|
||||
//! This will put the interface in error state
|
||||
//! \note This function must run in the event loop thread
|
||||
void error();
|
||||
|
||||
void systemStop();
|
||||
void systemGo();
|
||||
void systemHalt();
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2022 Reinder Feenstra
|
||||
* Copyright (C) 2022-2023 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 +77,7 @@ void HardwareIOHandler::processRead(size_t bytesTransferred)
|
||||
EventLoop::call(
|
||||
[this, drop]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::W2001_RECEIVED_MALFORMED_DATA_DROPPED_X_BYTES, drop);
|
||||
Log::log(m_kernel.logId, LogMessage::W2001_RECEIVED_MALFORMED_DATA_DROPPED_X_BYTES, drop);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2022 Reinder Feenstra
|
||||
* Copyright (C) 2022-2023 Reinder Feenstra
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -67,8 +67,8 @@ void SerialIOHandler::read()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E2002_SERIAL_READ_FAILED_X, ec);
|
||||
// TODO interface status -> error
|
||||
Log::log(m_kernel.logId, LogMessage::E2002_SERIAL_READ_FAILED_X, ec);
|
||||
m_kernel.error();
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -95,8 +95,8 @@ void SerialIOHandler::write()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E2001_SERIAL_WRITE_FAILED_X, ec);
|
||||
// TODO interface status -> error
|
||||
Log::log(m_kernel.logId, LogMessage::E2001_SERIAL_WRITE_FAILED_X, ec);
|
||||
m_kernel.error();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@ -76,8 +76,8 @@ void TCPIOHandler::read()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E1007_SOCKET_READ_FAILED_X, ec);
|
||||
// TODO interface status -> error
|
||||
Log::log(m_kernel.logId, LogMessage::E1007_SOCKET_READ_FAILED_X, ec);
|
||||
m_kernel.error();
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -103,8 +103,8 @@ void TCPIOHandler::write()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E1006_SOCKET_WRITE_FAILED_X, ec);
|
||||
// TODO interface status -> error
|
||||
Log::log(m_kernel.logId, LogMessage::E1006_SOCKET_WRITE_FAILED_X, ec);
|
||||
m_kernel.error();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@ -71,17 +71,15 @@ constexpr TriState toTriState(OutputState value)
|
||||
return TriState::Undefined;
|
||||
}
|
||||
|
||||
Kernel::Kernel(World& world, const Config& config, bool simulation)
|
||||
: m_world{world}
|
||||
Kernel::Kernel(std::string logId_, World& world, const Config& config, bool simulation)
|
||||
: KernelBase(std::move(logId_))
|
||||
, m_world{world}
|
||||
, m_ioContext{1}
|
||||
, m_simulation{simulation}
|
||||
, m_heartbeatTimeout{m_ioContext}
|
||||
, m_inputController{nullptr}
|
||||
, m_outputController{nullptr}
|
||||
, m_config{config}
|
||||
#ifndef NDEBUG
|
||||
, m_started{false}
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
@ -129,8 +127,8 @@ void Kernel::start()
|
||||
EventLoop::call(
|
||||
[this, e]()
|
||||
{
|
||||
Log::log(logId(), e.message(), e.args());
|
||||
//! \todo error();
|
||||
Log::log(logId, e.message(), e.args());
|
||||
error();
|
||||
});
|
||||
return;
|
||||
}
|
||||
@ -140,12 +138,7 @@ void Kernel::start()
|
||||
|
||||
restartHeartbeatTimeout();
|
||||
|
||||
if(m_onStarted)
|
||||
EventLoop::call(
|
||||
[this]()
|
||||
{
|
||||
m_onStarted();
|
||||
});
|
||||
started();
|
||||
});
|
||||
|
||||
#ifndef NDEBUG
|
||||
@ -185,7 +178,7 @@ void Kernel::receive(const Message& message)
|
||||
EventLoop::call(
|
||||
[this, msg=toString(message)]()
|
||||
{
|
||||
Log::log(m_logId, LogMessage::D2002_RX_X, msg);
|
||||
Log::log(logId, LogMessage::D2002_RX_X, msg);
|
||||
});
|
||||
|
||||
restartHeartbeatTimeout();
|
||||
@ -215,7 +208,7 @@ void Kernel::receive(const Message& message)
|
||||
if(state == InputState::Invalid)
|
||||
{
|
||||
if(m_inputController->inputMap().count({InputController::defaultInputChannel, address}) != 0)
|
||||
Log::log(m_logId, LogMessage::W2004_INPUT_ADDRESS_X_IS_INVALID, address);
|
||||
Log::log(logId, LogMessage::W2004_INPUT_ADDRESS_X_IS_INVALID, address);
|
||||
}
|
||||
else
|
||||
m_inputController->updateInputValue(InputController::defaultInputChannel, address, toTriState(state));
|
||||
@ -244,7 +237,7 @@ void Kernel::receive(const Message& message)
|
||||
if(state == OutputState::Invalid)
|
||||
{
|
||||
if(m_outputController->outputMap().count({OutputController::defaultOutputChannel, address}) != 0)
|
||||
Log::log(m_logId, LogMessage::W2005_OUTPUT_ADDRESS_X_IS_INVALID, address);
|
||||
Log::log(logId, LogMessage::W2005_OUTPUT_ADDRESS_X_IS_INVALID, address);
|
||||
}
|
||||
else
|
||||
m_outputController->updateOutputValue(OutputController::defaultOutputChannel, address, toTriState(state));
|
||||
@ -394,7 +387,7 @@ void Kernel::receive(const Message& message)
|
||||
EventLoop::call(
|
||||
[this, text=std::string(info.text())]()
|
||||
{
|
||||
Log::log(m_logId, LogMessage::I2005_X, text);
|
||||
Log::log(logId, LogMessage::I2005_X, text);
|
||||
});
|
||||
break;
|
||||
}
|
||||
@ -462,7 +455,7 @@ void Kernel::send(const Message& message)
|
||||
EventLoop::call(
|
||||
[this, msg=toString(message)]()
|
||||
{
|
||||
Log::log(m_logId, LogMessage::D2001_TX_X, msg);
|
||||
Log::log(logId, LogMessage::D2001_TX_X, msg);
|
||||
});
|
||||
}
|
||||
else
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
#ifndef TRAINTASTIC_SERVER_HARDWARE_PROTOCOL_TRAINTASTICDIY_KERNEL_HPP
|
||||
#define TRAINTASTIC_SERVER_HARDWARE_PROTOCOL_TRAINTASTICDIY_KERNEL_HPP
|
||||
|
||||
#include "../kernelbase.hpp"
|
||||
#include <unordered_map>
|
||||
#include <set>
|
||||
#include <thread>
|
||||
@ -47,7 +48,7 @@ namespace TraintasticDIY {
|
||||
|
||||
struct Message;
|
||||
|
||||
class Kernel
|
||||
class Kernel : public ::KernelBase
|
||||
{
|
||||
private:
|
||||
struct DecoderSubscription
|
||||
@ -63,7 +64,6 @@ class Kernel
|
||||
std::thread m_thread;
|
||||
std::string m_logId;
|
||||
boost::asio::steady_timer m_heartbeatTimeout;
|
||||
std::function<void()> m_onStarted;
|
||||
|
||||
bool m_featureFlagsSet;
|
||||
FeatureFlags1 m_featureFlags1;
|
||||
@ -81,11 +81,8 @@ class Kernel
|
||||
std::map<std::pair<uint16_t, bool>, DecoderSubscription> m_decoderSubscriptions;
|
||||
|
||||
Config m_config;
|
||||
#ifndef NDEBUG
|
||||
bool m_started;
|
||||
#endif
|
||||
|
||||
Kernel(World& world, const Config& config, bool simulation);
|
||||
Kernel(std::string logId, World& world, const Config& config, bool simulation);
|
||||
|
||||
void setIOHandler(std::unique_ptr<IOHandler> handler);
|
||||
|
||||
@ -136,10 +133,10 @@ class Kernel
|
||||
* \return The kernel instance
|
||||
*/
|
||||
template<class IOHandlerType, class... Args>
|
||||
static std::unique_ptr<Kernel> create(World& world, const Config& config, Args... args)
|
||||
static std::unique_ptr<Kernel> create(std::string logId_, World& world, const Config& config, Args... args)
|
||||
{
|
||||
static_assert(std::is_base_of_v<IOHandler, IOHandlerType>);
|
||||
std::unique_ptr<Kernel> kernel{new Kernel(world, config, isSimulation<IOHandlerType>())};
|
||||
std::unique_ptr<Kernel> kernel{new Kernel(std::move(logId_), world, config, isSimulation<IOHandlerType>())};
|
||||
kernel->setIOHandler(std::make_unique<IOHandlerType>(*kernel, std::forward<Args>(args)...));
|
||||
return kernel;
|
||||
}
|
||||
@ -157,22 +154,6 @@ class Kernel
|
||||
return static_cast<T&>(*m_ioHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
inline const std::string& logId() { return m_logId; }
|
||||
|
||||
/**
|
||||
* \brief Set object id used for log messages
|
||||
*
|
||||
* \param[in] value The object id
|
||||
*/
|
||||
inline void setLogId(std::string value)
|
||||
{
|
||||
m_logId = std::move(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set TraintasticDIY configuration
|
||||
*
|
||||
@ -180,18 +161,6 @@ class Kernel
|
||||
*/
|
||||
void setConfig(const Config& config);
|
||||
|
||||
/**
|
||||
* \brief ...
|
||||
*
|
||||
* \param[in] callback ...
|
||||
* \note This function may not be called when the kernel is running.
|
||||
*/
|
||||
inline void setOnStarted(std::function<void()> callback)
|
||||
{
|
||||
assert(!m_started);
|
||||
m_onStarted = std::move(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the input controller
|
||||
*
|
||||
|
||||
@ -88,8 +88,9 @@ static std::string buildName(std::string name, char multiThrottleId)
|
||||
return name;
|
||||
}
|
||||
|
||||
Kernel::Kernel(const Config& config)
|
||||
: m_config{config}
|
||||
Kernel::Kernel(std::string logId_, const Config& config)
|
||||
: KernelBase(std::move(logId_))
|
||||
, m_config{config}
|
||||
{
|
||||
assert(isEventLoopThread());
|
||||
}
|
||||
@ -148,18 +149,13 @@ void Kernel::start()
|
||||
EventLoop::call(
|
||||
[this, e]()
|
||||
{
|
||||
Log::log(logId(), e.message(), e.args());
|
||||
//! \todo error();
|
||||
Log::log(logId, e.message(), e.args());
|
||||
error();
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_onStarted)
|
||||
EventLoop::call(
|
||||
[this]()
|
||||
{
|
||||
m_onStarted();
|
||||
});
|
||||
started();
|
||||
});
|
||||
}
|
||||
|
||||
@ -272,7 +268,7 @@ void Kernel::receiveFrom(std::string_view message, IOHandler::ClientId clientId)
|
||||
EventLoop::call(
|
||||
[this, clientId, msg=std::string(message)]()
|
||||
{
|
||||
Log::log(m_logId, LogMessage::D2005_X_RX_X, clientId, msg);
|
||||
Log::log(logId, LogMessage::D2005_X_RX_X, clientId, msg);
|
||||
});
|
||||
|
||||
if(message[0] == 'M') // Multi throttle command
|
||||
@ -444,7 +440,7 @@ void Kernel::sendTo(std::string_view message, IOHandler::ClientId clientId)
|
||||
EventLoop::call(
|
||||
[this, clientId, msg=std::string(message)]()
|
||||
{
|
||||
Log::log(m_logId, LogMessage::D2004_X_TX_X, clientId, msg);
|
||||
Log::log(logId, LogMessage::D2004_X_TX_X, clientId, msg);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -459,7 +455,7 @@ void Kernel::sendToAll(std::string_view message)
|
||||
EventLoop::call(
|
||||
[this, msg=std::string(message)]()
|
||||
{
|
||||
Log::log(m_logId, LogMessage::D2001_TX_X, msg);
|
||||
Log::log(logId, LogMessage::D2001_TX_X, msg);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2022 Reinder Feenstra
|
||||
* Copyright (C) 2022-2023 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 +23,7 @@
|
||||
#ifndef TRAINTASTIC_SERVER_HARDWARE_PROTOCOL_WITHROTTLE_KERNEL_HPP
|
||||
#define TRAINTASTIC_SERVER_HARDWARE_PROTOCOL_WITHROTTLE_KERNEL_HPP
|
||||
|
||||
#include "../kernelbase.hpp"
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
@ -40,7 +41,7 @@ namespace WiThrottle {
|
||||
enum class ThrottleCommand : char;
|
||||
struct Address;
|
||||
|
||||
class Kernel
|
||||
class Kernel : public ::KernelBase
|
||||
{
|
||||
private:
|
||||
struct MultiThrottle
|
||||
@ -60,8 +61,6 @@ class Kernel
|
||||
boost::asio::io_context m_ioContext;
|
||||
std::unique_ptr<IOHandler> m_ioHandler;
|
||||
std::thread m_thread;
|
||||
std::string m_logId;
|
||||
std::function<void()> m_onStarted;
|
||||
|
||||
TriState m_powerOn;
|
||||
|
||||
@ -74,7 +73,7 @@ class Kernel
|
||||
Config m_config;
|
||||
bool m_running = false;
|
||||
|
||||
Kernel(const Config& config);
|
||||
Kernel(std::string logId_, const Config& config);
|
||||
|
||||
void setIOHandler(std::unique_ptr<IOHandler> handler);
|
||||
|
||||
@ -133,30 +132,14 @@ class Kernel
|
||||
* \return The kernel instance
|
||||
*/
|
||||
template<class IOHandlerType, class... Args>
|
||||
static std::unique_ptr<Kernel> create(const Config& config, Args... args)
|
||||
static std::unique_ptr<Kernel> create(std::string logId_, const Config& config, Args... args)
|
||||
{
|
||||
static_assert(std::is_base_of_v<IOHandler, IOHandlerType>);
|
||||
std::unique_ptr<Kernel> kernel{new Kernel(config)};
|
||||
std::unique_ptr<Kernel> kernel{new Kernel(std::move(logId_), config)};
|
||||
kernel->setIOHandler(std::make_unique<IOHandlerType>(*kernel, std::forward<Args>(args)...));
|
||||
return kernel;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
inline const std::string& logId() { return m_logId; }
|
||||
|
||||
/**
|
||||
* \brief Set object id used for log messages
|
||||
*
|
||||
* \param[in] value The object id
|
||||
*/
|
||||
inline void setLogId(std::string value)
|
||||
{
|
||||
m_logId = std::move(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set WiThrottle configuration
|
||||
*
|
||||
@ -164,18 +147,6 @@ class Kernel
|
||||
*/
|
||||
void setConfig(const Config& config);
|
||||
|
||||
/**
|
||||
* \brief ...
|
||||
*
|
||||
* \param[in] callback ...
|
||||
* \note This function may not be called when the kernel is running.
|
||||
*/
|
||||
inline void setOnStarted(std::function<void()> callback)
|
||||
{
|
||||
assert(!m_running);
|
||||
m_onStarted = std::move(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set clock for LocoNet fast clock
|
||||
*
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2021-2022 Reinder Feenstra
|
||||
* Copyright (C) 2021-2023 Reinder Feenstra
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -107,7 +107,7 @@ void HardwareIOHandler::processRead(size_t bytesTransferred)
|
||||
EventLoop::call(
|
||||
[this, drop]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::W2001_RECEIVED_MALFORMED_DATA_DROPPED_X_BYTES, drop);
|
||||
Log::log(m_kernel.logId, LogMessage::W2001_RECEIVED_MALFORMED_DATA_DROPPED_X_BYTES, drop);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -67,7 +67,7 @@ void SerialIOHandler::read()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E2002_SERIAL_READ_FAILED_X, ec);
|
||||
Log::log(m_kernel.logId, LogMessage::E2002_SERIAL_READ_FAILED_X, ec);
|
||||
m_kernel.error();
|
||||
});
|
||||
}
|
||||
@ -95,7 +95,7 @@ void SerialIOHandler::write()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E2001_SERIAL_WRITE_FAILED_X, ec);
|
||||
Log::log(m_kernel.logId, LogMessage::E2001_SERIAL_WRITE_FAILED_X, ec);
|
||||
m_kernel.error();
|
||||
});
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@ void TCPIOHandler::read()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E2008_SOCKET_READ_FAILED_X, ec);
|
||||
Log::log(m_kernel.logId, LogMessage::E2008_SOCKET_READ_FAILED_X, ec);
|
||||
m_kernel.error();
|
||||
});
|
||||
}
|
||||
@ -104,7 +104,7 @@ void TCPIOHandler::write()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E2007_SOCKET_WRITE_FAILED_X, ec);
|
||||
Log::log(m_kernel.logId, LogMessage::E2007_SOCKET_WRITE_FAILED_X, ec);
|
||||
m_kernel.error();
|
||||
});
|
||||
}
|
||||
|
||||
@ -32,16 +32,14 @@
|
||||
|
||||
namespace XpressNet {
|
||||
|
||||
Kernel::Kernel(const Config& config, bool simulation)
|
||||
: m_ioContext{1}
|
||||
Kernel::Kernel(std::string logId_, const Config& config, bool simulation)
|
||||
: KernelBase(std::move(logId_))
|
||||
, m_ioContext{1}
|
||||
, m_simulation{simulation}
|
||||
, m_decoderController{nullptr}
|
||||
, m_inputController{nullptr}
|
||||
, m_outputController{nullptr}
|
||||
, m_config{config}
|
||||
#ifndef NDEBUG
|
||||
, m_started{false}
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
@ -54,13 +52,6 @@ void Kernel::setConfig(const Config& config)
|
||||
});
|
||||
}
|
||||
|
||||
void Kernel::setOnError(std::function<void()> callback)
|
||||
{
|
||||
assert(isEventLoopThread());
|
||||
assert(!m_started);
|
||||
m_onError = std::move(callback);
|
||||
}
|
||||
|
||||
void Kernel::start()
|
||||
{
|
||||
assert(m_ioHandler);
|
||||
@ -91,18 +82,13 @@ void Kernel::start()
|
||||
EventLoop::call(
|
||||
[this, e]()
|
||||
{
|
||||
Log::log(logId(), e.message(), e.args());
|
||||
Log::log(logId, e.message(), e.args());
|
||||
error();
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_onStarted)
|
||||
EventLoop::call(
|
||||
[this]()
|
||||
{
|
||||
m_onStarted();
|
||||
});
|
||||
started();
|
||||
});
|
||||
|
||||
#ifndef NDEBUG
|
||||
@ -133,7 +119,7 @@ void Kernel::receive(const Message& message)
|
||||
EventLoop::call(
|
||||
[this, msg=toString(message)]()
|
||||
{
|
||||
Log::log(m_logId, LogMessage::D2002_RX_X, msg);
|
||||
Log::log(logId, LogMessage::D2002_RX_X, msg);
|
||||
});
|
||||
|
||||
switch(message.identification())
|
||||
@ -168,7 +154,7 @@ void Kernel::receive(const Message& message)
|
||||
EventLoop::call(
|
||||
[this, address=1 + fullAddress, value]()
|
||||
{
|
||||
Log::log(m_logId, LogMessage::D2007_INPUT_X_IS_X, address, value == TriState::True ? std::string_view{"1"} : std::string_view{"0"});
|
||||
Log::log(logId, LogMessage::D2007_INPUT_X_IS_X, address, value == TriState::True ? std::string_view{"1"} : std::string_view{"0"});
|
||||
});
|
||||
|
||||
m_inputValues[fullAddress] = value;
|
||||
@ -241,13 +227,6 @@ void Kernel::receive(const Message& message)
|
||||
}
|
||||
}
|
||||
|
||||
void Kernel::error()
|
||||
{
|
||||
assert(isEventLoopThread());
|
||||
if(m_onError)
|
||||
m_onError();
|
||||
}
|
||||
|
||||
void Kernel::resumeOperations()
|
||||
{
|
||||
m_ioContext.post(
|
||||
@ -471,7 +450,7 @@ void Kernel::send(const Message& message)
|
||||
EventLoop::call(
|
||||
[this, msg=toString(message)]()
|
||||
{
|
||||
Log::log(m_logId, LogMessage::D2001_TX_X, msg);
|
||||
Log::log(logId, LogMessage::D2001_TX_X, msg);
|
||||
});
|
||||
}
|
||||
else
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
#ifndef TRAINTASTIC_SERVER_HARDWARE_PROTOCOL_XPRESSNET_KERNEL_HPP
|
||||
#define TRAINTASTIC_SERVER_HARDWARE_PROTOCOL_XPRESSNET_KERNEL_HPP
|
||||
|
||||
#include "../kernelbase.hpp"
|
||||
#include <array>
|
||||
#include <thread>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
@ -42,16 +43,13 @@ namespace XpressNet {
|
||||
|
||||
struct Message;
|
||||
|
||||
class Kernel
|
||||
class Kernel : public ::KernelBase
|
||||
{
|
||||
private:
|
||||
boost::asio::io_context m_ioContext;
|
||||
std::unique_ptr<IOHandler> m_ioHandler;
|
||||
const bool m_simulation;
|
||||
std::thread m_thread;
|
||||
std::string m_logId;
|
||||
std::function<void()> m_onStarted;
|
||||
std::function<void()> m_onError;
|
||||
|
||||
TriState m_trackPowerOn;
|
||||
TriState m_emergencyStop;
|
||||
@ -68,11 +66,8 @@ class Kernel
|
||||
//std::array<TriState, 2048> m_outputValues;
|
||||
|
||||
Config m_config;
|
||||
#ifndef NDEBUG
|
||||
bool m_started;
|
||||
#endif
|
||||
|
||||
Kernel(const Config& config, bool simulation);
|
||||
Kernel(std::string logId_, const Config& config, bool simulation);
|
||||
|
||||
void setIOHandler(std::unique_ptr<IOHandler> handler);
|
||||
|
||||
@ -110,10 +105,10 @@ class Kernel
|
||||
* @return The kernel instance
|
||||
*/
|
||||
template<class IOHandlerType, class... Args>
|
||||
static std::unique_ptr<Kernel> create(const Config& config, Args... args)
|
||||
static std::unique_ptr<Kernel> create(std::string logId_, const Config& config, Args... args)
|
||||
{
|
||||
static_assert(std::is_base_of_v<IOHandler, IOHandlerType>);
|
||||
std::unique_ptr<Kernel> kernel{new Kernel(config, isSimulation<IOHandlerType>())};
|
||||
std::unique_ptr<Kernel> kernel{new Kernel(std::move(logId_), config, isSimulation<IOHandlerType>())};
|
||||
kernel->setIOHandler(std::make_unique<IOHandlerType>(*kernel, std::forward<Args>(args)...));
|
||||
return kernel;
|
||||
}
|
||||
@ -131,22 +126,6 @@ class Kernel
|
||||
return static_cast<T&>(*m_ioHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
inline const std::string& logId() { return m_logId; }
|
||||
|
||||
/**
|
||||
* @brief Set object id used for log messages
|
||||
*
|
||||
* @param[in] value The object id
|
||||
*/
|
||||
inline void setLogId(std::string value)
|
||||
{
|
||||
m_logId = std::move(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set XpressNet configuration
|
||||
*
|
||||
@ -154,24 +133,6 @@ class Kernel
|
||||
*/
|
||||
void setConfig(const Config& config);
|
||||
|
||||
/**
|
||||
* @brief ...
|
||||
*
|
||||
* @param[in] callback ...
|
||||
* @note This function may not be called when the kernel is running.
|
||||
*/
|
||||
inline void setOnStarted(std::function<void()> callback)
|
||||
{
|
||||
assert(!m_started);
|
||||
m_onStarted = std::move(callback);
|
||||
}
|
||||
|
||||
//! \brief Register error handler
|
||||
//! Once this handler is called the XpressNet communication is stopped.
|
||||
//! \param[in] callback Handler to call in case of an error.
|
||||
//! \note This function may not be called when the kernel is running.
|
||||
void setOnError(std::function<void()> callback);
|
||||
|
||||
/**
|
||||
* @brief ...
|
||||
*
|
||||
@ -264,11 +225,6 @@ class Kernel
|
||||
*/
|
||||
void receive(const Message& message);
|
||||
|
||||
//! Must be called by the IO handler in case of a fatal error.
|
||||
//! This will put the interface in error state
|
||||
//! \note This function must run in the event loop thread
|
||||
void error();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
|
||||
@ -32,8 +32,9 @@
|
||||
|
||||
namespace Z21 {
|
||||
|
||||
ClientKernel::ClientKernel(const ClientConfig& config, bool simulation)
|
||||
: m_simulation{simulation}
|
||||
ClientKernel::ClientKernel(std::string logId_, const ClientConfig& config, bool simulation)
|
||||
: Kernel(std::move(logId_))
|
||||
, m_simulation{simulation}
|
||||
, m_keepAliveTimer(m_ioContext)
|
||||
, m_config{config}
|
||||
{
|
||||
@ -54,7 +55,7 @@ void ClientKernel::receive(const Message& message)
|
||||
EventLoop::call(
|
||||
[this, msg=toString(message)]()
|
||||
{
|
||||
Log::log(m_logId, LogMessage::D2002_RX_X, msg);
|
||||
Log::log(logId, LogMessage::D2002_RX_X, msg);
|
||||
});
|
||||
|
||||
switch(message.header())
|
||||
@ -229,7 +230,7 @@ void ClientKernel::receive(const Message& message)
|
||||
|
||||
if(m_broadcastFlags != requiredBroadcastFlags)
|
||||
{
|
||||
Log::log(m_logId, LogMessage::W2019_Z21_BROADCAST_FLAG_MISMATCH);
|
||||
Log::log(logId, LogMessage::W2019_Z21_BROADCAST_FLAG_MISMATCH);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -520,7 +521,7 @@ void ClientKernel::send(const Message& message)
|
||||
EventLoop::call(
|
||||
[this, msg=toString(message)]()
|
||||
{
|
||||
Log::log(m_logId, LogMessage::D2001_TX_X, msg);
|
||||
Log::log(logId, LogMessage::D2001_TX_X, msg);
|
||||
});
|
||||
}
|
||||
else
|
||||
@ -531,7 +532,7 @@ void ClientKernel::startKeepAliveTimer()
|
||||
{
|
||||
if(m_broadcastFlags == BroadcastFlags::None && m_broadcastFlagsRetryCount == maxBroadcastFlagsRetryCount)
|
||||
{
|
||||
Log::log(m_logId, LogMessage::W2019_Z21_BROADCAST_FLAG_MISMATCH);
|
||||
Log::log(logId, LogMessage::W2019_Z21_BROADCAST_FLAG_MISMATCH);
|
||||
m_broadcastFlagsRetryCount++; //Log only once
|
||||
}
|
||||
|
||||
|
||||
@ -96,7 +96,7 @@ class ClientKernel final : public Kernel
|
||||
|
||||
ClientConfig m_config;
|
||||
|
||||
ClientKernel(const ClientConfig& config, bool simulation);
|
||||
ClientKernel(std::string logId_, const ClientConfig& config, bool simulation);
|
||||
|
||||
void onStart() final;
|
||||
void onStop() final;
|
||||
@ -124,10 +124,10 @@ class ClientKernel final : public Kernel
|
||||
* @return The kernel instance
|
||||
*/
|
||||
template<class IOHandlerType, class... Args>
|
||||
static std::unique_ptr<ClientKernel> create(const ClientConfig& config, Args... args)
|
||||
static std::unique_ptr<ClientKernel> create(std::string logId_, const ClientConfig& config, Args... args)
|
||||
{
|
||||
static_assert(std::is_base_of_v<IOHandler, IOHandlerType>);
|
||||
std::unique_ptr<ClientKernel> kernel{new ClientKernel(config, isSimulation<IOHandlerType>())};
|
||||
std::unique_ptr<ClientKernel> kernel{new ClientKernel(std::move(logId_), config, isSimulation<IOHandlerType>())};
|
||||
kernel->setIOHandler(std::make_unique<IOHandlerType>(*kernel, std::forward<Args>(args)...));
|
||||
return kernel;
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2021-2022 Reinder Feenstra
|
||||
* Copyright (C) 2021-2023 Reinder Feenstra
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -91,7 +91,7 @@ void UDPClientIOHandler::send()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E2011_SOCKET_SEND_FAILED_X, ec);
|
||||
Log::log(m_kernel.logId, LogMessage::E2011_SOCKET_SEND_FAILED_X, ec);
|
||||
// TODO interface status -> error
|
||||
});
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2021-2022 Reinder Feenstra
|
||||
* Copyright (C) 2021-2023 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 +68,7 @@ void UDPIOHandler::receive()
|
||||
EventLoop::call(
|
||||
[this, ec]()
|
||||
{
|
||||
Log::log(m_kernel.logId(), LogMessage::E2009_SOCKET_RECEIVE_FAILED_X, ec);
|
||||
Log::log(m_kernel.logId, LogMessage::E2009_SOCKET_RECEIVE_FAILED_X, ec);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@ -33,11 +33,9 @@
|
||||
|
||||
namespace Z21 {
|
||||
|
||||
Kernel::Kernel()
|
||||
: m_ioContext{1}
|
||||
#ifndef NDEBUG
|
||||
, m_started{false}
|
||||
#endif
|
||||
Kernel::Kernel(std::string logId_)
|
||||
: KernelBase(std::move(logId_))
|
||||
, m_ioContext{1}
|
||||
{
|
||||
}
|
||||
|
||||
@ -66,20 +64,15 @@ void Kernel::start()
|
||||
EventLoop::call(
|
||||
[this, e]()
|
||||
{
|
||||
Log::log(logId(), e.message(), e.args());
|
||||
//! \todo error();
|
||||
Log::log(logId, e.message(), e.args());
|
||||
error();
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
onStart();
|
||||
|
||||
if(m_onStarted)
|
||||
EventLoop::call(
|
||||
[this]()
|
||||
{
|
||||
m_onStarted();
|
||||
});
|
||||
started();
|
||||
});
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019-2022 Reinder Feenstra
|
||||
* Copyright (C) 2019-2023 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 +23,8 @@
|
||||
#ifndef TRAINTASTIC_SERVER_HARDWARE_PROTOCOL_Z21_KERNEL_HPP
|
||||
#define TRAINTASTIC_SERVER_HARDWARE_PROTOCOL_Z21_KERNEL_HPP
|
||||
|
||||
#include "../kernelbase.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <thread>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
@ -39,21 +41,16 @@ namespace Z21 {
|
||||
struct Message;
|
||||
enum HardwareType : uint32_t;
|
||||
|
||||
class Kernel
|
||||
class Kernel : public ::KernelBase
|
||||
{
|
||||
private:
|
||||
std::thread m_thread;
|
||||
std::function<void()> m_onStarted;
|
||||
|
||||
protected:
|
||||
boost::asio::io_context m_ioContext;
|
||||
std::unique_ptr<IOHandler> m_ioHandler;
|
||||
std::string m_logId;
|
||||
#ifndef NDEBUG
|
||||
bool m_started;
|
||||
#endif
|
||||
|
||||
Kernel();
|
||||
Kernel(std::string logId_);
|
||||
virtual ~Kernel() = default;
|
||||
|
||||
void setIOHandler(std::unique_ptr<IOHandler> handler);
|
||||
@ -72,35 +69,6 @@ class Kernel
|
||||
*/
|
||||
boost::asio::io_context& ioContext() { return m_ioContext; }
|
||||
|
||||
/**
|
||||
* @brief Get object id used for log messages
|
||||
* @return The object id
|
||||
*/
|
||||
inline const std::string& logId()
|
||||
{
|
||||
return m_logId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set object id used for log messages
|
||||
* @param[in] value The object id
|
||||
*/
|
||||
inline void setLogId(std::string value)
|
||||
{
|
||||
m_logId = std::move(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ...
|
||||
* @param[in] callback ...
|
||||
* @note This function may not be called when the kernel is running.
|
||||
*/
|
||||
inline void setOnStarted(std::function<void()> callback)
|
||||
{
|
||||
assert(!m_started);
|
||||
m_onStarted = std::move(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start the kernel and IO handler
|
||||
*/
|
||||
|
||||
@ -30,8 +30,9 @@
|
||||
|
||||
namespace Z21 {
|
||||
|
||||
ServerKernel::ServerKernel(const ServerConfig& config, std::shared_ptr<DecoderList> decoderList)
|
||||
: m_inactiveClientPurgeTimer{m_ioContext}
|
||||
ServerKernel::ServerKernel(std::string logId_, const ServerConfig& config, std::shared_ptr<DecoderList> decoderList)
|
||||
: Kernel(std::move(logId_))
|
||||
, m_inactiveClientPurgeTimer{m_ioContext}
|
||||
, m_config{config}
|
||||
, m_decoderList{std::move(decoderList)}
|
||||
{
|
||||
@ -80,7 +81,7 @@ void ServerKernel::receiveFrom(const Message& message, IOHandler::ClientId clien
|
||||
EventLoop::call(
|
||||
[this, clientId, msg=toString(message)]()
|
||||
{
|
||||
Log::log(m_logId, LogMessage::D2005_X_RX_X, clientId, msg);
|
||||
Log::log(logId, LogMessage::D2005_X_RX_X, clientId, msg);
|
||||
});
|
||||
|
||||
m_clients[clientId].lastSeen = std::chrono::steady_clock::now();
|
||||
@ -306,7 +307,7 @@ void ServerKernel::sendTo(const Message& message, IOHandler::ClientId clientId)
|
||||
EventLoop::call(
|
||||
[this, clientId, msg=toString(message)]()
|
||||
{
|
||||
Log::log(m_logId, LogMessage::D2004_X_TX_X, clientId, msg);
|
||||
Log::log(logId, LogMessage::D2004_X_TX_X, clientId, msg);
|
||||
});
|
||||
}
|
||||
else
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the traintastic source code.
|
||||
*
|
||||
* Copyright (C) 2019-2022 Reinder Feenstra
|
||||
* Copyright (C) 2019-2023 Reinder Feenstra
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -63,7 +63,7 @@ class ServerKernel final : public Kernel
|
||||
TriState m_emergencyStop = TriState::Undefined;
|
||||
std::function<void()> m_onEmergencyStop;
|
||||
|
||||
ServerKernel(const ServerConfig& config, std::shared_ptr<DecoderList> decoderList);
|
||||
ServerKernel(std::string logId_, const ServerConfig& config, std::shared_ptr<DecoderList> decoderList);
|
||||
|
||||
void onStart() final;
|
||||
void onStop() final;
|
||||
@ -101,10 +101,10 @@ class ServerKernel final : public Kernel
|
||||
* @return The kernel instance
|
||||
*/
|
||||
template<class IOHandlerType, class... Args>
|
||||
static std::unique_ptr<ServerKernel> create(const ServerConfig& config, std::shared_ptr<DecoderList> decoderList, Args... args)
|
||||
static std::unique_ptr<ServerKernel> create(std::string logId_, const ServerConfig& config, std::shared_ptr<DecoderList> decoderList, Args... args)
|
||||
{
|
||||
static_assert(std::is_base_of_v<IOHandler, IOHandlerType>);
|
||||
std::unique_ptr<ServerKernel> kernel{new ServerKernel(config, std::move(decoderList))};
|
||||
std::unique_ptr<ServerKernel> kernel{new ServerKernel(std::move(logId_), config, std::move(decoderList))};
|
||||
kernel->setIOHandler(std::make_unique<IOHandlerType>(*kernel, std::forward<Args>(args)...));
|
||||
return kernel;
|
||||
}
|
||||
|
||||
Laden…
x
In neuem Issue referenzieren
Einen Benutzer sperren