[Qt-interest] Qt state machine: problem while queuing multiple events

Sean Harmer sean.harmer at maps-technology.com
Wed Jun 22 15:48:40 CEST 2011


On Wednesday 22 June 2011 19:05:45 Mandeep Sandhu wrote:
> > Use two different events to trigger the "back" transitions. That is have
> > a backToS2 event and a backToS1 event. Then only post the correct event
> > depending upon what state you are in when the keypresses arrive.
> 
> I already have 2 different transitions. The problem is both of them
> react to _same_ event, i.e the 'back' event here.
> 
> So when I was in S3, I processed 2 keypress events (i.e for key
> 3)....and my SM event translator changed it to 'back' (since it got 3
> when in S3) and posted it to the machine.
> 
> Now when the SM ran next (I don't when that is though), it sees TWO
> 'back' events queued. Hence, even though the transitions are different
> the transition still happens.
> 
> Or were you suggesting posting different events altogether based on
> what my current state is? (that'll get messy in my real SM that has
> many such states/transitions).

Yes that is what I was suggesting. I use a simple template for such trivial 
events and a trivial guarded transition class:

template<int offset>
class SimpleEvent : public QEvent
{
public:
    SimpleEvent()
        : QEvent( QEvent::Type( QEvent::User + offset ) )
    {
    }
};

enum EventOffset {
    backToS1 = 2048,
    backToS2
};

typedef SimpleEvent<backToS1> BackToS1Event;
typedef SimpleEvent<backToS2> BackToS2Event;


class CustomEventTransition : public QAbstractTransition
{
public:
    // The simple single event type trigger case...
    explicit CustomEventTransition( const QEvent::Type eventType = 
QEvent::None, QState* sourceState = 0 );
    // The generalised multi event types trigger case...
    explicit CustomEventTransition( const QList<QEvent::Type> eventTypes, 
QState* sourceState = 0 );

    virtual bool eventTest( QEvent* e );
    virtual void onTransition( QEvent* e );

private:
    QList< QEvent::Type > m_eventTypes;
};


CustomEventTransition::CustomEventTransition( QEvent::Type eventType, QState* 
sourceState )
    : QAbstractTransition( sourceState ),
      m_eventTypes()
{
    m_eventTypes.append( eventType );
}

CustomEventTransition::CustomEventTransition( QList< QEvent::Type > 
eventTypes, QState* sourceState )
    : QAbstractTransition( sourceState ),
      m_eventTypes( eventTypes )
{
}

bool CustomEventTransition::eventTest( QEvent* e )
{
    QList< QEvent::Type >::const_iterator itr;
    for ( itr = m_eventTypes.constBegin(); itr != m_eventTypes.constEnd(); 
++itr )
    {
        if ( e->type() == *itr )
        {
            return true;
        }
    }

    return false;
}

void CustomEventTransition::onTransition( QEvent* e )
{
    Q_UNUSED( e );
}

If you delegate the creation of the transitions to the parent state it remains 
very neat and encapsulated.

HTH,

Sean




More information about the Qt-interest-old mailing list