Add state machine module.
This commit is contained in:
parent
9fc61803f1
commit
08d451c882
|
@ -42,14 +42,6 @@ endif()
|
||||||
#Add macro definition
|
#Add macro definition
|
||||||
# add_definitions(-DCONFIG_FILE_PATH=\"${CONFIG_FILE_PATH}\")
|
# add_definitions(-DCONFIG_FILE_PATH=\"${CONFIG_FILE_PATH}\")
|
||||||
|
|
||||||
# Config message of libs on board
|
|
||||||
# unset(MAIN_INCLUDE_PATH CACHE)
|
|
||||||
# set(MAIN_INCLUDE_PATH "" CACHE STRING INTERNAL)
|
|
||||||
# unset(MAIN_SRC_FILE CACHE)
|
|
||||||
# set(MAIN_SRC_FILE "" CACHE STRING INTERNAL)
|
|
||||||
# unset(MAIN_LINK_LIB CACHE)
|
|
||||||
# set(MAIN_LINK_LIB "" CACHE STRING INTERNAL)
|
|
||||||
|
|
||||||
# Config message of main thread
|
# Config message of main thread
|
||||||
unset(MAIN_INCLUDE_PATH CACHE)
|
unset(MAIN_INCLUDE_PATH CACHE)
|
||||||
set(MAIN_INCLUDE_PATH "" CACHE STRING INTERNAL)
|
set(MAIN_INCLUDE_PATH "" CACHE STRING INTERNAL)
|
||||||
|
@ -85,6 +77,7 @@ endif()
|
||||||
|
|
||||||
# 添加编译目录
|
# 添加编译目录
|
||||||
# add_subdirectory(application)
|
# add_subdirectory(application)
|
||||||
|
add_subdirectory(middleware)
|
||||||
add_subdirectory(utils)
|
add_subdirectory(utils)
|
||||||
add_subdirectory(hal)
|
add_subdirectory(hal)
|
||||||
# add_subdirectory(customization)
|
# add_subdirectory(customization)
|
||||||
|
|
|
@ -7,6 +7,7 @@ set(TEST_OUTPUT_PATH "${PLATFORM_PATH}/out/test")
|
||||||
|
|
||||||
set(PROJECT_ROOT_PATH "${PLATFORM_PATH}")
|
set(PROJECT_ROOT_PATH "${PLATFORM_PATH}")
|
||||||
set(APPLICATION_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/application")
|
set(APPLICATION_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/application")
|
||||||
|
set(MIDDLEWARE_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/middleware")
|
||||||
set(UTILS_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/utils")
|
set(UTILS_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/utils")
|
||||||
set(HAL_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/hal")
|
set(HAL_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/hal")
|
||||||
set(TEST_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/test")
|
set(TEST_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/test")
|
||||||
|
|
2
middleware/CMakeLists.txt
Normal file
2
middleware/CMakeLists.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
add_subdirectory(StateMachine)
|
47
middleware/StateMachine/CMakeLists.txt
Normal file
47
middleware/StateMachine/CMakeLists.txt
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
|
||||||
|
include(${CMAKE_SOURCE_DIR}/build/global_config.cmake)
|
||||||
|
set(EXECUTABLE_OUTPUT_PATH ${EXEC_OUTPUT_PATH})
|
||||||
|
set(LIBRARY_OUTPUT_PATH ${LIBS_OUTPUT_PATH})
|
||||||
|
|
||||||
|
include_directories(
|
||||||
|
./src
|
||||||
|
./include
|
||||||
|
./src/OpenHarmony
|
||||||
|
${UTILS_SOURCE_PATH}/StatusCode/include
|
||||||
|
${UTILS_SOURCE_PATH}/Log/include
|
||||||
|
${HAL_SOURCE_PATH}/include
|
||||||
|
)
|
||||||
|
#do not rely on any other library
|
||||||
|
#link_directories(
|
||||||
|
#)
|
||||||
|
|
||||||
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
|
|
||||||
|
aux_source_directory(./src SRC_FILES)
|
||||||
|
aux_source_directory(./src/OpenHarmony SRC_FILES_OPENHARMONY)
|
||||||
|
|
||||||
|
set(TARGET_NAME StateMachine)
|
||||||
|
add_library(${TARGET_NAME} STATIC ${SRC_FILES} ${SRC_FILES_OPENHARMONY})
|
||||||
|
|
||||||
|
target_link_libraries(${TARGET_NAME} ReturnCode Log)
|
||||||
|
|
||||||
|
if ("${CLANG_TIDY_SUPPORT}" MATCHES "true")
|
||||||
|
add_custom_target(
|
||||||
|
StateMahince_code_check
|
||||||
|
COMMAND ${CLANG_TIDY_EXE}
|
||||||
|
-checks='${CLANG_TIDY_CHECKS}'
|
||||||
|
--header-filter=.*
|
||||||
|
--system-headers=false
|
||||||
|
${SRC_FILES}
|
||||||
|
${CLANG_TIDY_CONFIG}
|
||||||
|
-p ${CMAKE_SOURCE_DIR_IPCSDK}/cmake-shell-linux
|
||||||
|
WORKING_DIRECTORY ${MIDDLEWARE_SOURCE_PATH}/StateMachine
|
||||||
|
)
|
||||||
|
add_custom_command(
|
||||||
|
TARGET ${TARGET_NAME}
|
||||||
|
PRE_BUILD
|
||||||
|
COMMAND make StateMahince_code_check
|
||||||
|
WORKING_DIRECTORY ${PROJECT_ROOT_PATH}/cmake-shell-linux/
|
||||||
|
)
|
||||||
|
endif()
|
26
middleware/StateMachine/README.md
Normal file
26
middleware/StateMachine/README.md
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
# 1. 层次状态机
|
||||||
|
|
||||||
|
   层次状态机在事件队列的基础上进行状态管理,使得业务逻辑耦合度非常低。
|
||||||
|
|
||||||
|
## 1.1. 开源代码
|
||||||
|
|
||||||
|
   移植了鸿蒙开源项目当中的层次状态机代码进行二次封装改造而成。
|
||||||
|
|
||||||
|
源码目录:
|
||||||
|
|
||||||
|
```
|
||||||
|
middleware/
|
||||||
|
├── CMakeLists.txt
|
||||||
|
└── StateMachine // 状态机中间件
|
||||||
|
├── CMakeLists.txt
|
||||||
|
├── include
|
||||||
|
│ └── IStateMachine.h
|
||||||
|
├── README.md
|
||||||
|
└── src
|
||||||
|
├── IStateMachine.cpp
|
||||||
|
├── OpenHarmony // 鸿蒙开源的状态机源码目录
|
||||||
|
├── StateMachineImpl.cpp
|
||||||
|
├── StateMachineImpl.h
|
||||||
|
├── StateMachineMakePtr.cpp
|
||||||
|
└── StateMachineMakePtr.h
|
||||||
|
```
|
77
middleware/StateMachine/include/IStateMachine.h
Normal file
77
middleware/StateMachine/include/IStateMachine.h
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 JIUYILIAN Co., Ltd.
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
#ifndef I_STATE_MACHINE_H
|
||||||
|
#define I_STATE_MACHINE_H
|
||||||
|
#include "StatusCode.h"
|
||||||
|
#include <memory>
|
||||||
|
class VStateMessage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VStateMessage() = default;
|
||||||
|
virtual ~VStateMessage() = default;
|
||||||
|
};
|
||||||
|
class VStateMachineParam
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VStateMachineParam() = default;
|
||||||
|
virtual ~VStateMachineParam() = default;
|
||||||
|
virtual int GetMessageName() const = 0;
|
||||||
|
virtual const std::shared_ptr<VStateMessage> &GetMessageObj(void) const = 0;
|
||||||
|
};
|
||||||
|
class State
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit State(const std::string &name) : mStateName(name) {}
|
||||||
|
virtual ~State() = default;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void GoInState() = 0;
|
||||||
|
virtual void GoOutState() = 0;
|
||||||
|
virtual bool ExecuteStateMsg(VStateMachineParam *msg) = 0;
|
||||||
|
std::string GetStateName() { return mStateName; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string mStateName;
|
||||||
|
};
|
||||||
|
class VStateMachine
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VStateMachine() = default;
|
||||||
|
virtual ~VStateMachine() = default;
|
||||||
|
virtual bool InitialStateMachine() { return false; }
|
||||||
|
virtual void StatePlus(State *state, State *upper) {}
|
||||||
|
virtual void SetFirstState(State *firstState) {}
|
||||||
|
virtual void StartStateMachine() {}
|
||||||
|
virtual void SendMessage(int msgName) {}
|
||||||
|
virtual void StopHandlerThread() {}
|
||||||
|
virtual void SendMessage(int msgName, const std::shared_ptr<VStateMessage> &messageObj) {}
|
||||||
|
virtual void MessageExecutedLater(int msgName, const std::shared_ptr<VStateMessage> &messageObj, int64_t delayTimeMs) {}
|
||||||
|
virtual void SwitchState(State *targetState) {}
|
||||||
|
virtual void StopTimer(int timerName) {}
|
||||||
|
virtual void DelayMessage(VStateMachineParam *msg) {}
|
||||||
|
};
|
||||||
|
class IStateMachine
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IStateMachine() = default;
|
||||||
|
virtual ~IStateMachine() = default;
|
||||||
|
static std::shared_ptr<IStateMachine> &GetInstance(std::shared_ptr<IStateMachine> *impl = nullptr);
|
||||||
|
virtual const StatusCode CreateStateMachine(std::shared_ptr<VStateMachine> &stateMachine)
|
||||||
|
{
|
||||||
|
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
bool CreateStateMachine(void);
|
||||||
|
#endif
|
42
middleware/StateMachine/src/IStateMachine.cpp
Normal file
42
middleware/StateMachine/src/IStateMachine.cpp
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 JIUYILIAN Co., Ltd.
|
||||||
|
* 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 "IStateMachine.h"
|
||||||
|
#include "ILog.h"
|
||||||
|
#include <thread>
|
||||||
|
std::shared_ptr<IStateMachine> &IStateMachine::GetInstance(std::shared_ptr<IStateMachine> *impl)
|
||||||
|
{
|
||||||
|
static std::shared_ptr<IStateMachine> instance = std::make_shared<IStateMachine>();
|
||||||
|
static bool instanceChanging = false;
|
||||||
|
if (impl && false == instanceChanging)
|
||||||
|
{
|
||||||
|
instanceChanging = true;
|
||||||
|
if (instance.use_count() == 1)
|
||||||
|
{
|
||||||
|
LogInfo("Instance change succeed.\n");
|
||||||
|
instance = *impl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogError("Instance change failed, using by some one.\n");
|
||||||
|
}
|
||||||
|
instanceChanging = false;
|
||||||
|
}
|
||||||
|
if (instanceChanging)
|
||||||
|
{
|
||||||
|
static std::shared_ptr<IStateMachine> tmporaryInstance = std::make_shared<IStateMachine>();
|
||||||
|
return tmporaryInstance;
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
215
middleware/StateMachine/src/OpenHarmony/handler.cpp
Normal file
215
middleware/StateMachine/src/OpenHarmony/handler.cpp
Normal file
|
@ -0,0 +1,215 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||||
|
* 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 "handler.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include "ILog.h"
|
||||||
|
|
||||||
|
#undef LOG_TAG
|
||||||
|
#define LOG_TAG "OHWIFI_HANDLER"
|
||||||
|
|
||||||
|
// namespace OHOS {
|
||||||
|
// namespace Wifi {
|
||||||
|
Handler::Handler() : pMyQueue(nullptr), handleThread(0), isRunning(true)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Handler::~Handler()
|
||||||
|
{
|
||||||
|
LogInfo("Handler::~Handler\n");
|
||||||
|
StopHandlerThread();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Handler::InitialHandler()
|
||||||
|
{
|
||||||
|
if (handleThread != 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (pMyQueue == nullptr) {
|
||||||
|
pMyQueue = std::make_unique<MessageQueue>();
|
||||||
|
if (pMyQueue == nullptr) {
|
||||||
|
LogError("pMyQueue alloc failed.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = pthread_create(&handleThread, nullptr, RunHandleThreadFunc, this);
|
||||||
|
if (ret < 0) {
|
||||||
|
LogError("pthread_create failed.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Handler::StopHandlerThread()
|
||||||
|
{
|
||||||
|
LogInfo("Handler::StopHandlerThread\n");
|
||||||
|
if (isRunning) {
|
||||||
|
isRunning = false;
|
||||||
|
if (pMyQueue != nullptr) {
|
||||||
|
pMyQueue->StopQueueLoop();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handleThread != 0) {
|
||||||
|
pthread_join(handleThread, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *Handler::RunHandleThreadFunc(void *pInstance)
|
||||||
|
{
|
||||||
|
if (pInstance == nullptr) {
|
||||||
|
LogError("pInstance is null.\n");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Handler *pHandler = (Handler *)pInstance;
|
||||||
|
pHandler->GetAndDistributeMessage();
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Handler::GetAndDistributeMessage()
|
||||||
|
{
|
||||||
|
if (pMyQueue == nullptr) {
|
||||||
|
LogError("pMyQueue is null.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (isRunning) {
|
||||||
|
InternalMessage *msg = pMyQueue->GetNextMessage();
|
||||||
|
if (msg == nullptr) {
|
||||||
|
LogError("GetNextMessage failed.\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
DistributeMessage(msg);
|
||||||
|
MessageManage::GetInstance().ReclaimMsg(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Handler::SendMessage(InternalMessage *msg)
|
||||||
|
{
|
||||||
|
if (msg == nullptr) {
|
||||||
|
LogError("Handler::SendMessage: msg is null.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// LogInfo("Handler::SendMessage msg:%d\n", msg->GetMessageName());
|
||||||
|
MessageExecutedLater(msg, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Handler::MessageExecutedLater(InternalMessage *msg, int64_t delayTimeMs)
|
||||||
|
{
|
||||||
|
if (msg == nullptr) {
|
||||||
|
LogError("Handler::MessageExecutedLater: msg is null.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// LogInfo("Handler::MessageExecutedLater msg:%d\n", msg->GetMessageName());
|
||||||
|
int64_t delayTime = delayTimeMs;
|
||||||
|
if (delayTime < 0) {
|
||||||
|
delayTime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Obtains the current time, accurate to milliseconds. */
|
||||||
|
struct timeval curTime = {0, 0};
|
||||||
|
if (gettimeofday(&curTime, nullptr) != 0) {
|
||||||
|
LogError("gettimeofday failed.\n");
|
||||||
|
MessageManage::GetInstance().ReclaimMsg(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int64_t nowTime = static_cast<int64_t>(curTime.tv_sec) * USEC_1000 + curTime.tv_usec / USEC_1000;
|
||||||
|
|
||||||
|
MessageExecutedAtTime(msg, nowTime + delayTime);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Handler::MessageExecutedAtTime(InternalMessage *msg, int64_t execTime)
|
||||||
|
{
|
||||||
|
if (msg == nullptr) {
|
||||||
|
LogError("Handler::MessageExecutedAtTime: msg is null.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// LogInfo("Handler::MessageExecutedAtTime msg: %d\n", msg->GetMessageName());
|
||||||
|
if (pMyQueue == nullptr) {
|
||||||
|
LogError("pMyQueue is null.\n");
|
||||||
|
MessageManage::GetInstance().ReclaimMsg(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pMyQueue->AddMessageToQueue(msg, execTime) != true) {
|
||||||
|
LogError("AddMessageToQueue failed.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Handler::PlaceMessageTopOfQueue(InternalMessage *msg)
|
||||||
|
{
|
||||||
|
if (msg == nullptr) {
|
||||||
|
LogError("Handler::PlaceMessageTopOfQueue: msg is null.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// LogInfo("Handler::PlaceMessageTopOfQueue msg: %d\n", msg->GetMessageName());
|
||||||
|
if (pMyQueue == nullptr) {
|
||||||
|
LogError("pMyQueue is null.\n");
|
||||||
|
MessageManage::GetInstance().ReclaimMsg(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pMyQueue->AddMessageToQueue(msg, 0)) {
|
||||||
|
LogError("AddMessageToQueue failed.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Handler::DeleteMessageFromQueue(int messageName)
|
||||||
|
{
|
||||||
|
// LogInfo("Handler::DeleteMessageFromQueue msg is: %d\n", messageName);
|
||||||
|
if (pMyQueue == nullptr) {
|
||||||
|
LogError("pMyQueue is null.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pMyQueue->DeleteMessageFromQueue(messageName)) {
|
||||||
|
LogError("DeleteMessageFromQueue failed.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Handler::DistributeMessage(InternalMessage *msg)
|
||||||
|
{
|
||||||
|
if (msg == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ExecuteMessage(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// } // namespace Wifi
|
||||||
|
// } // namespace OHOS
|
135
middleware/StateMachine/src/OpenHarmony/handler.h
Normal file
135
middleware/StateMachine/src/OpenHarmony/handler.h
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OHOS_HANDLER_H
|
||||||
|
#define OHOS_HANDLER_H
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include "internal_message.h"
|
||||||
|
#include "message_queue.h"
|
||||||
|
|
||||||
|
// namespace OHOS {
|
||||||
|
// namespace Wifi {
|
||||||
|
const int USEC_1000 = 1000;
|
||||||
|
|
||||||
|
class Handler {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @Description : Construct a new Handler:: Handler object.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Handler();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Destroy the Handler:: Handler object.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
virtual ~Handler();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Initialize Handler
|
||||||
|
*
|
||||||
|
* @return true : Initialize Handler success, false: Initialize Handler failed.
|
||||||
|
*/
|
||||||
|
bool InitialHandler();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Thread processing function
|
||||||
|
*
|
||||||
|
* @param pInstance - Handler Instance pointer.[in]
|
||||||
|
*/
|
||||||
|
static void *RunHandleThreadFunc(void *pInstance);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description :Stop the thread for obtaining messages.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void StopHandlerThread();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Send a message and place the message in the message queue.
|
||||||
|
*
|
||||||
|
* @param msg - Message to be sent.[in]
|
||||||
|
*/
|
||||||
|
void SendMessage(InternalMessage *msg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Send a message, place the message in the message queue, and
|
||||||
|
process the message after delayTimeMs is delayed.
|
||||||
|
*
|
||||||
|
* @param msg - Message to be sent.[in]
|
||||||
|
* @param delayTimeMs - Delay Time.[in]
|
||||||
|
*/
|
||||||
|
void MessageExecutedLater(InternalMessage *msg, int64_t delayTimeMs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Send a message, place the message in the message queue, and
|
||||||
|
process the message at the execTime time point.
|
||||||
|
*
|
||||||
|
* @param msg - Message to be sent.[in]
|
||||||
|
* @param execTime - Time when a message is processed.[in]
|
||||||
|
*/
|
||||||
|
void MessageExecutedAtTime(InternalMessage *msg, int64_t execTime);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Send a message and place the message at the top of the message queue.
|
||||||
|
*
|
||||||
|
* @param msg - Message to be sent.[in]
|
||||||
|
*/
|
||||||
|
void PlaceMessageTopOfQueue(InternalMessage *msg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Delete messages from the queue.
|
||||||
|
*
|
||||||
|
* @param messageName - Name of the message to be deleted.[in]
|
||||||
|
*/
|
||||||
|
void DeleteMessageFromQueue(int messageName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Distributing Messages.
|
||||||
|
*
|
||||||
|
* @param msg - Messages to be processed.[in]
|
||||||
|
*/
|
||||||
|
void DistributeMessage(InternalMessage *msg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Invoke the ExecuteStateMsg interface of the current state
|
||||||
|
to process messages sent to the state machine. The entry/exit
|
||||||
|
of the state machine is also called, and the delayed message
|
||||||
|
is put back into queue when transitioning to a new state.
|
||||||
|
*
|
||||||
|
* @param msg - Messages.[in]
|
||||||
|
*/
|
||||||
|
virtual void ExecuteMessage(InternalMessage *msg) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Obtains messages from the message queue, distributes the
|
||||||
|
messages, and recycles the messages.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void GetAndDistributeMessage();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* message queue. */
|
||||||
|
std::unique_ptr<MessageQueue> pMyQueue;
|
||||||
|
/* Thread handle. */
|
||||||
|
pthread_t handleThread;
|
||||||
|
|
||||||
|
/* Running flag. */
|
||||||
|
bool isRunning;
|
||||||
|
};
|
||||||
|
// } // namespace Wifi
|
||||||
|
// } // namespace OHOS
|
||||||
|
#endif
|
332
middleware/StateMachine/src/OpenHarmony/internal_message.cpp
Normal file
332
middleware/StateMachine/src/OpenHarmony/internal_message.cpp
Normal file
|
@ -0,0 +1,332 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||||
|
* 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 "internal_message.h"
|
||||||
|
// #include "securec.h"
|
||||||
|
#include "ILog.h"
|
||||||
|
|
||||||
|
#undef LOG_TAG
|
||||||
|
#define LOG_TAG "OHWIFI_INTERNAL_MESSAGE"
|
||||||
|
|
||||||
|
// namespace OHOS {
|
||||||
|
// namespace Wifi {
|
||||||
|
void MessageBody::SaveIntData(int data)
|
||||||
|
{
|
||||||
|
intArray_.push_back(data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageBody::SaveStringData(std::string data)
|
||||||
|
{
|
||||||
|
stringArray_.push_back(data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MessageBody::GetIntData()
|
||||||
|
{
|
||||||
|
if (intArray_.empty()) {
|
||||||
|
LogError("intArray is null.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tmp = intArray_.front();
|
||||||
|
intArray_.pop_front();
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MessageBody::GetStringData()
|
||||||
|
{
|
||||||
|
std::string tmp;
|
||||||
|
if (stringArray_.empty()) {
|
||||||
|
LogError("stringArray is null.\n");
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = stringArray_.front();
|
||||||
|
stringArray_.pop_front();
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageBody::ClearAllData()
|
||||||
|
{
|
||||||
|
intArray_.clear();
|
||||||
|
stringArray_.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageBody::CopyMessageBody(const MessageBody &origBody)
|
||||||
|
{
|
||||||
|
intArray_.assign(origBody.intArray_.begin(), origBody.intArray_.end());
|
||||||
|
stringArray_.assign(origBody.stringArray_.begin(), origBody.stringArray_.end());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
InternalMessage::InternalMessage()
|
||||||
|
: mMsgName(0),
|
||||||
|
mParam1(0),
|
||||||
|
mParam2(0),
|
||||||
|
pNextMsg(nullptr),
|
||||||
|
mHandleTime(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
InternalMessage::~InternalMessage()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int InternalMessage::GetMessageName() const
|
||||||
|
{
|
||||||
|
return mMsgName;
|
||||||
|
}
|
||||||
|
|
||||||
|
int InternalMessage::GetParam1() const
|
||||||
|
{
|
||||||
|
return mParam1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int InternalMessage::GetParam2() const
|
||||||
|
{
|
||||||
|
return mParam2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int InternalMessage::GetIntFromMessage()
|
||||||
|
{
|
||||||
|
return mMessageBody.GetIntData();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string InternalMessage::GetStringFromMessage()
|
||||||
|
{
|
||||||
|
return mMessageBody.GetStringData();
|
||||||
|
}
|
||||||
|
|
||||||
|
const MessageBody &InternalMessage::GetMessageBody() const
|
||||||
|
{
|
||||||
|
return mMessageBody;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InternalMessage::CopyMessageBody(const MessageBody &origBody)
|
||||||
|
{
|
||||||
|
mMessageBody.CopyMessageBody(origBody);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
InternalMessage *InternalMessage::GetNextMsg() const
|
||||||
|
{
|
||||||
|
return pNextMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t InternalMessage::GetHandleTime() const
|
||||||
|
{
|
||||||
|
return mHandleTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InternalMessage::SetMessageName(int msgName)
|
||||||
|
{
|
||||||
|
mMsgName = msgName;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InternalMessage::SetParam1(int param1)
|
||||||
|
{
|
||||||
|
mParam1 = param1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InternalMessage::SetParam2(int param2)
|
||||||
|
{
|
||||||
|
mParam2 = param2;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InternalMessage::ReleaseMessageObj()
|
||||||
|
{
|
||||||
|
mMessageObj.reset();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InternalMessage::AddIntMessageBody(int data)
|
||||||
|
{
|
||||||
|
mMessageBody.SaveIntData(data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InternalMessage::AddStringMessageBody(std::string data)
|
||||||
|
{
|
||||||
|
mMessageBody.SaveStringData(data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InternalMessage::ClearMessageBody()
|
||||||
|
{
|
||||||
|
mMessageBody.ClearAllData();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InternalMessage::SetNextMsg(InternalMessage *nextMsg)
|
||||||
|
{
|
||||||
|
pNextMsg = nextMsg;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InternalMessage::SetHandleTime(int64_t time)
|
||||||
|
{
|
||||||
|
mHandleTime = time;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<MessageManage> MessageManage::msgManage;
|
||||||
|
|
||||||
|
MessageManage &MessageManage::GetInstance()
|
||||||
|
{
|
||||||
|
if (msgManage.get() == nullptr) {
|
||||||
|
msgManage = std::make_unique<MessageManage>();
|
||||||
|
}
|
||||||
|
return *msgManage;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageManage::MessageManage() : pMsgPool(nullptr), mMsgPoolSize(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
MessageManage::~MessageManage()
|
||||||
|
{
|
||||||
|
ReleasePool();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
InternalMessage *MessageManage::CreateMessage()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(mPoolMutex);
|
||||||
|
if (pMsgPool != nullptr) {
|
||||||
|
InternalMessage *m = pMsgPool;
|
||||||
|
pMsgPool = m->GetNextMsg();
|
||||||
|
m->SetNextMsg(nullptr);
|
||||||
|
mMsgPoolSize--;
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pMessage = new (std::nothrow) InternalMessage();
|
||||||
|
return pMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
InternalMessage *MessageManage::CreateMessage(const InternalMessage *orig)
|
||||||
|
{
|
||||||
|
InternalMessage *m = CreateMessage();
|
||||||
|
if (m == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
m->SetMessageName(orig->GetMessageName());
|
||||||
|
m->SetParam1(orig->GetParam1());
|
||||||
|
m->SetParam2(orig->GetParam2());
|
||||||
|
m->SetMessageObj(orig->GetMessageObj());
|
||||||
|
m->CopyMessageBody(orig->GetMessageBody());
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
InternalMessage *MessageManage::CreateMessage(int messageName)
|
||||||
|
{
|
||||||
|
InternalMessage *m = CreateMessage();
|
||||||
|
if (m == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
m->SetMessageName(messageName);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
InternalMessage *MessageManage::CreateMessage(int messageName, const std::shared_ptr<VStateMessage> &messageObj)
|
||||||
|
{
|
||||||
|
InternalMessage *m = CreateMessage();
|
||||||
|
if (m == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
m->SetMessageName(messageName);
|
||||||
|
|
||||||
|
m->SetMessageObj(messageObj);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
InternalMessage *MessageManage::CreateMessage(int messageName, int param1, int param2)
|
||||||
|
{
|
||||||
|
InternalMessage *m = CreateMessage();
|
||||||
|
if (m == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
m->SetMessageName(messageName);
|
||||||
|
m->SetParam1(param1);
|
||||||
|
m->SetParam2(param2);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
InternalMessage *MessageManage::CreateMessage(int messageName, int param1, int param2, const std::shared_ptr<VStateMessage> &messageObj)
|
||||||
|
{
|
||||||
|
InternalMessage *m = CreateMessage();
|
||||||
|
if (m == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
m->SetMessageName(messageName);
|
||||||
|
m->SetParam1(param1);
|
||||||
|
m->SetParam2(param2);
|
||||||
|
m->SetMessageObj(messageObj);
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageManage::ReclaimMsg(InternalMessage *m)
|
||||||
|
{
|
||||||
|
if (m == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m->SetMessageName(0);
|
||||||
|
m->SetParam1(0);
|
||||||
|
m->SetParam2(0);
|
||||||
|
m->ReleaseMessageObj();
|
||||||
|
m->ClearMessageBody();
|
||||||
|
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(mPoolMutex);
|
||||||
|
if (mMsgPoolSize < MAX_MSG_NUM_IN_POOL) {
|
||||||
|
m->SetNextMsg(pMsgPool);
|
||||||
|
pMsgPool = m;
|
||||||
|
mMsgPoolSize++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete m;
|
||||||
|
m = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageManage::ReleasePool()
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(mPoolMutex);
|
||||||
|
InternalMessage *current = pMsgPool;
|
||||||
|
InternalMessage *next = nullptr;
|
||||||
|
while (current != nullptr) {
|
||||||
|
next = current->GetNextMsg();
|
||||||
|
delete current;
|
||||||
|
current = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// } // namespace Wifi
|
||||||
|
// } // namespace OHOS
|
390
middleware/StateMachine/src/OpenHarmony/internal_message.h
Normal file
390
middleware/StateMachine/src/OpenHarmony/internal_message.h
Normal file
|
@ -0,0 +1,390 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OHOS_INTERNAL_MESSAGE_H
|
||||||
|
#define OHOS_INTERNAL_MESSAGE_H
|
||||||
|
#include "IStateMachine.h"
|
||||||
|
#include <cstring>
|
||||||
|
#include <list>
|
||||||
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
#include <string>
|
||||||
|
// #include <any>
|
||||||
|
|
||||||
|
// namespace OHOS {
|
||||||
|
// namespace Wifi {
|
||||||
|
const int MAX_POOL_SIZE_INIT = 50;
|
||||||
|
class MessageBody {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @Description : Save an Integer Data.
|
||||||
|
*
|
||||||
|
* @param data - Integer Data.[in]
|
||||||
|
*/
|
||||||
|
void SaveIntData(int data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Save a String Data.
|
||||||
|
*
|
||||||
|
* @param data - String Data.[in]
|
||||||
|
*/
|
||||||
|
void SaveStringData(std::string data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Get an Integer Data.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int GetIntData();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Get a String Data.
|
||||||
|
*
|
||||||
|
* @return std::string
|
||||||
|
*/
|
||||||
|
std::string GetStringData();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Clear all Data.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ClearAllData();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Copy a message body.
|
||||||
|
*
|
||||||
|
* @param origBody - Source Message Body.[in]
|
||||||
|
*/
|
||||||
|
void CopyMessageBody(const MessageBody &origBody);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* Integer data. */
|
||||||
|
std::list<int> intArray_;
|
||||||
|
/* String data. */
|
||||||
|
std::list<std::string> stringArray_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class InternalMessage : public VStateMachineParam {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @Description : Construct a new Internal Message object.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
InternalMessage();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description Destroy the Internal Message object.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
~InternalMessage();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Get message name.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int GetMessageName() const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Obtains the first parameter in the message body.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int GetParam1() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Obtains the second parameter in the message body.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int GetParam2() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Obtains Integer data from message.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int GetIntFromMessage();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Obtains Sting data from message.
|
||||||
|
*
|
||||||
|
* @return std::string
|
||||||
|
*/
|
||||||
|
std::string GetStringFromMessage();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Obtains message body.
|
||||||
|
*
|
||||||
|
* @return MessageBody&
|
||||||
|
*/
|
||||||
|
const MessageBody &GetMessageBody() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Copy message body.
|
||||||
|
*
|
||||||
|
* @param origBody - Source Message Body.[in]
|
||||||
|
*/
|
||||||
|
void CopyMessageBody(const MessageBody &origBody);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Get next message.
|
||||||
|
*
|
||||||
|
* @return InternalMessage*
|
||||||
|
*/
|
||||||
|
InternalMessage *GetNextMsg() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Obtains time.
|
||||||
|
*
|
||||||
|
* @return int64_t
|
||||||
|
*/
|
||||||
|
int64_t GetHandleTime() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Set message name.
|
||||||
|
*
|
||||||
|
* @param msgName - Message name.[in]
|
||||||
|
*/
|
||||||
|
void SetMessageName(int msgName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Set the first parameter in the message body.
|
||||||
|
*
|
||||||
|
* @param param1 - The first parameter.[in]
|
||||||
|
*/
|
||||||
|
void SetParam1(int param1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Set the second parameter in the message body.
|
||||||
|
*
|
||||||
|
* @param param2 - The second parameter.[in]
|
||||||
|
*/
|
||||||
|
void SetParam2(int param2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @DescriptionSet the Message Obj object - brief
|
||||||
|
* @tparam - T Custom type to be set
|
||||||
|
* @param messageObj - User-defined data to be set
|
||||||
|
*/
|
||||||
|
// template<typename T>
|
||||||
|
// void SetMessageObj(const T &messageObj)
|
||||||
|
// {
|
||||||
|
// mMessageObj = messageObj;
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @DescriptionSet the Message Obj object - brief
|
||||||
|
* @tparam - T Custom type to be set
|
||||||
|
* @param messageObj - User-defined data to be set
|
||||||
|
*/
|
||||||
|
// template<typename T>
|
||||||
|
// void SetMessageObj(T &&messageObj)
|
||||||
|
// {
|
||||||
|
// mMessageObj = T(messageObj);
|
||||||
|
// }
|
||||||
|
|
||||||
|
void SetMessageObj(const std::shared_ptr<VStateMessage> &messageObj)
|
||||||
|
{
|
||||||
|
mMessageObj = messageObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @DescriptionGet the Message Obj object
|
||||||
|
* @tparam - T Custom type to be set
|
||||||
|
* @param messageObj - Gets data of an actual specific object.
|
||||||
|
* @return - bool true:success false:failed
|
||||||
|
*/
|
||||||
|
// template<typename T>
|
||||||
|
// bool GetMessageObj(T &messageObj) const
|
||||||
|
// {
|
||||||
|
// messageObj = std::any_cast<const T &>(mMessageObj);
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
bool GetMessageObj(std::shared_ptr<VStateMessage> &messageObj) const
|
||||||
|
{
|
||||||
|
// TODO:
|
||||||
|
// messageObj = std::any_cast<const T &>(mMessageObj);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// const std::any &GetMessageObj(void) const
|
||||||
|
// {
|
||||||
|
// return mMessageObj;
|
||||||
|
// }
|
||||||
|
const std::shared_ptr<VStateMessage> &GetMessageObj(void) const override
|
||||||
|
{
|
||||||
|
return mMessageObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Release Message Object.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ReleaseMessageObj();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Add integer message body.
|
||||||
|
*
|
||||||
|
* @param data - Integer data.[in]
|
||||||
|
*/
|
||||||
|
void AddIntMessageBody(int data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Add string message body.
|
||||||
|
*
|
||||||
|
* @param data - String data.[in]
|
||||||
|
*/
|
||||||
|
void AddStringMessageBody(std::string data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Clear message body.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ClearMessageBody();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Sets next message.
|
||||||
|
*
|
||||||
|
* @param next - The next message.[in]
|
||||||
|
*/
|
||||||
|
void SetNextMsg(InternalMessage *nextMsg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Set the time.
|
||||||
|
*
|
||||||
|
* @param time - Time.[in]
|
||||||
|
*/
|
||||||
|
void SetHandleTime(int64_t time);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* Message Name */
|
||||||
|
int mMsgName;
|
||||||
|
/* Parameter 1 */
|
||||||
|
int mParam1;
|
||||||
|
/* Parameter 2 */
|
||||||
|
int mParam2;
|
||||||
|
/* any message obj. */
|
||||||
|
// std::any mMessageObj;
|
||||||
|
std::shared_ptr<VStateMessage> mMessageObj;
|
||||||
|
/* Message bodies that cannot be directly copied */
|
||||||
|
MessageBody mMessageBody;
|
||||||
|
/* Next message in the resource pool or message queue */
|
||||||
|
InternalMessage *pNextMsg;
|
||||||
|
/* Message execution time */
|
||||||
|
int64_t mHandleTime;
|
||||||
|
};
|
||||||
|
class MessageManage {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @Description : Obtains a single instance.
|
||||||
|
*
|
||||||
|
* @return MessageManage&
|
||||||
|
*/
|
||||||
|
static MessageManage &GetInstance();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Message obtaining function.
|
||||||
|
*
|
||||||
|
* @return InternalMessage*
|
||||||
|
*/
|
||||||
|
InternalMessage *CreateMessage();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Obtain original messages.
|
||||||
|
*
|
||||||
|
* @param orig - Original messages.[in]
|
||||||
|
* @return InternalMessage*
|
||||||
|
*/
|
||||||
|
InternalMessage *CreateMessage(const InternalMessage *orig);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Obtains the message name.
|
||||||
|
*
|
||||||
|
* @param messageName - Message name.[in]
|
||||||
|
* @return InternalMessage*
|
||||||
|
*/
|
||||||
|
InternalMessage *CreateMessage(int messageName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description :Obtaining Message Information.
|
||||||
|
*
|
||||||
|
* @param messageName - Message name.[in]
|
||||||
|
* @param messageObj - Message pointer.[in]
|
||||||
|
* @return InternalMessage*
|
||||||
|
*/
|
||||||
|
InternalMessage *CreateMessage(int messageName, const std::shared_ptr<VStateMessage> &messageObj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Obtaining Message Information.
|
||||||
|
*
|
||||||
|
* @param messageName - Message name.[in]
|
||||||
|
* @param param1 - param1.[in]
|
||||||
|
* @param param2 - param2.[in]
|
||||||
|
* @return InternalMessage*
|
||||||
|
*/
|
||||||
|
InternalMessage *CreateMessage(int messageName, int param1, int param2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Obtaining Message Information.
|
||||||
|
*
|
||||||
|
* @param messageName - Message name.[in]
|
||||||
|
* @param param1 - param1.[in]
|
||||||
|
* @param param2 - param2.[in]
|
||||||
|
* @param messageObj - Message pointer.[in]
|
||||||
|
* @return InternalMessage*
|
||||||
|
*/
|
||||||
|
InternalMessage *CreateMessage(int messageName, int param1, int param2, const std::shared_ptr<VStateMessage> &messageObj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description :Recycle message.
|
||||||
|
*
|
||||||
|
* @param m - message.[in]
|
||||||
|
*/
|
||||||
|
void ReclaimMsg(InternalMessage *m);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Release pool.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void ReleasePool();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Construct a new Message Manage object.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
MessageManage();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Destroy the Message Manage object.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
~MessageManage();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* Maximum number of messages in the message resource pool */
|
||||||
|
const int MAX_MSG_NUM_IN_POOL = 50;
|
||||||
|
/* Message resource pool */
|
||||||
|
InternalMessage *pMsgPool;
|
||||||
|
/* Number of messages in the message resource pool */
|
||||||
|
int mMsgPoolSize;
|
||||||
|
/* Mutex for operating the message resource pool */
|
||||||
|
std::mutex mPoolMutex;
|
||||||
|
static std::unique_ptr<MessageManage> msgManage;
|
||||||
|
};
|
||||||
|
// } // namespace Wifi
|
||||||
|
// } // namespace OHOS
|
||||||
|
#endif
|
190
middleware/StateMachine/src/OpenHarmony/message_queue.cpp
Normal file
190
middleware/StateMachine/src/OpenHarmony/message_queue.cpp
Normal file
|
@ -0,0 +1,190 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||||
|
* 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 "message_queue.h"
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include "ILog.h"
|
||||||
|
// #include "wifi_errcode.h"
|
||||||
|
|
||||||
|
#undef LOG_TAG
|
||||||
|
#define LOG_TAG "OHWIFI_MESSAGE_QUEUE"
|
||||||
|
|
||||||
|
// namespace OHOS {
|
||||||
|
// namespace Wifi {
|
||||||
|
MessageQueue::MessageQueue() : pMessageQueue(nullptr), mIsBlocked(false), mNeedQuit(false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
MessageQueue::~MessageQueue()
|
||||||
|
{
|
||||||
|
LogInfo("MessageQueue::~MessageQueue\n");
|
||||||
|
/* Releasing Messages in a Queue */
|
||||||
|
std::unique_lock<std::mutex> lock(mMtxQueue);
|
||||||
|
InternalMessage *current = pMessageQueue;
|
||||||
|
InternalMessage *next = nullptr;
|
||||||
|
while (current != nullptr) {
|
||||||
|
next = current->GetNextMsg();
|
||||||
|
delete current;
|
||||||
|
current = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MessageQueue::AddMessageToQueue(InternalMessage *message, int64_t handleTime)
|
||||||
|
{
|
||||||
|
if (message == nullptr) {
|
||||||
|
LogError("message is null.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mNeedQuit) {
|
||||||
|
MessageManage::GetInstance().ReclaimMsg(message);
|
||||||
|
LogError("Already quit the message queue.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
message->SetHandleTime(handleTime);
|
||||||
|
bool needWake = false;
|
||||||
|
/*
|
||||||
|
* If the queue is empty, the current message needs to be executed
|
||||||
|
* immediately, or the execution time is earlier than the queue header, the
|
||||||
|
* message is placed in the queue header and is woken up when the queue is
|
||||||
|
* blocked.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lck(mMtxQueue);
|
||||||
|
InternalMessage *pTop = pMessageQueue;
|
||||||
|
if (pTop == nullptr || handleTime == 0 || handleTime < pTop->GetHandleTime()) {
|
||||||
|
message->SetNextMsg(pTop);
|
||||||
|
pMessageQueue = message;
|
||||||
|
needWake = mIsBlocked;
|
||||||
|
/* Inserts messages in the middle of the queue based on the execution time. */
|
||||||
|
} else {
|
||||||
|
InternalMessage *pPrev = nullptr;
|
||||||
|
InternalMessage *pCurrent = pTop;
|
||||||
|
while (pCurrent != nullptr) {
|
||||||
|
pPrev = pCurrent;
|
||||||
|
pCurrent = pCurrent->GetNextMsg();
|
||||||
|
if (pCurrent == nullptr || handleTime < pCurrent->GetHandleTime()) {
|
||||||
|
message->SetNextMsg(pCurrent);
|
||||||
|
pPrev->SetNextMsg(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wake up the process. */
|
||||||
|
if (needWake) {
|
||||||
|
std::unique_lock<std::mutex> lck(mMtxBlock);
|
||||||
|
mCvQueue.notify_all();
|
||||||
|
mIsBlocked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MessageQueue::DeleteMessageFromQueue(int messageName)
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lck(mMtxQueue);
|
||||||
|
|
||||||
|
InternalMessage *pTop = pMessageQueue;
|
||||||
|
if (pTop == nullptr) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
InternalMessage *pCurrent = pTop;
|
||||||
|
while (pCurrent != nullptr) {
|
||||||
|
InternalMessage *pPrev = pCurrent;
|
||||||
|
pCurrent = pCurrent->GetNextMsg();
|
||||||
|
if ((pCurrent != nullptr) && (pCurrent->GetMessageName() == messageName)) {
|
||||||
|
InternalMessage *pNextMsg = pCurrent->GetNextMsg();
|
||||||
|
pPrev->SetNextMsg(pNextMsg);
|
||||||
|
MessageManage::GetInstance().ReclaimMsg(pCurrent);
|
||||||
|
pCurrent = pNextMsg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pTop->GetMessageName() == messageName) {
|
||||||
|
pMessageQueue = pTop->GetNextMsg();
|
||||||
|
MessageManage::GetInstance().ReclaimMsg(pTop);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
InternalMessage *MessageQueue::GetNextMessage()
|
||||||
|
{
|
||||||
|
// LogInfo("MessageQueue::GetNextMessage\n");
|
||||||
|
int nextBlockTime = 0;
|
||||||
|
|
||||||
|
while (!mNeedQuit) {
|
||||||
|
/* Obtains the current time, accurate to milliseconds. */
|
||||||
|
struct timeval curTime = {0, 0};
|
||||||
|
if (gettimeofday(&curTime, nullptr) != 0) {
|
||||||
|
LogError("gettimeofday failed.\n");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
int64_t nowTime = static_cast<int64_t>(curTime.tv_sec) * TIME_USEC_1000 + curTime.tv_usec / TIME_USEC_1000;
|
||||||
|
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lck(mMtxQueue);
|
||||||
|
InternalMessage *curMsg = pMessageQueue;
|
||||||
|
mIsBlocked = true;
|
||||||
|
if (curMsg != nullptr) {
|
||||||
|
if (nowTime < curMsg->GetHandleTime()) {
|
||||||
|
/* The execution time of the first message is not reached.
|
||||||
|
The remaining time is blocked here. */
|
||||||
|
nextBlockTime = curMsg->GetHandleTime() - nowTime;
|
||||||
|
} else {
|
||||||
|
/* Return the first message. */
|
||||||
|
mIsBlocked = false;
|
||||||
|
pMessageQueue = curMsg->GetNextMsg();
|
||||||
|
curMsg->SetNextMsg(nullptr);
|
||||||
|
return curMsg;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* If there's no message, check it every 30 seconds. */
|
||||||
|
nextBlockTime = TIME_INTERVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_lock<std::mutex> lck(mMtxBlock);
|
||||||
|
if (mIsBlocked && (!mNeedQuit)) {
|
||||||
|
if (mCvQueue.wait_for(lck, std::chrono::milliseconds(nextBlockTime)) == std::cv_status::timeout) {
|
||||||
|
// LogInfo("mCvQueue timeout.\n");
|
||||||
|
} else {
|
||||||
|
// LogInfo("Wake up.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mIsBlocked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogError("Already quit the message queue.\n");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageQueue::StopQueueLoop()
|
||||||
|
{
|
||||||
|
mNeedQuit = true;
|
||||||
|
if (mIsBlocked) {
|
||||||
|
std::unique_lock<std::mutex> lck(mMtxBlock);
|
||||||
|
mCvQueue.notify_all();
|
||||||
|
mIsBlocked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// } // namespace Wifi
|
||||||
|
// } // namespace OHOS
|
88
middleware/StateMachine/src/OpenHarmony/message_queue.h
Normal file
88
middleware/StateMachine/src/OpenHarmony/message_queue.h
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OHOS_MESSAGE_QUEUE_H
|
||||||
|
#define OHOS_MESSAGE_QUEUE_H
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <mutex>
|
||||||
|
#include "internal_message.h"
|
||||||
|
|
||||||
|
// namespace OHOS {
|
||||||
|
// namespace Wifi {
|
||||||
|
#define TIME_USEC_1000 1000
|
||||||
|
#define TIME_INTERVAL 30000
|
||||||
|
class MessageQueue {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @Description : Construct a new Message Queue object.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
MessageQueue();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Destroy the Message Queue object.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
~MessageQueue();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Inserting Messages into Queues.
|
||||||
|
*
|
||||||
|
* @param message - Message to be inserted.[in]
|
||||||
|
* @param handleTime - Message execution time.[in]
|
||||||
|
* @return true : success, false : failed.
|
||||||
|
*/
|
||||||
|
bool AddMessageToQueue(InternalMessage *message, int64_t handleTime);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Delete messages from the queue.
|
||||||
|
*
|
||||||
|
* @param messageName - Name of the message to be deleted.[in]
|
||||||
|
* @return true : success, false : failed.
|
||||||
|
*/
|
||||||
|
bool DeleteMessageFromQueue(int messageName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Obtain messages from the queue for processing.
|
||||||
|
* If no message is found, the system blocks the messages.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
InternalMessage *GetNextMessage();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Obtain messages from the queue for processing.
|
||||||
|
* If no message is found, the system blocks the messages.
|
||||||
|
*/
|
||||||
|
void StopQueueLoop();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* Message Queuing */
|
||||||
|
InternalMessage *pMessageQueue;
|
||||||
|
/* No messages to be executed, blocking */
|
||||||
|
bool mIsBlocked;
|
||||||
|
/* Exit Loop */
|
||||||
|
bool mNeedQuit;
|
||||||
|
/* Thread lock of operation queue */
|
||||||
|
std::mutex mMtxQueue;
|
||||||
|
/* Blocked thread lock */
|
||||||
|
std::mutex mMtxBlock;
|
||||||
|
/* blocking condition variable */
|
||||||
|
std::condition_variable mCvQueue;
|
||||||
|
};
|
||||||
|
// } // namespace Wifi
|
||||||
|
// } // namespace OHOS
|
||||||
|
#endif
|
34
middleware/StateMachine/src/OpenHarmony/state.cpp
Normal file
34
middleware/StateMachine/src/OpenHarmony/state.cpp
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||||
|
* 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 "IStateMachine.h"
|
||||||
|
|
||||||
|
#undef LOG_TAG
|
||||||
|
#define LOG_TAG "OHWIFI_STATE"
|
||||||
|
|
||||||
|
// namespace OHOS {
|
||||||
|
// namespace Wifi {
|
||||||
|
// State::State(const std::string &name) : mStateName(name)
|
||||||
|
// {}
|
||||||
|
|
||||||
|
// State::~State()
|
||||||
|
// {}
|
||||||
|
|
||||||
|
// std::string State::GetStateName()
|
||||||
|
// {
|
||||||
|
// return mStateName;
|
||||||
|
// }
|
||||||
|
// } // namespace Wifi
|
||||||
|
// } // namespace OHOS
|
26
middleware/StateMachine/src/OpenHarmony/state.h
Normal file
26
middleware/StateMachine/src/OpenHarmony/state.h
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OHOS_STATE_H
|
||||||
|
#define OHOS_STATE_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "message_queue.h"
|
||||||
|
|
||||||
|
// namespace OHOS {
|
||||||
|
// namespace Wifi {
|
||||||
|
// } // namespace Wifi
|
||||||
|
// } // namespace OHOS
|
||||||
|
#endif
|
686
middleware/StateMachine/src/OpenHarmony/state_machine.cpp
Normal file
686
middleware/StateMachine/src/OpenHarmony/state_machine.cpp
Normal file
|
@ -0,0 +1,686 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021-2022 Huawei Device Co., Ltd.
|
||||||
|
* 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 <inttypes.h>
|
||||||
|
#include "state_machine.h"
|
||||||
|
#include "ILog.h"
|
||||||
|
|
||||||
|
#undef LOG_TAG
|
||||||
|
#define LOG_TAG "OHWIFI_STATE_MACHINE"
|
||||||
|
|
||||||
|
// namespace OHOS {
|
||||||
|
// namespace Wifi {
|
||||||
|
static const int SM_INIT_CMD = -2;
|
||||||
|
StateMachine::StateMachine(const std::string &name) : pStateMachineHandler(nullptr), mStateName(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
StateMachine::~StateMachine()
|
||||||
|
{
|
||||||
|
LogInfo("StateMachine::~StateMachine\n");
|
||||||
|
if (pStateMachineHandler != nullptr) {
|
||||||
|
delete pStateMachineHandler;
|
||||||
|
pStateMachineHandler = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StateMachine::InitialStateMachine()
|
||||||
|
{
|
||||||
|
pStateMachineHandler = new (std::nothrow) StateMachineHandler(this);
|
||||||
|
if (pStateMachineHandler == nullptr) {
|
||||||
|
LogError("pStateMachineHandler alloc failed.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pStateMachineHandler->InitialSmHandler()) {
|
||||||
|
LogError("InitialStateMachineHandler failed.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachine::StartStateMachine()
|
||||||
|
{
|
||||||
|
if (pStateMachineHandler == nullptr) {
|
||||||
|
LogError("Start StateMachine failed, pStateMachineHandler is nullptr!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pStateMachineHandler->BuildTreeComplete();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachine::SetHandler(StateMachineHandler *handler)
|
||||||
|
{
|
||||||
|
pStateMachineHandler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachine::NotExecutedMessage(const InternalMessage *msg)
|
||||||
|
{
|
||||||
|
if (msg == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LogWarning("msg not handled msg:%d\n", msg->GetMessageName());
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachine::StatePlus(State *state, State *upper)
|
||||||
|
{
|
||||||
|
if (pStateMachineHandler == nullptr) {
|
||||||
|
LogError("Start StateMachine failed, pStateMachineHandler is nullptr!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pStateMachineHandler->StatePlus(state, upper);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachine::StateDelete(State *state)
|
||||||
|
{
|
||||||
|
if (pStateMachineHandler == nullptr) {
|
||||||
|
LogError("Start StateMachine failed, pStateMachineHandler is nullptr!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pStateMachineHandler->StateDelete(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachine::SetFirstState(State *firstState)
|
||||||
|
{
|
||||||
|
if (pStateMachineHandler == nullptr) {
|
||||||
|
LogError("Start StateMachine failed, pStateMachineHandler is nullptr!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pStateMachineHandler->SetFirstState(firstState);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachine::SwitchState(State *targetState)
|
||||||
|
{
|
||||||
|
if (pStateMachineHandler == nullptr) {
|
||||||
|
LogError("Start StateMachine failed, pStateMachineHandler is nullptr!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pStateMachineHandler->SwitchState(targetState);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachine::DelayMessage(const InternalMessage *msg)
|
||||||
|
{
|
||||||
|
if (pStateMachineHandler == nullptr) {
|
||||||
|
LogError("Start StateMachine failed, pStateMachineHandler is nullptr!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pStateMachineHandler->DelayMessage(msg);
|
||||||
|
}
|
||||||
|
void StateMachine::DelayMessage(VStateMachineParam *msg)
|
||||||
|
{
|
||||||
|
if (pStateMachineHandler == nullptr) {
|
||||||
|
LogError("Start StateMachine failed, pStateMachineHandler is nullptr!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pStateMachineHandler->DelayMessage((InternalMessage *)msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachine::StopHandlerThread()
|
||||||
|
{
|
||||||
|
if (pStateMachineHandler == nullptr) {
|
||||||
|
LogError("Start StateMachine failed, pStateMachineHandler is nullptr!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pStateMachineHandler->StopHandlerThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
InternalMessage *StateMachine::CreateMessage()
|
||||||
|
{
|
||||||
|
return MessageManage::GetInstance().CreateMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
InternalMessage *StateMachine::CreateMessage(const InternalMessage *orig)
|
||||||
|
{
|
||||||
|
if (orig == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return MessageManage::GetInstance().CreateMessage(orig);
|
||||||
|
}
|
||||||
|
|
||||||
|
InternalMessage *StateMachine::CreateMessage(int msgName)
|
||||||
|
{
|
||||||
|
return MessageManage::GetInstance().CreateMessage(msgName);
|
||||||
|
}
|
||||||
|
|
||||||
|
InternalMessage *StateMachine::CreateMessage(int msgName, int param1)
|
||||||
|
{
|
||||||
|
return MessageManage::GetInstance().CreateMessage(msgName, param1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
InternalMessage *StateMachine::CreateMessage(int msgName, int param1, int param2)
|
||||||
|
{
|
||||||
|
return MessageManage::GetInstance().CreateMessage(msgName, param1, param2);
|
||||||
|
}
|
||||||
|
|
||||||
|
InternalMessage *StateMachine::CreateMessage(int msgName, const std::shared_ptr<VStateMessage> &messageObj)
|
||||||
|
{
|
||||||
|
return MessageManage::GetInstance().CreateMessage(msgName, messageObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
InternalMessage *StateMachine::CreateMessage(int msgName, int param1, int param2, const std::shared_ptr<VStateMessage> &messageObj)
|
||||||
|
{
|
||||||
|
return MessageManage::GetInstance().CreateMessage(msgName, param1, param2, messageObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachine::SendMessage(int msgName)
|
||||||
|
{
|
||||||
|
pStateMachineHandler->SendMessage(CreateMessage(msgName));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachine::SendMessage(int msgName, int param1)
|
||||||
|
{
|
||||||
|
pStateMachineHandler->SendMessage(CreateMessage(msgName, param1));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachine::SendMessage(int msgName, int param1, int param2)
|
||||||
|
{
|
||||||
|
pStateMachineHandler->SendMessage(CreateMessage(msgName, param1, param2));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachine::SendMessage(InternalMessage *msg)
|
||||||
|
{
|
||||||
|
if (msg == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pStateMachineHandler->SendMessage(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachine::SendMessage(int msgName, const std::shared_ptr<VStateMessage> &messageObj)
|
||||||
|
{
|
||||||
|
pStateMachineHandler->SendMessage(CreateMessage(msgName, messageObj));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachine::SendMessage(int msgName, int param1, int param2, const std::shared_ptr<VStateMessage> &messageObj)
|
||||||
|
{
|
||||||
|
pStateMachineHandler->SendMessage(CreateMessage(msgName, param1, param2, messageObj));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachine::MessageExecutedLater(int msgName, int64_t delayTimeMs)
|
||||||
|
{
|
||||||
|
pStateMachineHandler->MessageExecutedLater(CreateMessage(msgName), delayTimeMs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachine::MessageExecutedLater(int msgName, int param1, int64_t delayTimeMs)
|
||||||
|
{
|
||||||
|
pStateMachineHandler->MessageExecutedLater(CreateMessage(msgName, param1), delayTimeMs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachine::MessageExecutedLater(int msgName, int param1, int param2, int64_t delayTimeMs)
|
||||||
|
{
|
||||||
|
pStateMachineHandler->MessageExecutedLater(CreateMessage(msgName, param1, param2), delayTimeMs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachine::MessageExecutedLater(InternalMessage *msg, int64_t delayTimeMs)
|
||||||
|
{
|
||||||
|
pStateMachineHandler->MessageExecutedLater(msg, delayTimeMs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachine::MessageExecutedLater(int msgName, const std::shared_ptr<VStateMessage> &messageObj, int64_t delayTimeMs)
|
||||||
|
{
|
||||||
|
pStateMachineHandler->MessageExecutedLater(CreateMessage(msgName, messageObj), delayTimeMs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachine::MessageExecutedLater(
|
||||||
|
int msgName, int param1, int param2, const std::shared_ptr<VStateMessage> &messageObj, int64_t delayTimeMs)
|
||||||
|
{
|
||||||
|
pStateMachineHandler->MessageExecutedLater(CreateMessage(msgName, param1, param2, messageObj), delayTimeMs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachine::StartTimer(int timerName, int64_t interval)
|
||||||
|
{
|
||||||
|
// LogInfo("Enter StateMachine::StartTimer, timerName is %d, interval is %d\n", timerName, interval);
|
||||||
|
MessageExecutedLater(timerName, interval);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachine::StopTimer(int timerName)
|
||||||
|
{
|
||||||
|
// LogInfo("Enter StateMachine::StopTimer, timerName is %d.\n", timerName);
|
||||||
|
pStateMachineHandler->DeleteMessageFromQueue(timerName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
StateMachineHandler::StateMachineHandler(StateMachine *pStateMgr)
|
||||||
|
{
|
||||||
|
mStateInfoMap.clear();
|
||||||
|
mStateVector.clear();
|
||||||
|
mStateVectorTopIndex = -1;
|
||||||
|
mSequenceStateVector.clear();
|
||||||
|
mSequenceStateVectorCount = 0;
|
||||||
|
mDelayedMessages.clear();
|
||||||
|
pStateMachine = pStateMgr;
|
||||||
|
pFirstState = nullptr;
|
||||||
|
pTargetState = nullptr;
|
||||||
|
mQuitFlag = false;
|
||||||
|
mBuildCompleteFlag = false;
|
||||||
|
mSwitchingStateFlag = false;
|
||||||
|
pCurrentMsg = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
StateMachineHandler::~StateMachineHandler()
|
||||||
|
{
|
||||||
|
LogInfo("StateMachineHandler::~StateMachineHandler\n");
|
||||||
|
StopHandlerThread();
|
||||||
|
ReleaseDelayedMessages();
|
||||||
|
ClearWhenQuit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StateMachineHandler::InitialSmHandler()
|
||||||
|
{
|
||||||
|
if (!InitialHandler()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
StateInfo *StateMachineHandler::StatePlus(State *state, State *upper)
|
||||||
|
{
|
||||||
|
LogInfo("Enter StateMachineHandler::StatePlus function.\n");
|
||||||
|
|
||||||
|
StateInfo *upperStateInfo = nullptr;
|
||||||
|
StateInfoMap::iterator it = mStateInfoMap.begin();
|
||||||
|
if (upper != nullptr) {
|
||||||
|
it = mStateInfoMap.find(upper->GetStateName());
|
||||||
|
if (it != mStateInfoMap.end()) {
|
||||||
|
upperStateInfo = it->second;
|
||||||
|
}
|
||||||
|
if (upperStateInfo == nullptr) {
|
||||||
|
LogInfo("upperStateInfo is null, add upper first. upper->GetStateName():%s\n",
|
||||||
|
upper->GetStateName().c_str());
|
||||||
|
/* Recursively add our upper as it's not been added yet. */
|
||||||
|
StatePlus(upper, nullptr);
|
||||||
|
} else {
|
||||||
|
LogInfo("upperStateInfo is not null, go on.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StateInfo *stateInfo = nullptr;
|
||||||
|
it = mStateInfoMap.find(state->GetStateName());
|
||||||
|
if (it != mStateInfoMap.end()) {
|
||||||
|
stateInfo = it->second;
|
||||||
|
}
|
||||||
|
if (stateInfo == nullptr) {
|
||||||
|
stateInfo = new (std::nothrow) StateInfo();
|
||||||
|
if (stateInfo == nullptr) {
|
||||||
|
LogError("failed to new StateInfo!\n");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
mStateInfoMap.insert(StateInfoMap::value_type(state->GetStateName(), stateInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate that we aren't adding the same state in two different hierarchies. */
|
||||||
|
if (stateInfo->upperStateInfo != nullptr && stateInfo->upperStateInfo != upperStateInfo) {
|
||||||
|
LogError("The same state cannot be added to two different hierarchies!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
stateInfo->state = state;
|
||||||
|
stateInfo->upperStateInfo = upperStateInfo;
|
||||||
|
stateInfo->active = false;
|
||||||
|
|
||||||
|
LogInfo("successfully added a new state!\n");
|
||||||
|
|
||||||
|
return stateInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachineHandler::StateDelete(State *state)
|
||||||
|
{
|
||||||
|
StateInfoMap::iterator it = mStateInfoMap.find(state->GetStateName());
|
||||||
|
StateInfo *stateInfo = nullptr;
|
||||||
|
if (it != mStateInfoMap.end()) {
|
||||||
|
stateInfo = it->second;
|
||||||
|
}
|
||||||
|
if (stateInfo == nullptr || stateInfo->active) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
it = mStateInfoMap.begin();
|
||||||
|
while (it != mStateInfoMap.end()) {
|
||||||
|
if (it->second->upperStateInfo == stateInfo) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
it = mStateInfoMap.find(state->GetStateName());
|
||||||
|
if (it != mStateInfoMap.end()) {
|
||||||
|
delete it->second;
|
||||||
|
it->second = nullptr;
|
||||||
|
mStateInfoMap.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachineHandler::SetFirstState(State *firstState)
|
||||||
|
{
|
||||||
|
pFirstState = firstState;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachineHandler::BuildTreeComplete()
|
||||||
|
{
|
||||||
|
/* Determines the maximum depth of the state hierarchy. */
|
||||||
|
int maxDepth = 0;
|
||||||
|
StateInfoMap::iterator it = mStateInfoMap.begin();
|
||||||
|
while (it != mStateInfoMap.end()) {
|
||||||
|
int depth = 0;
|
||||||
|
StateInfo *tempStateInfo = it->second;
|
||||||
|
while (tempStateInfo != nullptr) {
|
||||||
|
depth++;
|
||||||
|
tempStateInfo = tempStateInfo->upperStateInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxDepth < depth) {
|
||||||
|
maxDepth = depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogInfo("StateMachineHandler::BuildTreeComplete, maxDepth:%d\n", maxDepth);
|
||||||
|
mStateVector.resize(maxDepth);
|
||||||
|
mSequenceStateVector.resize(maxDepth);
|
||||||
|
BuildStateInitVector();
|
||||||
|
MessageExecutedAtTime(pStateMachine->CreateMessage(SM_INIT_CMD), 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachineHandler::BuildStateInitVector()
|
||||||
|
{
|
||||||
|
LogInfo("StateMachineHandler::BuildStateInitVector\n");
|
||||||
|
|
||||||
|
if (pFirstState == nullptr) {
|
||||||
|
LogError("StateMachineHandler::BuildStateInitVector please set initial state first!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
StateInfoMap::iterator it = mStateInfoMap.find(pFirstState->GetStateName());
|
||||||
|
StateInfo *startStateInfo = nullptr;
|
||||||
|
if (it != mStateInfoMap.end()) {
|
||||||
|
startStateInfo = it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (mSequenceStateVectorCount = 0; startStateInfo != nullptr; mSequenceStateVectorCount++) {
|
||||||
|
mSequenceStateVector[mSequenceStateVectorCount] = startStateInfo;
|
||||||
|
startStateInfo = startStateInfo->upperStateInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clearing the StateVector. */
|
||||||
|
mStateVectorTopIndex = -1;
|
||||||
|
MoveSequenceToStateVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
StateInfo *StateMachineHandler::BuildSequenceStateVector(State *targetState)
|
||||||
|
{
|
||||||
|
mSequenceStateVectorCount = 0;
|
||||||
|
StateInfoMap::iterator it = mStateInfoMap.find(targetState->GetStateName());
|
||||||
|
StateInfo *curStateInfo = nullptr;
|
||||||
|
if (it != mStateInfoMap.end()) {
|
||||||
|
curStateInfo = it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (curStateInfo == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
mSequenceStateVector[mSequenceStateVectorCount++] = curStateInfo;
|
||||||
|
curStateInfo = curStateInfo->upperStateInfo;
|
||||||
|
} while ((curStateInfo != nullptr) && (!curStateInfo->active));
|
||||||
|
|
||||||
|
return curStateInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachineHandler::PlaceDelayedMsgQueueTop()
|
||||||
|
{
|
||||||
|
// LogInfo("Enter StateMachineHandler::PlaceDelayedMsgQueueTop.\n");
|
||||||
|
|
||||||
|
for (int i = mDelayedMessages.size() - 1; i >= 0; i--) {
|
||||||
|
InternalMessage *curMsg = mDelayedMessages[i];
|
||||||
|
if (curMsg == nullptr) {
|
||||||
|
LogError("StateMachineHandler::PlaceDelayedMsgQueueTop: curMsg is null.\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
PlaceMessageTopOfQueue(curMsg);
|
||||||
|
}
|
||||||
|
mDelayedMessages.clear();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachineHandler::ReleaseDelayedMessages()
|
||||||
|
{
|
||||||
|
for (int i = mDelayedMessages.size() - 1; i >= 0; i--) {
|
||||||
|
InternalMessage *curMsg = mDelayedMessages[i];
|
||||||
|
if (curMsg != nullptr) {
|
||||||
|
delete curMsg;
|
||||||
|
curMsg = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mDelayedMessages.clear();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int StateMachineHandler::MoveSequenceToStateVector()
|
||||||
|
{
|
||||||
|
// LogInfo("StateMachineHandler::MoveSequenceToStateVector mSequenceStateVectorCount:%d\n",
|
||||||
|
// mSequenceStateVectorCount);
|
||||||
|
|
||||||
|
int newIndex = mStateVectorTopIndex + 1;
|
||||||
|
int i = mSequenceStateVectorCount - 1;
|
||||||
|
int j = newIndex;
|
||||||
|
while (i >= 0) {
|
||||||
|
mStateVector[j] = mSequenceStateVector[i];
|
||||||
|
j += 1;
|
||||||
|
i -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
mStateVectorTopIndex = j - 1;
|
||||||
|
return newIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachineHandler::SwitchState(State *targetState)
|
||||||
|
{
|
||||||
|
pTargetState = static_cast<State *>(targetState);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachineHandler::ClearWhenQuit()
|
||||||
|
{
|
||||||
|
pStateMachine->SetHandler(nullptr);
|
||||||
|
pStateMachine = nullptr;
|
||||||
|
pCurrentMsg = nullptr;
|
||||||
|
mStateVector.clear();
|
||||||
|
mSequenceStateVector.clear();
|
||||||
|
mDelayedMessages.clear();
|
||||||
|
pFirstState = nullptr;
|
||||||
|
pTargetState = nullptr;
|
||||||
|
mQuitFlag = true;
|
||||||
|
|
||||||
|
StateInfoMap::iterator it = mStateInfoMap.begin();
|
||||||
|
while (it != mStateInfoMap.end()) {
|
||||||
|
delete it->second;
|
||||||
|
it->second = nullptr;
|
||||||
|
it = mStateInfoMap.erase(it);
|
||||||
|
}
|
||||||
|
mStateInfoMap.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachineHandler::PerformSwitchState(State *msgProcessedState, InternalMessage *msg)
|
||||||
|
{
|
||||||
|
if (msgProcessedState == nullptr || msg == nullptr) {
|
||||||
|
// LogError("poniter is null.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
State *targetState = pTargetState;
|
||||||
|
if (targetState != nullptr) {
|
||||||
|
// LogInfo("StateMachineHandler::PerformSwitchState targetState name is: %s\n",
|
||||||
|
// targetState->GetStateName().c_str());
|
||||||
|
while (true) {
|
||||||
|
StateInfo *commonStateInfo = BuildSequenceStateVector(targetState);
|
||||||
|
mSwitchingStateFlag = true;
|
||||||
|
CallTreeStateExits(commonStateInfo);
|
||||||
|
|
||||||
|
int stateListEnteringIndex = MoveSequenceToStateVector();
|
||||||
|
CallTreeStateEnters(stateListEnteringIndex);
|
||||||
|
|
||||||
|
PlaceDelayedMsgQueueTop();
|
||||||
|
|
||||||
|
if (targetState != pTargetState) {
|
||||||
|
targetState = pTargetState;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pTargetState = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachineHandler::ExecuteMessage(InternalMessage *msg)
|
||||||
|
{
|
||||||
|
if (msg == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!mQuitFlag) {
|
||||||
|
if (pStateMachine != nullptr && msg->GetMessageName() != SM_INIT_CMD) {
|
||||||
|
}
|
||||||
|
|
||||||
|
pCurrentMsg = msg;
|
||||||
|
|
||||||
|
State *msgProcessedState = nullptr;
|
||||||
|
if (mBuildCompleteFlag) {
|
||||||
|
// LogInfo("StateMachineHandler::ExecuteMessage ExecuteTreeStateMsg!\n");
|
||||||
|
msgProcessedState = ExecuteTreeStateMsg(msg);
|
||||||
|
} else if (!mBuildCompleteFlag && msg->GetMessageName() == SM_INIT_CMD) {
|
||||||
|
// LogInfo("StateMachineHandler::ExecuteMessage msg: SM_INIT_CMD\n");
|
||||||
|
mBuildCompleteFlag = true;
|
||||||
|
CallTreeStateEnters(0);
|
||||||
|
} else {
|
||||||
|
LogError("The start method not called!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pStateMachine != nullptr) {
|
||||||
|
PerformSwitchState(msgProcessedState, msg);
|
||||||
|
} else {
|
||||||
|
LogError("poniter is null.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pStateMachine != nullptr && msg->GetMessageName() != SM_INIT_CMD) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachineHandler::DelayMessage(const InternalMessage *msg)
|
||||||
|
{
|
||||||
|
// LogInfo("Enter StateMachineHandler::DelayMessage.\n");
|
||||||
|
if (msg == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
InternalMessage *newMsg = pStateMachine->CreateMessage(msg);
|
||||||
|
if (newMsg == nullptr) {
|
||||||
|
LogError("StateMachineHandler::DelayMessage: newMsg is null.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mDelayedMessages.push_back(newMsg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
State *StateMachineHandler::ExecuteTreeStateMsg(InternalMessage *msg)
|
||||||
|
{
|
||||||
|
// LogInfo("StateMachineHandler::ExecuteTreeStateMsg mStateVectorTopIndex:%d\n", mStateVectorTopIndex);
|
||||||
|
if (msg == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
StateInfo *curStateInfo = mStateVector[mStateVectorTopIndex];
|
||||||
|
if (curStateInfo == nullptr) {
|
||||||
|
LogError("StateInfo is null.\n");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (curStateInfo->state) {
|
||||||
|
LOGI("State machine: %s execute Cmd:%d\n",
|
||||||
|
curStateInfo->state->GetStateName().c_str(), msg->GetMessageName());
|
||||||
|
}
|
||||||
|
// TODO:
|
||||||
|
while (curStateInfo->state && (!curStateInfo->state->ExecuteStateMsg((VStateMachineParam *)(msg)))) {
|
||||||
|
curStateInfo = curStateInfo->upperStateInfo;
|
||||||
|
|
||||||
|
if (curStateInfo == nullptr) {
|
||||||
|
pStateMachine->NotExecutedMessage(msg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (curStateInfo != nullptr) ? curStateInfo->state : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachineHandler::CallTreeStateExits(StateInfo *commonStateInfo)
|
||||||
|
{
|
||||||
|
while ((mStateVectorTopIndex >= 0) && (mStateVector[mStateVectorTopIndex] != commonStateInfo)) {
|
||||||
|
if (mStateVector[mStateVectorTopIndex] != nullptr) {
|
||||||
|
State *curState = mStateVector[mStateVectorTopIndex]->state;
|
||||||
|
if (curState != nullptr) {
|
||||||
|
curState->GoOutState();
|
||||||
|
}
|
||||||
|
mStateVector[mStateVectorTopIndex]->active = false;
|
||||||
|
}
|
||||||
|
mStateVectorTopIndex -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StateMachineHandler::CallTreeStateEnters(int index)
|
||||||
|
{
|
||||||
|
for (int i = index; i <= mStateVectorTopIndex; i++) {
|
||||||
|
if (index == mStateVectorTopIndex) {
|
||||||
|
/* Last enter state for transition. */
|
||||||
|
mSwitchingStateFlag = false;
|
||||||
|
}
|
||||||
|
// LogInfo("StateMachineHandler::CallTreeStateEnters mStateVectorTopIndex:%d, i: %d\n",
|
||||||
|
// mStateVectorTopIndex,
|
||||||
|
// i);
|
||||||
|
if (mStateVector[i] != nullptr && mStateVector[i]->state != nullptr) {
|
||||||
|
mStateVector[i]->state->GoInState();
|
||||||
|
mStateVector[i]->active = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* ensure flag set to false if no methods called. */
|
||||||
|
mSwitchingStateFlag = false;
|
||||||
|
}
|
||||||
|
// } // namespace Wifi
|
||||||
|
// } // namespace OHOS
|
518
middleware/StateMachine/src/OpenHarmony/state_machine.h
Normal file
518
middleware/StateMachine/src/OpenHarmony/state_machine.h
Normal file
|
@ -0,0 +1,518 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OHOS_STA_MACHINE_H
|
||||||
|
#define OHOS_STA_MACHINE_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include "handler.h"
|
||||||
|
#include "message_queue.h"
|
||||||
|
#include "IStateMachine.h"
|
||||||
|
|
||||||
|
// namespace OHOS {
|
||||||
|
// namespace Wifi {
|
||||||
|
#define CMD_SET_OPERATIONAL_MODE 1
|
||||||
|
|
||||||
|
class StateMachineHandler;
|
||||||
|
class StateMachine : public VStateMachine
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @Description : StateMachine Initialization Function
|
||||||
|
*
|
||||||
|
* @return true :success, false : failed.
|
||||||
|
*/
|
||||||
|
bool InitialStateMachine() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Start StateMachine.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void StartStateMachine() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Set Handler.
|
||||||
|
*
|
||||||
|
* @param handler - StateMachineHandler instance.[in]
|
||||||
|
*/
|
||||||
|
void SetHandler(StateMachineHandler *handler);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : The Message is not handled.
|
||||||
|
*
|
||||||
|
* @param msg - Message object.[in]
|
||||||
|
*/
|
||||||
|
void NotExecutedMessage(const InternalMessage *msg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description Stop Handler Thread.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void StopHandlerThread() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Start the timer.
|
||||||
|
*
|
||||||
|
* @param timerName - Timer Name.[in]
|
||||||
|
* @param interval - Timer duration, in milliseconds.[in]
|
||||||
|
*/
|
||||||
|
virtual void StartTimer(int timerName, int64_t interval);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Stop the timer.
|
||||||
|
*
|
||||||
|
* @param timerName - Timer Name.[in]
|
||||||
|
*/
|
||||||
|
virtual void StopTimer(int timerName) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Construct internal messages.
|
||||||
|
*
|
||||||
|
* @return InternalMessage* : Pointer to the constructed internal message.
|
||||||
|
*/
|
||||||
|
InternalMessage *CreateMessage();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Construct an information message based on
|
||||||
|
* the original message.
|
||||||
|
*
|
||||||
|
* @param orig - Original message.[in]
|
||||||
|
* @return InternalMessage* : Pointer to the constructed internal message.
|
||||||
|
*/
|
||||||
|
InternalMessage *CreateMessage(const InternalMessage *orig);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Construct internal messages.
|
||||||
|
*
|
||||||
|
* @param msgName - Message Name.[in]
|
||||||
|
* @return InternalMessage* : Pointer to the constructed internal message.
|
||||||
|
*/
|
||||||
|
InternalMessage *CreateMessage(int msgName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Construct internal messages.
|
||||||
|
*
|
||||||
|
* @param msgName - Message Name.[in]
|
||||||
|
* @param param1 - Message parameters.[in]
|
||||||
|
* @return InternalMessage* : Pointer to the constructed internal message.
|
||||||
|
*/
|
||||||
|
InternalMessage *CreateMessage(int msgName, int param1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Construct internal messages.
|
||||||
|
*
|
||||||
|
* @param msgName - Message Name.[in]
|
||||||
|
* @param param1 - Message parameters.[in]
|
||||||
|
* @param param2 - Message parameters.[in]
|
||||||
|
* @return InternalMessage* : Pointer to the constructed internal message.
|
||||||
|
*/
|
||||||
|
InternalMessage *CreateMessage(int msgName, int param1, int param2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Construct internal messages.
|
||||||
|
*
|
||||||
|
* @param msgName - Message Name.[in]
|
||||||
|
* @param messageObj - User-defined data
|
||||||
|
* @return InternalMessage* : Pointer to the constructed internal message.
|
||||||
|
*/
|
||||||
|
InternalMessage *CreateMessage(int msgName, const std::shared_ptr<VStateMessage> &messageObj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Constructs internal messages.
|
||||||
|
*
|
||||||
|
* @param msgName - Message name.[in]
|
||||||
|
* @param param1 - First Message parameter.[in]
|
||||||
|
* @param param2 - Second Message parameter.[in]
|
||||||
|
* @param messageObj - User-defined data
|
||||||
|
* @return InternalMessage* : Pointer to the constructed internal message.
|
||||||
|
*/
|
||||||
|
InternalMessage *CreateMessage(int msgName, int param1, int param2, const std::shared_ptr<VStateMessage> &messageObj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Constructs internal messages and places the
|
||||||
|
* messages in the message queue of the state machine.
|
||||||
|
*
|
||||||
|
* @param msgName - Message name.[in]
|
||||||
|
*/
|
||||||
|
virtual void SendMessage(int msgName) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Constructs internal messages and places the messages
|
||||||
|
* in the message queue of the state machine.
|
||||||
|
*
|
||||||
|
* @param msgName - Message name.[in]
|
||||||
|
* @param param1 - Message parameter.[in]
|
||||||
|
*/
|
||||||
|
virtual void SendMessage(int msgName, int param1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Constructs internal messages and places the messages
|
||||||
|
* in the message queue of the state machine.
|
||||||
|
*
|
||||||
|
* @param msgName - Message name.[in]
|
||||||
|
* @param param1 - Message parameter.[in]
|
||||||
|
* @param param2 - Message parameter.[in]
|
||||||
|
*/
|
||||||
|
virtual void SendMessage(int msgName, int param1, int param2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Puts messages into the message queue of the state machine.
|
||||||
|
*
|
||||||
|
* @param msg - Message to be sent.[in]
|
||||||
|
*/
|
||||||
|
virtual void SendMessage(InternalMessage *msg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Puts messages into the message queue of the state machine.
|
||||||
|
*
|
||||||
|
* @param msgName - Message Name.[in]
|
||||||
|
* @param messageObj - User-defined data
|
||||||
|
*/
|
||||||
|
virtual void SendMessage(int msgName, const std::shared_ptr<VStateMessage> &messageObj) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Puts messages into the message queue of the state machine.
|
||||||
|
*
|
||||||
|
* @param msgName - Message Name.[in]
|
||||||
|
* @param param1 - Message parameters.[in]
|
||||||
|
* @param param2 - Message parameters.[in]
|
||||||
|
* @param messageObj - User-defined data
|
||||||
|
*/
|
||||||
|
virtual void SendMessage(int msgName, int param1, int param2, const std::shared_ptr<VStateMessage> &messageObj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description Constructs internal messages and places them in the
|
||||||
|
* message queue of the state machine. The messages are processed
|
||||||
|
* after the specified delay time.
|
||||||
|
*
|
||||||
|
* @param msgName - Message Name.[in]
|
||||||
|
* @param delayTimeMs - Delay time, in milliseconds.[in]
|
||||||
|
*/
|
||||||
|
void MessageExecutedLater(int msgName, int64_t delayTimeMs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Constructs internal messages and places them in the
|
||||||
|
* message queue of the state machine. The messages are processed
|
||||||
|
* after the specified delay time.
|
||||||
|
*
|
||||||
|
* @param msgName - Message Name.[in]
|
||||||
|
* @param param1 - Message parameters.[in]
|
||||||
|
* @param delayTimeMs - Delay time, in milliseconds.[in]
|
||||||
|
*/
|
||||||
|
void MessageExecutedLater(int msgName, int param1, int64_t delayTimeMs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Constructs internal messages and places them in the
|
||||||
|
* message queue of the state machine. The messages are processed
|
||||||
|
* after the specified delay time.
|
||||||
|
*
|
||||||
|
* @param msgName - Message Name.[in]
|
||||||
|
* @param param1 - Message parameters.[in]
|
||||||
|
* @param param2 - Message parameters.[in]
|
||||||
|
* @param delayTimeMs - Delay time, in milliseconds.[in]
|
||||||
|
*/
|
||||||
|
void MessageExecutedLater(int msgName, int param1, int param2, int64_t delayTimeMs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Constructs internal messages and places them in the
|
||||||
|
* message queue of the state machine. The messages are processed
|
||||||
|
* after the specified delay time.
|
||||||
|
*
|
||||||
|
* @param msg - Message to be sent.[in]
|
||||||
|
* @param delayTimeMs - Delay time, in milliseconds.[in]
|
||||||
|
*/
|
||||||
|
void MessageExecutedLater(InternalMessage *msg, int64_t delayTimeMs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Constructs internal messages and places them in the
|
||||||
|
* message queue of the state machine. The messages are processed
|
||||||
|
* after the specified delay time.
|
||||||
|
*
|
||||||
|
* @param msgName - Message Name.[in]
|
||||||
|
* @param messageObj -User-defined data
|
||||||
|
* @param delayTimeMs - Delay time, in milliseconds.[in]
|
||||||
|
*/
|
||||||
|
void MessageExecutedLater(int msgName, const std::shared_ptr<VStateMessage> &messageObj, int64_t delayTimeMs) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Constructs internal messages and places them in the
|
||||||
|
* message queue of the state machine. The messages are processed
|
||||||
|
* after the specified delay time.
|
||||||
|
*
|
||||||
|
* @param msgName - Message Name.[in]
|
||||||
|
* @param param1 - Message parameters.[in]
|
||||||
|
* @param param2 - Message parameters.[in]
|
||||||
|
* @param messageObj - User-defined data
|
||||||
|
* @param delayTimeMs - Delay time, in milliseconds.[in]
|
||||||
|
*/
|
||||||
|
void MessageExecutedLater(int msgName, int param1, int param2, const std::shared_ptr<VStateMessage> &messageObj, int64_t delayTimeMs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Construct a new State Machine:: State Machine object.
|
||||||
|
*
|
||||||
|
* @param name - State name.[in]
|
||||||
|
*/
|
||||||
|
explicit StateMachine(const std::string &name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Destroy the State Machine:: State Machine object.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
virtual ~StateMachine();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* @Description : Add state.
|
||||||
|
*
|
||||||
|
* @param state - state.[in]
|
||||||
|
* @param upper - upper state.[in]
|
||||||
|
*/
|
||||||
|
void StatePlus(State *state, State *upper) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Remove state.
|
||||||
|
*
|
||||||
|
* @param state - state.[in]
|
||||||
|
*/
|
||||||
|
void StateDelete(State *state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Set first state.
|
||||||
|
*
|
||||||
|
* @param firstState - First state.[in]
|
||||||
|
*/
|
||||||
|
void SetFirstState(State *firstState) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Transition to orther state.
|
||||||
|
*
|
||||||
|
* @param targetState - state.[in]
|
||||||
|
*/
|
||||||
|
void SwitchState(State *targetState) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Delay Message.
|
||||||
|
*
|
||||||
|
* @param msg - Message object.[in]
|
||||||
|
*/
|
||||||
|
void DelayMessage(const InternalMessage *msg);
|
||||||
|
void DelayMessage(VStateMachineParam *msg) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
StateMachineHandler *pStateMachineHandler;
|
||||||
|
std::string mStateName;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct StateInfo
|
||||||
|
{
|
||||||
|
State *state;
|
||||||
|
StateInfo *upperStateInfo;
|
||||||
|
bool active;
|
||||||
|
} StateInfo;
|
||||||
|
|
||||||
|
class StateMachineHandler : public Handler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using StateInfoMap = std::map<std::string, StateInfo *>;
|
||||||
|
using StateVector = std::vector<StateInfo *>;
|
||||||
|
using DelayedMessage = std::vector<InternalMessage *>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Construct a new state machine Handler:: StateMachine Handler object.
|
||||||
|
*
|
||||||
|
* @param pStateMgr - Handler pointer.[in]
|
||||||
|
*/
|
||||||
|
explicit StateMachineHandler(StateMachine *pStateMgr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Destroy the StateMachine Handler:: StateMachine Handler object.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
~StateMachineHandler();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : StateMachineHandler Initialization Function.
|
||||||
|
*
|
||||||
|
* @return true : success, false : failed.
|
||||||
|
*/
|
||||||
|
bool InitialSmHandler();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Add a new state.
|
||||||
|
*
|
||||||
|
* @param state - State to be added.[in]
|
||||||
|
* @param upper - upper of state.[in]
|
||||||
|
* @return StateInfo*
|
||||||
|
*/
|
||||||
|
StateInfo *StatePlus(State *state, State *upper);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Delete a state.
|
||||||
|
*
|
||||||
|
* @param state - State to be deleted.[in]
|
||||||
|
*/
|
||||||
|
void StateDelete(State *state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Sets the Initialization State.
|
||||||
|
*
|
||||||
|
* @param firstState - Initialization State.[in]
|
||||||
|
*/
|
||||||
|
void SetFirstState(State *firstState);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : State transition function.
|
||||||
|
*
|
||||||
|
* @param targetState - Destination State.[in]
|
||||||
|
*/
|
||||||
|
void SwitchState(State *targetState);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Delay Message Processing Function.
|
||||||
|
*
|
||||||
|
* @param msg - Message body pointer.[in]
|
||||||
|
*/
|
||||||
|
void DelayMessage(const InternalMessage *msg);
|
||||||
|
// void DelayMessage(const std::shared_ptr<VStateMessage> &messageObj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : The state machine is constructed.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void BuildTreeComplete();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* @Description : Sets the initial state sequence.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void BuildStateInitVector();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Writes the inactive upper states of targetState
|
||||||
|
* and targetState to the sequenceStateVector list.
|
||||||
|
*
|
||||||
|
* @param targetState - Target State Machine.[in]
|
||||||
|
* @return StateInfo*
|
||||||
|
*/
|
||||||
|
StateInfo *BuildSequenceStateVector(State *targetState);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Move Delayed Message At Front Of Queue.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void PlaceDelayedMsgQueueTop();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Release all messages in delayed Messages.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ReleaseDelayedMessages();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Fill the status in the sequential status
|
||||||
|
* list in reverse order.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int MoveSequenceToStateVector();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Invoke the ExecuteStateMsg interface of the current state
|
||||||
|
* to process messages sent to the state machine. The entry/exit of the
|
||||||
|
* state machine is also called, and the delayed messagei s put back
|
||||||
|
* into queue when transitioning to a new state.
|
||||||
|
*
|
||||||
|
* @param msg - Messages.[in]
|
||||||
|
*/
|
||||||
|
void ExecuteMessage(InternalMessage *msg) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Clean up After Quitting.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ClearWhenQuit();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Performing Status Transitions.
|
||||||
|
*
|
||||||
|
* @param msgProcessedState - Message processing status.[in]
|
||||||
|
* @param msg - Messages.[in]
|
||||||
|
*/
|
||||||
|
void PerformSwitchState(State *msgProcessedState, InternalMessage *msg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Process messages. If the current state doesnot process it,
|
||||||
|
* the upper state processing is called, and so on. If all upper states
|
||||||
|
* are not processed, invoke the NotExecutedMessage method of the state machine.
|
||||||
|
*
|
||||||
|
* @param msg - Message body pointer.[in]
|
||||||
|
* @return State*
|
||||||
|
*/
|
||||||
|
State *ExecuteTreeStateMsg(InternalMessage *msg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Invoke GoOutState() for each state from the first
|
||||||
|
* state in the list to the public upper state.
|
||||||
|
*
|
||||||
|
* @param commonStateInfo - common upper state machine.[in]
|
||||||
|
*/
|
||||||
|
void CallTreeStateExits(StateInfo *commonStateInfo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description : Call the GoInState method from the start state
|
||||||
|
* index to the top of the state stack.
|
||||||
|
*
|
||||||
|
* @param index - Start state index of the
|
||||||
|
* state machine list.
|
||||||
|
*/
|
||||||
|
void CallTreeStateEnters(int index);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* All state mappings of the state machine */
|
||||||
|
StateInfoMap mStateInfoMap;
|
||||||
|
/* From child state to upper state list */
|
||||||
|
StateVector mStateVector;
|
||||||
|
/* Top index of mStateVector */
|
||||||
|
int mStateVectorTopIndex;
|
||||||
|
/* From upper state to child state list */
|
||||||
|
StateVector mSequenceStateVector;
|
||||||
|
/* Top of mSequenceStateVector */
|
||||||
|
int mSequenceStateVectorCount;
|
||||||
|
/* Delayed Message Queue */
|
||||||
|
DelayedMessage mDelayedMessages;
|
||||||
|
/* State machine instance */
|
||||||
|
StateMachine *pStateMachine;
|
||||||
|
/* Initial state */
|
||||||
|
State *pFirstState;
|
||||||
|
/* Target Status */
|
||||||
|
State *pTargetState;
|
||||||
|
/* StateMachine exit or not */
|
||||||
|
bool mQuitFlag;
|
||||||
|
/* Whether the state machine has been built */
|
||||||
|
bool mBuildCompleteFlag;
|
||||||
|
/*
|
||||||
|
* All State exit/enter calls are true before the
|
||||||
|
* last enter call in the target state.
|
||||||
|
*/
|
||||||
|
bool mSwitchingStateFlag;
|
||||||
|
/* Current Message */
|
||||||
|
InternalMessage *pCurrentMsg;
|
||||||
|
};
|
||||||
|
// } // namespace Wifi
|
||||||
|
// } // namespace OHOS
|
||||||
|
#endif
|
20
middleware/StateMachine/src/StateMachineImpl.cpp
Normal file
20
middleware/StateMachine/src/StateMachineImpl.cpp
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 JIUYILIAN Co., Ltd.
|
||||||
|
* 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 "StateMachineImpl.h"
|
||||||
|
#include "StateMachineMakePtr.h"
|
||||||
|
const StatusCode StateMachineImpl::CreateStateMachine(std::shared_ptr<VStateMachine> &stateMachine)
|
||||||
|
{
|
||||||
|
return StateMachineMakePtr::GetInstance()->CreateStateMachine(stateMachine);
|
||||||
|
}
|
25
middleware/StateMachine/src/StateMachineImpl.h
Normal file
25
middleware/StateMachine/src/StateMachineImpl.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 JIUYILIAN Co., Ltd.
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
#ifndef STATE_MACHINE_IMPL_H
|
||||||
|
#define STATE_MACHINE_IMPL_H
|
||||||
|
#include "IStateMachine.h"
|
||||||
|
class StateMachineImpl : public IStateMachine
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
StateMachineImpl() = default;
|
||||||
|
~StateMachineImpl() = default;
|
||||||
|
const StatusCode CreateStateMachine(std::shared_ptr<VStateMachine> &stateMachine) override;
|
||||||
|
};
|
||||||
|
#endif
|
64
middleware/StateMachine/src/StateMachineMakePtr.cpp
Normal file
64
middleware/StateMachine/src/StateMachineMakePtr.cpp
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 JIUYILIAN Co., Ltd.
|
||||||
|
* 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 "StateMachineMakePtr.h"
|
||||||
|
#include "ILog.h"
|
||||||
|
#include "state_machine.h"
|
||||||
|
#include "IStateMachine.h"
|
||||||
|
#include "StateMachineImpl.h"
|
||||||
|
#include <thread>
|
||||||
|
bool CreateStateMachine(void)
|
||||||
|
{
|
||||||
|
auto instance = std::make_shared<IStateMachine>();
|
||||||
|
StatusCode code = StateMachineMakePtr::GetInstance()->CreateStateMachine(instance);
|
||||||
|
if (IsCodeOK(code))
|
||||||
|
{
|
||||||
|
LogInfo("State machine instance is ok.\n");
|
||||||
|
IStateMachine::GetInstance(&instance);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::shared_ptr<StateMachineMakePtr> &StateMachineMakePtr::GetInstance(std::shared_ptr<StateMachineMakePtr> *impl)
|
||||||
|
{
|
||||||
|
static auto instance = std::make_shared<StateMachineMakePtr>();
|
||||||
|
if (impl)
|
||||||
|
{
|
||||||
|
instance = *impl;
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
StatusCode StateMachineMakePtr::CreateStateMachine(std::shared_ptr<VStateMachine> &stateMachine)
|
||||||
|
{
|
||||||
|
// TODO: need a name ?
|
||||||
|
auto tmp = std::make_shared<StateMachine>("TODO");
|
||||||
|
if (tmp)
|
||||||
|
{
|
||||||
|
stateMachine = std::move(tmp);
|
||||||
|
return CreateStatusCode(STATUS_CODE_OK);
|
||||||
|
}
|
||||||
|
LogError("Create state machine module failed.\n");
|
||||||
|
return CreateStatusCode(STATUS_CODE_MAKE_SHARED_PTR_FAILED);
|
||||||
|
}
|
||||||
|
StatusCode StateMachineMakePtr::CreateStateMachine(std::shared_ptr<IStateMachine> &instance)
|
||||||
|
{
|
||||||
|
auto tmp = std::make_shared<StateMachineImpl>();
|
||||||
|
if (tmp)
|
||||||
|
{
|
||||||
|
instance = std::move(tmp);
|
||||||
|
return CreateStatusCode(STATUS_CODE_OK);
|
||||||
|
}
|
||||||
|
LogError("Create state machine module failed.\n");
|
||||||
|
return CreateStatusCode(STATUS_CODE_MAKE_SHARED_PTR_FAILED);
|
||||||
|
}
|
29
middleware/StateMachine/src/StateMachineMakePtr.h
Normal file
29
middleware/StateMachine/src/StateMachineMakePtr.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 JIUYILIAN Co., Ltd.
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
#ifndef STATE_MACHINE_MAKE_PTR_H
|
||||||
|
#define STATE_MACHINE_MAKE_PTR_H
|
||||||
|
#include "StatusCode.h"
|
||||||
|
#include "IStateMachine.h"
|
||||||
|
#include <memory>
|
||||||
|
class StateMachineMakePtr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
StateMachineMakePtr() = default;
|
||||||
|
virtual ~StateMachineMakePtr() = default;
|
||||||
|
static std::shared_ptr<StateMachineMakePtr> &GetInstance(std::shared_ptr<StateMachineMakePtr> *impl = nullptr);
|
||||||
|
virtual StatusCode CreateStateMachine(std::shared_ptr<VStateMachine> &stateMachine);
|
||||||
|
virtual StatusCode CreateStateMachine(std::shared_ptr<IStateMachine> &instance);
|
||||||
|
};
|
||||||
|
#endif
|
|
@ -32,6 +32,13 @@ extern "C"
|
||||||
#define LogWarning(...) GetLogIntance()->printf(GetLogIntance(), __FUNCTION__, __LINE__, LOG_TYPE_WARNING, __VA_ARGS__)
|
#define LogWarning(...) GetLogIntance()->printf(GetLogIntance(), __FUNCTION__, __LINE__, LOG_TYPE_WARNING, __VA_ARGS__)
|
||||||
#define LogError(...) GetLogIntance()->printf(GetLogIntance(), __FUNCTION__, __LINE__, LOG_TYPE_ERROR, __VA_ARGS__)
|
#define LogError(...) GetLogIntance()->printf(GetLogIntance(), __FUNCTION__, __LINE__, LOG_TYPE_ERROR, __VA_ARGS__)
|
||||||
#define LogTrace(...) GetLogIntance()->printf(GetLogIntance(), __FUNCTION__, __LINE__, LOG_TYPE_TRACE, __VA_ARGS__)
|
#define LogTrace(...) GetLogIntance()->printf(GetLogIntance(), __FUNCTION__, __LINE__, LOG_TYPE_TRACE, __VA_ARGS__)
|
||||||
|
#if 1 // For OpenHarmony log, should delete finally.// TODO:
|
||||||
|
#define LOGD(...)
|
||||||
|
#define LOGI(...)
|
||||||
|
#define LOGW(...)
|
||||||
|
#define LOGE(...)
|
||||||
|
#define LOGF(...)
|
||||||
|
#endif
|
||||||
typedef struct i_log ILog;
|
typedef struct i_log ILog;
|
||||||
typedef struct i_log
|
typedef struct i_log
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,6 +11,7 @@ extern "C"
|
||||||
STATUS_CODE_NOT_OK,
|
STATUS_CODE_NOT_OK,
|
||||||
STATUS_CODE_VIRTUAL_FUNCTION,
|
STATUS_CODE_VIRTUAL_FUNCTION,
|
||||||
STATUS_CODE_INVALID_PARAMENTER,
|
STATUS_CODE_INVALID_PARAMENTER,
|
||||||
|
STATUS_CODE_MAKE_SHARED_PTR_FAILED,
|
||||||
STATUS_CODE_END
|
STATUS_CODE_END
|
||||||
};
|
};
|
||||||
typedef struct status_code StatusCode;
|
typedef struct status_code StatusCode;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user