Add state machine module.
This commit is contained in:
parent
9fc61803f1
commit
08d451c882
|
@ -42,14 +42,6 @@ endif()
|
|||
#Add macro definition
|
||||
# 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
|
||||
unset(MAIN_INCLUDE_PATH CACHE)
|
||||
set(MAIN_INCLUDE_PATH "" CACHE STRING INTERNAL)
|
||||
|
@ -85,6 +77,7 @@ endif()
|
|||
|
||||
# 添加编译目录
|
||||
# add_subdirectory(application)
|
||||
add_subdirectory(middleware)
|
||||
add_subdirectory(utils)
|
||||
add_subdirectory(hal)
|
||||
# add_subdirectory(customization)
|
||||
|
|
|
@ -7,6 +7,7 @@ set(TEST_OUTPUT_PATH "${PLATFORM_PATH}/out/test")
|
|||
|
||||
set(PROJECT_ROOT_PATH "${PLATFORM_PATH}")
|
||||
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(HAL_SOURCE_PATH "${CMAKE_SOURCE_DIR_IPCSDK}/hal")
|
||||
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 LogError(...) GetLogIntance()->printf(GetLogIntance(), __FUNCTION__, __LINE__, LOG_TYPE_ERROR, __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
|
||||
{
|
||||
|
|
|
@ -11,6 +11,7 @@ extern "C"
|
|||
STATUS_CODE_NOT_OK,
|
||||
STATUS_CODE_VIRTUAL_FUNCTION,
|
||||
STATUS_CODE_INVALID_PARAMENTER,
|
||||
STATUS_CODE_MAKE_SHARED_PTR_FAILED,
|
||||
STATUS_CODE_END
|
||||
};
|
||||
typedef struct status_code StatusCode;
|
||||
|
|
Loading…
Reference in New Issue
Block a user