/* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ //#define LOG_NDEBUG 0 #define LOG_TAG "AHierarchicalStateMachine" #include #include #include #include #include namespace android { AState::AState(const sp &parentState) : mParentState(parentState) { } AState::~AState() { } sp AState::parentState() { return mParentState; } void AState::stateEntered() { } void AState::stateExited() { } //////////////////////////////////////////////////////////////////////////////// AHierarchicalStateMachine::AHierarchicalStateMachine() { } AHierarchicalStateMachine::~AHierarchicalStateMachine() { } void AHierarchicalStateMachine::handleMessage(const sp &msg) { sp save = mState; sp cur = mState; while (cur != NULL && !cur->onMessageReceived(msg)) { // If you claim not to have handled the message you shouldn't // have called setState... CHECK(save == mState); cur = cur->parentState(); } if (cur != NULL) { return; } ALOGW("Warning message %s unhandled in root state.", msg->debugString().c_str()); } void AHierarchicalStateMachine::changeState(const sp &state) { if (state == mState) { // Quick exit for the easy case. return; } Vector > A; sp cur = mState; for (;;) { A.push(cur); if (cur == NULL) { break; } cur = cur->parentState(); } Vector > B; cur = state; for (;;) { B.push(cur); if (cur == NULL) { break; } cur = cur->parentState(); } // Remove the common tail. while (A.size() > 0 && B.size() > 0 && A.top() == B.top()) { A.pop(); B.pop(); } mState = state; for (size_t i = 0; i < A.size(); ++i) { A.editItemAt(i)->stateExited(); } for (size_t i = B.size(); i > 0;) { i--; B.editItemAt(i)->stateEntered(); } } } // namespace android