FrozenCanuck / Ki

A Statechart Framework for SproutCore
http://frozencanuck.wordpress.com
Other
105 stars 7 forks source link

Event handlers in states with concurrent substates get triggered multiple times #25

Closed burrows closed 13 years ago

burrows commented 13 years ago

Consider the following statechart:

Test.statechart = Ki.Statechart.create({
  initialState: 'foo',
  foo: Ki.State.design({
    substatesAreConcurrent: YES,
    bar: Ki.State.design(),
    baz: Ki.State.design(),
    eventX: function() {
      console.log('eventX handled');
    }
  })
});

Sending the event eventX in the initial state will cause the eventX handler to be called twice. This is not what I would expect and this patch ensures that handlers are only triggered once per state.

FrozenCanuck commented 13 years ago

The behavior you are observing is intended. Each substate is completely independent of its sibling substates, and therefore each will receive eventX. If a substate can not handle eventX then its parent state is given the opportunity to handle the event. This is why eventX will get fired twice -- once because state bar can not handle eventX and once because state baz can not handle eventX. This is all based on the responder chain pattern. The parent state foo should not keep track of how many times it has been called. Rather, if you want eventX to be handled once then you have another substate to handle the event, not the parent state. This means you'll have the following:

Test.statechart = Ki.Statechart.create({
  initialState: 'foo',
  foo: Ki.State.design({
    substatesAreConcurrent: YES,
    bar: Ki.State.design(),
    baz: Ki.State.design(),
    bah: Ki.State.design({
      eventX: function() {
        console.log('eventX handled');
      }
    })
  })
});