hunting/application/MissionManager/src/MissionStateMachine.cpp
2024-06-26 16:18:46 +08:00

151 lines
6.4 KiB
C++

/*
* Copyright (c) 2023 Fancy Code.
* 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.
*/
#include "MissionStateMachine.h"
#include "DataProcessing.h"
#include "ILog.h"
#include "IMcuManager.h"
#include "IMissionManager.h"
#include "IStateMachine.h"
#include "McuAskBase.h"
#include "MissionManagerMakePtr.h"
#include "StatusCode.h"
#include "VStateBase.h"
#include <memory>
// #include "TopState.h"
std::shared_ptr<MissionStateMachine> &MissionStateMachine::GetInstance(std::shared_ptr<MissionStateMachine> *impl)
{
static auto instance = std::make_shared<MissionStateMachine>();
if (impl) {
instance = *impl;
}
return instance;
}
MissionStateMachine::MissionStateMachine()
{
mStartMission = IpcMission::END;
}
void MissionStateMachine::Init(void)
{
mStateMachine = std::make_shared<VStateMachineHandle>();
auto code = IStateMachine::GetInstance()->CreateStateMachine(mStateMachine);
if (!IsCodeOK(code)) {
LogError("Create state machine failed[%s].\n", code.mPrintStringCode(code));
return;
}
if (!mStateMachine->InitialStateMachine()) {
LogError("State machine init failed.\n");
return;
}
mStartMission = GetStartMission();
if (mStartMission == IpcMission::END) {
LogError("ipcmission error, will start test mode.\n");
mStartMission = IpcMission::TEST;
}
RunStateMachine(mStartMission);
}
void MissionStateMachine::UnInit(void)
{
mStateMachine->StopHandlerThread();
UnInitAllState();
mStateTree.clear();
}
StatusCode MissionStateMachine::SendStateMessage(const std::shared_ptr<VMissionData> &message)
{
std::shared_ptr<VStateMessage> msg = std::make_shared<MissionMessage>(message);
mStateMachine->SendMessage(static_cast<int>(message->mEvent), msg);
return CreateStatusCode(STATUS_CODE_OK);
}
StatusCode MissionStateMachine::MessageExecutedLater(const std::shared_ptr<VMissionData> &message,
long long &delayTimeMs)
{
std::shared_ptr<VStateMessage> msg = std::make_shared<MissionMessage>(message);
mStateMachine->MessageExecutedLater(static_cast<int>(message->mEvent), msg, delayTimeMs);
return CreateStatusCode(STATUS_CODE_OK);
}
void MissionStateMachine::DelayMessage(VStateMachineData *msg)
{
mStateMachine->DelayMessage(msg);
}
void MissionStateMachine::SwitchState(const SystemState &state)
{
mStateMachine->SwitchState(mStateTree[state].get());
}
IpcMission MissionStateMachine::GetStartMission(void)
{
class McuAskIpcMission : public McuAsk<IpcMission>, public McuAskBase
{
public:
McuAskIpcMission() : McuAskBase(McuAskBlock::BLOCK, McuAskReply::NEED_REPLY)
{
mDataReply = IpcMission::END;
}
virtual ~McuAskIpcMission() = default;
};
std::shared_ptr<VMcuAsk> ask = std::make_shared<McuAskIpcMission>();
IMcuManager::GetInstance()->GetIpcMission(ask);
return std::dynamic_pointer_cast<McuAskIpcMission>(ask)->mDataReply;
}
void MissionStateMachine::RunStateMachine(const IpcMission &mission)
{
LogInfo("Make all states and start the state machine, ipc mission = %s.\n",
IMcuManager::GetInstance()->PrintIpcMissionString(mission));
mStateTree[SystemState::TOP_STATE] = MissionManagerMakePtr::GetInstance()->CreateTopState();
mStateTree[SystemState::MISSION_STATE] = MissionManagerMakePtr::GetInstance()->CreateMissionState(mission);
mStateTree[SystemState::STORAGE_HANDLE_STATE] = MissionManagerMakePtr::GetInstance()->CreateStorageHandleState();
mStateTree[SystemState::SD_CARD_HANDLE_STATE] = MissionManagerMakePtr::GetInstance()->CreateSdCardHandleState();
mStateTree[SystemState::UPGRADE_STATE] = MissionManagerMakePtr::GetInstance()->CreateUpgradeState();
mStateTree[SystemState::MEDIA_HANDLE_STATE] = MissionManagerMakePtr::GetInstance()->CreateMediaHandleState();
mStateTree[SystemState::IDLE_STATE] = MissionManagerMakePtr::GetInstance()->CreateIdleState();
mStateMachine->StatePlus(mStateTree[SystemState::TOP_STATE].get(), nullptr);
mStateMachine->StatePlus(mStateTree[SystemState::MISSION_STATE].get(), mStateTree[SystemState::TOP_STATE].get());
mStateMachine->StatePlus(mStateTree[SystemState::STORAGE_HANDLE_STATE].get(),
mStateTree[SystemState::MISSION_STATE].get());
mStateMachine->StatePlus(mStateTree[SystemState::SD_CARD_HANDLE_STATE].get(),
mStateTree[SystemState::STORAGE_HANDLE_STATE].get());
mStateMachine->StatePlus(mStateTree[SystemState::UPGRADE_STATE].get(),
mStateTree[SystemState::MISSION_STATE].get());
mStateMachine->StatePlus(mStateTree[SystemState::MEDIA_HANDLE_STATE].get(),
mStateTree[SystemState::MISSION_STATE].get());
mStateMachine->StatePlus(mStateTree[SystemState::IDLE_STATE].get(), mStateTree[SystemState::MISSION_STATE].get());
mStateMachine->SetCurrentState(mStateTree[SystemState::TOP_STATE].get());
mStateMachine->StartStateMachine();
// /**
// * @brief The business can only be processed after the state machine is started.
// *
// */
// std::shared_ptr<VMissionData> message =
// std::make_shared<VMissionData>(static_cast<MissionEvent>(InternalStateEvent::STORAGE_HANDLE_STATE_INIT));
// SendStateMessage(message);
InitAllState();
}
void MissionStateMachine::InitAllState(void)
{
for (auto &state : mStateTree) {
std::shared_ptr<VStateBase> stateBase = std::dynamic_pointer_cast<VStateBase>(state.second);
if (stateBase) {
stateBase->StateInit();
}
}
}
void MissionStateMachine::UnInitAllState(void)
{
for (auto &state : mStateTree) {
std::shared_ptr<VStateBase> stateBase = std::dynamic_pointer_cast<VStateBase>(state.second);
if (stateBase) {
stateBase->StateUnInit();
}
}
}