[loconet] improved handling of power commands

Dieser Commit ist enthalten in:
Reinder Feenstra 2025-12-22 15:24:14 +01:00
Ursprung 42015e2064
Commit 35ecb8b46f
3 geänderte Dateien mit 38 neuen und 39 gelöschten Zeilen

Datei anzeigen

@ -332,19 +332,25 @@ bool LocoNetInterface::setOnline(bool& value, bool simulation)
setState(InterfaceState::Error);
online = false; // communication no longer possible
});
m_kernel->setOnGlobalPowerChanged(
[this](bool powerOn)
m_kernel->setOnStateChanged(
[this](bool powerOn, bool run)
{
if(powerOn && !contains(m_world.state.value(), WorldState::PowerOn))
if(run && !contains(m_world.state.value(), WorldState::Run))
{
m_world.run();
}
else if(powerOn && !contains(m_world.state.value(), WorldState::PowerOn))
{
m_world.powerOn();
}
else if(!powerOn && contains(m_world.state.value(), WorldState::PowerOn))
{
m_world.powerOff();
});
m_kernel->setOnIdle(
[this]()
{
if(contains(m_world.state.value(), WorldState::Run))
}
else if(!run && contains(m_world.state.value(), WorldState::Run))
{
m_world.stop();
}
});
m_kernel->setClock(m_world.clock.value());
m_kernel->setDecoderController(this);

Datei anzeigen

@ -161,18 +161,11 @@ void Kernel::setConfig(const Config& config)
});
}
void Kernel::setOnGlobalPowerChanged(std::function<void(bool)> callback)
void Kernel::setOnStateChanged(std::function<void(bool, bool)> callback)
{
assert(isEventLoopThread());
assert(!m_started);
m_onGlobalPowerChanged = std::move(callback);
}
void Kernel::setOnIdle(std::function<void()> callback)
{
assert(isEventLoopThread());
assert(!m_started);
m_onIdle = std::move(callback);
m_onStateChanged = std::move(callback);
}
void Kernel::setClock(std::shared_ptr<Clock> clock)
@ -320,8 +313,9 @@ void Kernel::receive(const Message& message)
if(m_config.debugLogRXTX)
EventLoop::call([this, msg=toString(message)](){ Log::log(logId, LogMessage::D2002_RX_X, msg); });
const bool isEcho = (message == lastSentMessage());
bool isResponse = false;
if(m_waitingForEcho && message == lastSentMessage())
if(m_waitingForEcho && isEcho)
{
m_waitingForEcho = false;
m_waitingForEchoTimer.cancel();
@ -339,41 +333,49 @@ void Kernel::receive(const Message& message)
switch(message.opCode)
{
case OPC_GPON:
if(m_globalPower != TriState::True)
if(!isEcho) // sent by another LocoNet device, not by Traintastic
{
m_globalPower = TriState::True;
if(m_onGlobalPowerChanged)
m_emergencyStop = TriState::False;
if(m_onStateChanged) [[likely]]
{
EventLoop::call(
[this]()
{
m_onGlobalPowerChanged(true);
m_onStateChanged(true, true);
});
}
EventLoop::call(std::bind_front(&Kernel::resume, this));
}
break;
case OPC_GPOFF:
if(m_globalPower != TriState::False)
if(!isEcho) // sent by another LocoNet device, not by Traintastic
{
m_globalPower = TriState::False;
if(m_onGlobalPowerChanged)
if(m_onStateChanged) [[likely]]
{
EventLoop::call(
[this]()
{
m_onGlobalPowerChanged(false);
m_onStateChanged(false, false);
});
}
}
break;
case OPC_IDLE:
if(m_emergencyStop != TriState::True)
if(!isEcho) // sent by another LocoNet device, not by Traintastic
{
m_emergencyStop = TriState::True;
if(m_onIdle)
if(m_onStateChanged) [[likely]]
{
EventLoop::call(
[this]()
{
m_onIdle();
m_onStateChanged(m_globalPower == TriState::True, false);
});
}
}
break;
@ -918,6 +920,7 @@ void Kernel::setState(bool powerOn, bool run)
}
if(run && m_emergencyStop != TriState::False)
{
m_emergencyStop = TriState::False;
EventLoop::call(std::bind_front(&Kernel::resume, this));
}
else if(!run && m_emergencyStop != TriState::True)

Datei anzeigen

@ -152,10 +152,8 @@ class Kernel : public ::KernelBase
boost::asio::steady_timer m_waitingForResponseTimer;
TriState m_globalPower;
std::function<void(bool)> m_onGlobalPowerChanged;
TriState m_emergencyStop;
std::function<void()> m_onIdle;
std::function<void(bool, bool)> m_onStateChanged;
std::shared_ptr<Clock> m_clock;
boost::signals2::connection m_clockChangeConnection;
@ -318,15 +316,7 @@ class Kernel : public ::KernelBase
* @param[in] callback ...
* @note This function may not be called when the kernel is running.
*/
void setOnGlobalPowerChanged(std::function<void(bool)> callback);
/**
* @brief ...
*
* @param[in] callback ...
* @note This function may not be called when the kernel is running.
*/
void setOnIdle(std::function<void()> callback);
void setOnStateChanged(std::function<void(bool, bool)> callback);
/**
* @brief Set clock for LocoNet fast clock