How to delay delivery of a signal until the QStateMachine returns to the state that can handle it?

27 views Asked by At

I have a state machine that should handle certain incoming signals when in certain state. Sometimes it is possible that a signal will arrive when the machine is in another state. In that case, I want to process it later.

To that end, I have made this for my first attempt:

template<typename EventType, int ErrorCode>
class TransitionWithProcessor : public TransitionSavingAddress
{
public:
    TransitionWithProcessor(QAbstractState *target, std::function<void(EventType*)> &&errorProcessor = std::function<void(EventType*)>())
        : m_Processor(errorProcessor)
    {
        setTargetState(target);
    }

protected:
    bool eventTest(QEvent *e) override
    {
        return ErrorCode == (int)e->type();
    }

    void onTransition(QEvent *e) override
    {
        TransitionSavingAddress::onTransition(e);
        if (m_Processor)
            m_Processor(static_cast<EventType *>(e));
    }

private:
    std::function<void(EventType*)> m_Processor;
};

TransitionDelaySignal::TransitionDelaySignal(QObject *sender, std::function<void(QStateMachine::SignalEvent*)> action)
    : pSource(sender),
      Action(action)
{
    // Empty
}

bool TransitionDelaySignal::eventTest(QEvent *e)
{
    if (QEvent::StateMachineSignal != e->type())
        return false;

    return static_cast<QStateMachine::SignalEvent*>(e)->sender() == pSource;
}

void TransitionDelaySignal::onTransition(QEvent *e)
{
    Action(static_cast<QStateMachine::SignalEvent*>(e));
}

As an Action, I put the incoming event into a queue, and when I enter the state, I need to send the saved event over to processing.

Only, that does not work. I get segmentation fault, I presume, due to the event being deleted somewhere earlier.

What can I do to achieve that effect correctly?

0

There are 0 answers