// ------------------------------------------------------- // switch state // ------------------------------------------------------- bool StateManager::switchState() { if (_next != -1 && _next != _current) { //LOG << "switching from " << _current << " to " << _next; int outcome = 0; if (_next != -1) { if (_current != -1) { deactivateState(_current, false); } _current = _next; _states[_current]->resetTimer(); //LOG << "activating: " << _states[_current]->getName(); outcome = _states[_current]->activate(); //LOG << "outcome: " << outcome; int idx = findTransition(_current, outcome); if (outcome != 0 && idx != -1) { activate(_transitions[idx].to); } else { _next = -1; } if (_states[_current]->getBehavior() == SB_TRANSIENT) { _ttl = _transitions[idx].ttl; } else { _ttl = 0.0f; } //LOG << "TTL: " << _ttl; return true; } } return false; }
void MenuSystem::doWork(void) { button_t button = m_readButton(); unsigned long elapsed = getElapsedDuration(); if (button == BUTTON_NONE) { unsigned long dur = getTimeoutDuration(); if (dur != 0 && dur < elapsed) button = BUTTON_TIMEOUT; } // Debounce: wait for last button to be released if (elapsed < 250) return; if (button != BUTTON_TIMEOUT) m_lastButton = button; if (button == BUTTON_NONE) return; //Serial.print("New button: "); //Serial.println(button, DEC); m_lastActivity = millis(); state_t newState = ST_AUTO; handler_t handler = getHandler(); if (handler != NULL) newState = handler(button); if (newState == ST_AUTO) newState = findTransition(button); setState(newState); }
// ------------------------------------------------------- // tick // ------------------------------------------------------- void StateManager::tick(float dt) { _events.reset(); if (!switchState()) { if (_current != -1) { int outcome = _states[_current]->update(dt); if (_states[_current]->getBehavior() == SB_TRANSIENT) { _states[_current]->tickTimer(dt); if (_states[_current]->getTimer() >= _ttl) { //LOG << "timer expired"; int ret = deactivateState(_current, true); int idx = findTransition(_current, outcome); if (idx != -1) { StateTransition t = _transitions[idx]; activate(t.to); } else if (ret != -1) { StateTransition t = _transitions[ret]; activate(t.to); } else { //LOG << "no next state"; _current = -1; } } } else if (_states[_current]->getBehavior() == SB_ONETIME) { int ret = deactivateState(_current, false); int idx = findTransition(_current, outcome); if (idx != -1) { activate(_transitions[idx].to); } if (ret != -1) { activate(_transitions[ret].to); } } if (outcome != 0) { int idx = findTransition(_current, outcome); if (idx != -1) { activate(_transitions[idx].to); } else { _current = -1; } } } } }
void QQuickStateGroupPrivate::setCurrentStateInternal(const QString &state, bool ignoreTrans) { Q_Q(QQuickStateGroup); if (!componentComplete) { currentState = state; return; } if (applyingState) { qmlInfo(q) << "Can't apply a state change as part of a state definition."; return; } applyingState = true; QQuickTransition *transition = ignoreTrans ? 0 : findTransition(currentState, state); if (stateChangeDebug()) { qWarning() << this << "Changing state. From" << currentState << ". To" << state; if (transition) qWarning() << " using transition" << transition->fromState() << transition->toState(); } QQuickState *oldState = 0; if (!currentState.isEmpty()) { for (int ii = 0; ii < states.count(); ++ii) { if (states.at(ii)->name() == currentState) { oldState = states.at(ii); break; } } } currentState = state; emit q->stateChanged(currentState); QQuickState *newState = 0; for (int ii = 0; ii < states.count(); ++ii) { if (states.at(ii)->name() == currentState) { newState = states.at(ii); break; } } if (oldState == 0 || newState == 0) { if (!nullState) { nullState = new QQuickState; QQml_setParent_noEvent(nullState, q); nullState->setStateGroup(q); } if (!oldState) oldState = nullState; if (!newState) newState = nullState; } newState->apply(transition, oldState); applyingState = false; //### consider removing this (don't allow state changes in transition) }
void QDeclarativeStateGroupPrivate::setCurrentStateInternal(const QString &state, bool ignoreTrans) { Q_Q(QDeclarativeStateGroup); if (!componentComplete) { currentState = state; return; } if (applyingState) { qmlInfo(q) << "Can't apply a state change as part of a state definition."; return; } applyingState = true; QDeclarativeTransition *transition = (ignoreTrans || ignoreTrans) ? 0 : findTransition(currentState, state); if (stateChangeDebug()) { qWarning() << this << "Changing state. From" << currentState << ". To" << state; if (transition) qWarning() << " using transition" << transition->fromState() << transition->toState(); } QDeclarativeState *oldState = 0; if (!currentState.isEmpty()) { for (int ii = 0; ii < states.count(); ++ii) { if (states.at(ii)->name() == currentState) { oldState = states.at(ii); break; } } } currentState = state; emit q->stateChanged(currentState); QDeclarativeState *newState = 0; for (int ii = 0; ii < states.count(); ++ii) { if (states.at(ii)->name() == currentState) { newState = states.at(ii); break; } } if (oldState == 0 || newState == 0) { if (!nullState) { nullState = new QDeclarativeState; QDeclarative_setParent_noEvent(nullState, q); } if (!oldState) oldState = nullState; if (!newState) newState = nullState; } newState->apply(q, transition, oldState); applyingState = false; if (!transition) static_cast<QDeclarativeStatePrivate*>(QObjectPrivate::get(newState))->complete(); }
int StateManager::deactivateState(int index, bool checkOutcome) { if (index != -1) { //LOG << "deactivating: " << _states[index]->getName(); int outcome = _states[index]->deactivate(); //LOG << "outcome: " << outcome; if (outcome != 0 && checkOutcome ) { return findTransition(index, outcome); } } return -1; }