From 1f862db3de43cb49bba9045d8dfd4539d5e51ec1 Mon Sep 17 00:00:00 2001 From: Fancy code <258828110.@qq.com> Date: Wed, 14 Feb 2024 11:27:43 -0800 Subject: [PATCH] Key and Led control utils module. --- middleware/DeviceManager/CMakeLists.txt | 4 +- .../DeviceManager/include/IDeviceManager.h | 49 ++++----- .../DeviceManager/src/DeviceManager.cpp | 13 +-- middleware/DeviceManager/src/DeviceManager.h | 7 +- .../src/DeviceManagerMakePtr.cpp | 8 +- .../DeviceManager/src/IDeviceManager.cpp | 7 ++ middleware/DeviceManager/src/KeyManager.cpp | 8 +- middleware/DeviceManager/src/KeyManager.h | 2 +- middleware/DeviceManager/src/LedManager.cpp | 26 ++--- middleware/DeviceManager/src/LedManager.h | 18 ++-- middleware/DeviceManager/src/LedTimer.cpp | 3 +- test/CMakeLists.txt | 26 +++-- test/middleware/LedTest/src/Led_Test.cpp | 2 +- utils/CMakeLists.txt | 2 + utils/KeyControl/CMakeLists.txt | 55 ++++++++++ utils/KeyControl/include/KeyControl.h | 83 +++++++++++++++ utils/KeyControl/src/KeyControl.cpp | 96 +++++++++++++++++ utils/LedControl/CMakeLists.txt | 55 ++++++++++ utils/LedControl/include/LedControl.h | 78 ++++++++++++++ utils/LedControl/src/LedControl.cpp | 100 ++++++++++++++++++ utils/README.md | 13 +++ 21 files changed, 569 insertions(+), 86 deletions(-) create mode 100644 utils/KeyControl/CMakeLists.txt create mode 100644 utils/KeyControl/include/KeyControl.h create mode 100644 utils/KeyControl/src/KeyControl.cpp create mode 100644 utils/LedControl/CMakeLists.txt create mode 100644 utils/LedControl/include/LedControl.h create mode 100644 utils/LedControl/src/LedControl.cpp create mode 100644 utils/README.md diff --git a/middleware/DeviceManager/CMakeLists.txt b/middleware/DeviceManager/CMakeLists.txt index dede2ebc..2f0da22f 100644 --- a/middleware/DeviceManager/CMakeLists.txt +++ b/middleware/DeviceManager/CMakeLists.txt @@ -51,4 +51,6 @@ add_custom_command( COMMAND make DeviceManager_code_format WORKING_DIRECTORY ${PLATFORM_PATH}/cmake-shell/ ) -endif() \ No newline at end of file +endif() + +define_file_name(${TARGET_NAME}) \ No newline at end of file diff --git a/middleware/DeviceManager/include/IDeviceManager.h b/middleware/DeviceManager/include/IDeviceManager.h index ce8969db..ad1321f3 100644 --- a/middleware/DeviceManager/include/IDeviceManager.h +++ b/middleware/DeviceManager/include/IDeviceManager.h @@ -14,39 +14,33 @@ */ #ifndef IDEVICEMANAGER_H #define IDEVICEMANAGER_H -#include "ILog.h" #include "StatusCode.h" #include #include #include -enum class IpcMission -{ - TEST = 0, - END -}; -enum class KeyAction +bool CreateDeviceManagerModule(void); +enum class KeyEvent { SHORT_CLICK = 0, - // LONG_CLICK, // Do not support. HOLD_DOWN, HOLD_UP, END }; -enum LedState +enum class LedState { - LED_STATE_OFF = 0, - LED_STATE_ON, - LED_STATE_GREEN, - LED_STATE_RED, - LED_STATE_YELLOW, - LED_STATE_LEVEL_0, - LED_STATE_LEVEL_1, - LED_STATE_LEVEL_2, - LED_STATE_LEVEL_3, - LED_STATE_LEVEL_4, - LED_STATE_LEVEL_END, - LED_STATE_END + OFF = 0, + ON, + GREEN, + RED, + YELLOW, + LEVEL_0, + LEVEL_1, + LEVEL_2, + LEVEL_3, + LEVEL_4, + LEVEL_END, + END }; class IDeviceManager @@ -55,14 +49,9 @@ public: IDeviceManager() = default; virtual ~IDeviceManager() = default; static std::shared_ptr &GetInstance(std::shared_ptr *impl = nullptr); - virtual const StatusCode Init(void) { return CreateStatusCode(STATUS_CODE_OK); } - virtual const StatusCode UnInit(void) { return CreateStatusCode(STATUS_CODE_OK); } - virtual const IpcMission GetIpcMission(void) { return IpcMission::END; } - virtual const StatusCode ISetLedState(std::string ledName, LedState &CurrentState, - const unsigned int &KeepAliveTime, const unsigned int &BlinkPeriod) - { - return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION); - } + virtual const StatusCode Init(void); + virtual const StatusCode UnInit(void); + virtual const StatusCode SetLedState(const std::string &ledName, const LedState ¤tState, + const unsigned int &KeepAliveTime, const unsigned int &blinkPeriod); }; -bool CreateDeviceManagerModule(void); #endif \ No newline at end of file diff --git a/middleware/DeviceManager/src/DeviceManager.cpp b/middleware/DeviceManager/src/DeviceManager.cpp index 72996633..876d3363 100644 --- a/middleware/DeviceManager/src/DeviceManager.cpp +++ b/middleware/DeviceManager/src/DeviceManager.cpp @@ -14,6 +14,7 @@ */ #include "DeviceManager.h" +#include "ILog.h" #include "LedTimer.h" #include @@ -43,19 +44,13 @@ const StatusCode DeviceManager::UnInit(void) return CreateStatusCode(STATUS_CODE_OK); } -const IpcMission DeviceManager::GetIpcMission(void) { return IpcMission::TEST; } - -const StatusCode DeviceManager::ISetLedState(std::string ledName, LedState &CurrentState, - const unsigned int &KeepAliveTime, const unsigned int &BlinkPeriod) +const StatusCode DeviceManager::SetLedState(const std::string &ledName, const LedState ¤tState, + const unsigned int &KeepAliveTime, const unsigned int &blinkPeriod) { - if (!ledName.empty() || *ledName.c_str() == '\0') { - LogDebug("\n\n\n\n %s %d\n\n\n", __func__, __LINE__); - } - for (auto it = mLedManagers.begin(); it != mLedManagers.end(); ++it) { std::shared_ptr ledOut = *it; if (ledOut->GetLedHal()->GetLedName() == ledName) { - ledOut->SetLedState(CurrentState, KeepAliveTime, BlinkPeriod); + ledOut->SetLedState(currentState, KeepAliveTime, blinkPeriod); return CreateStatusCode(STATUS_CODE_OK); } } diff --git a/middleware/DeviceManager/src/DeviceManager.h b/middleware/DeviceManager/src/DeviceManager.h index 4f92a1f8..974ef660 100644 --- a/middleware/DeviceManager/src/DeviceManager.h +++ b/middleware/DeviceManager/src/DeviceManager.h @@ -25,10 +25,9 @@ public: const StatusCode Init(void) override; const StatusCode UnInit(void) override; - const IpcMission GetIpcMission(void) override; - const StatusCode ISetLedState(std::string ledName, LedState &CurrentState, - const unsigned int &KeepAliveTime = DEFAULT_KEEP_ALIVE_TIME, - const unsigned int &BlinkPeriod = LED_NOT_BLINK) override; + const StatusCode SetLedState(const std::string &ledName, const LedState ¤tState, + const unsigned int &keepAliveTime = DEFAULT_KEEP_ALIVE_TIME, + const unsigned int &blinkPeriod = LED_NOT_BLINK) override; private: std::vector> mLedManagers; diff --git a/middleware/DeviceManager/src/DeviceManagerMakePtr.cpp b/middleware/DeviceManager/src/DeviceManagerMakePtr.cpp index 758a9fac..26ed9e9d 100644 --- a/middleware/DeviceManager/src/DeviceManagerMakePtr.cpp +++ b/middleware/DeviceManager/src/DeviceManagerMakePtr.cpp @@ -30,7 +30,13 @@ std::shared_ptr &DeviceManagerMakePtr::GetInstance(std::sh { static auto instance = std::make_shared(); if (impl) { - instance = *impl; + if (instance.use_count() == 1) { + LogInfo("Instance changed succeed.\n"); + instance = *impl; + } + else { + LogError("Can't changing the instance becase of using by some one.\n"); + } } return instance; } diff --git a/middleware/DeviceManager/src/IDeviceManager.cpp b/middleware/DeviceManager/src/IDeviceManager.cpp index 88abfdfd..d41f493d 100644 --- a/middleware/DeviceManager/src/IDeviceManager.cpp +++ b/middleware/DeviceManager/src/IDeviceManager.cpp @@ -27,4 +27,11 @@ std::shared_ptr &IDeviceManager::GetInstance(std::shared_ptr #include -using KeyActionReport = std::function; +using KeyActionReport = std::function; constexpr int KEY_ACTION_LONG_CLICK = 1000 * 5; constexpr int KEY_ACTION_SHORT_CLICK = 200; constexpr int KEY_ACTION_HOLD_DWON = 500; diff --git a/middleware/DeviceManager/src/LedManager.cpp b/middleware/DeviceManager/src/LedManager.cpp index bfc3c775..618c4dd3 100644 --- a/middleware/DeviceManager/src/LedManager.cpp +++ b/middleware/DeviceManager/src/LedManager.cpp @@ -25,34 +25,34 @@ LedManager::LedManager() mStateAliveTime = 0; } -LedManager::LedManager(std::shared_ptr &LedHal, const LedState &CurrentState, - const unsigned int &KeepAliveTime, const unsigned int &BlinkPeriod) +LedManager::LedManager(std::shared_ptr &LedHal, const LedState &urrentState, const unsigned int &KeepAliveTime, + const unsigned int &blinkPeriod) { mLedHal = LedHal; - mCurrentState = CurrentState; + mCurrentState = urrentState; mKeepAliveTime = KeepAliveTime; - mBlinkPeriod = BlinkPeriod; + mBlinkPeriod = blinkPeriod; mStateAliveTime = 0; } std::shared_ptr LedManager::GetLedHal(void) { return mLedHal; } -StatusCode LedManager::SetLedState(LedState &CurrentState, const unsigned int &KeepAliveTime, - const unsigned int &BlinkPeriod) +StatusCode LedManager::SetLedState(const LedState ¤tState, const unsigned int &keepAliveTime, + const unsigned int &blinkPeriod) { - mCurrentState = CurrentState; - mKeepAliveTime = KeepAliveTime; - mBlinkPeriod = BlinkPeriod; + mCurrentState = currentState; + mKeepAliveTime = keepAliveTime; + mBlinkPeriod = blinkPeriod; return CreateStatusCode(STATUS_CODE_OK); } -StatusCode LedManager::GetLedState(LedState &CurrentState) +StatusCode LedManager::GetLedState(LedState &urrentState) { - CurrentState = mCurrentState; + urrentState = mCurrentState; return CreateStatusCode(STATUS_CODE_OK); } -// StatusCode LedManager::BlinkOn(LedState CurrentState, unsigned int KeepAliveTime) +// StatusCode LedManager::BlinkOn(LedState urrentState, unsigned int KeepAliveTime) // { // mKeepAliveTime = KeepAliveTime; // return CreateStatusCode(STATUS_CODE_OK); @@ -60,6 +60,6 @@ StatusCode LedManager::GetLedState(LedState &CurrentState) // StatusCode LedManager::BlinkOff(void) // { -// mCurrentState = LedState::LED_STATE_OFF; +// mCurrentState = LedState::OFF; // return CreateStatusCode(STATUS_CODE_OK); // } diff --git a/middleware/DeviceManager/src/LedManager.h b/middleware/DeviceManager/src/LedManager.h index 133aecf2..4ecbecd8 100644 --- a/middleware/DeviceManager/src/LedManager.h +++ b/middleware/DeviceManager/src/LedManager.h @@ -20,7 +20,7 @@ #include #include -constexpr LedState NEW_LED_STATE = LedState::LED_STATE_OFF; +constexpr LedState NEW_LED_STATE = LedState::OFF; constexpr unsigned int LED_NOT_BLINK = 0; constexpr unsigned int BLINKING_FAST_MS = 500; constexpr unsigned int BLINKING_SLOW_MS = 1000; @@ -33,26 +33,26 @@ class LedManager public: LedManager(); LedManager(std::shared_ptr &LedHal, const LedState &CurrentState, - const unsigned int &KeepAliveTime = DEFAULT_KEEP_ALIVE_TIME, - const unsigned int &BlinkPeriod = LED_NOT_BLINK); + const unsigned int &keepAliveTime = DEFAULT_KEEP_ALIVE_TIME, + const unsigned int &blinkPeriod = LED_NOT_BLINK); ~LedManager() = default; StatusCode Init(void) { return CreateStatusCode(STATUS_CODE_NOT_OK); } StatusCode Unit(void) { return CreateStatusCode(STATUS_CODE_NOT_OK); } public: std::shared_ptr GetLedHal(void); - StatusCode SetLedState(LedState &CurrentState, const unsigned int &KeepAliveTime = DEFAULT_KEEP_ALIVE_TIME, - const unsigned int &BlinkPeriod = LED_NOT_BLINK); + StatusCode SetLedState(const LedState &CurrentState, const unsigned int &keepAliveTime = DEFAULT_KEEP_ALIVE_TIME, + const unsigned int &blinkPeriod = LED_NOT_BLINK); StatusCode GetLedState(LedState &CurrentState); // StatusCode BlinkOn(LedState CurrentState, unsigned int KeepAliveTime); // StatusCode BlinkOff(void); private: std::shared_ptr mLedHal; - LedState mCurrentState; // 当前状态 - unsigned int mBlinkPeriod; // 闪烁频率 - unsigned int mKeepAliveTime; // 保持存活时间 - unsigned int mStateAliveTime; // 状态保持时间 + LedState mCurrentState; + unsigned int mBlinkPeriod; + unsigned int mKeepAliveTime; + unsigned int mStateAliveTime; }; #endif diff --git a/middleware/DeviceManager/src/LedTimer.cpp b/middleware/DeviceManager/src/LedTimer.cpp index 22453547..b0ae9eb2 100644 --- a/middleware/DeviceManager/src/LedTimer.cpp +++ b/middleware/DeviceManager/src/LedTimer.cpp @@ -14,7 +14,7 @@ */ #include "LedTimer.h" -// #include "Log.h" +#include "ILog.h" LedTimer::LedTimer() { mTimerRuning = false; } std::shared_ptr &LedTimer::GetInstance(std::shared_ptr *impl) { @@ -70,7 +70,6 @@ const StatusCode LedTimer::CheckState(void) int count = 0; for (auto it = TimerLedManagers.begin(); it != TimerLedManagers.end(); ++it) { std::shared_ptr LedManager = *it; - LogInfo("%s %d count = %d\n\n", __func__, __LINE__, count++); } return CreateStatusCode(STATUS_CODE_OK); } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0b123997..9a17c895 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,17 +1,21 @@ # cmake_minimum_required(VERSION 2.8.0) # Compile gtest for test code. -execute_process(COMMAND sh build_gtest.sh ${TARGET_PLATFORM} ${PLATFORM_PATH} ${PLATFORM_PATH} WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/gtest/) -execute_process(COMMAND mkdir ${PLATFORM_PATH}/output_files - WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/gtest/) -execute_process(COMMAND mkdir ${PLATFORM_PATH}/output_files/libs - WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/gtest/) -execute_process(COMMAND mkdir ${PLATFORM_PATH}/output_files/libs/external - WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/gtest/) -execute_process(COMMAND mv ${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googlemock/lib/libgtest.a ${EXTERNAL_LIBS_OUTPUT_PATH}/libgtest.a - WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/gtest/) -execute_process(COMMAND mv ${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googlemock/lib/libgmock.a ${EXTERNAL_LIBS_OUTPUT_PATH}/libgmock.a - WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/gtest/) +if (EXISTS "${EXTERNAL_LIBS_OUTPUT_PATH}/libgtest.a") + message("googletest compile ok.") +else() + execute_process(COMMAND sh build_gtest.sh ${TARGET_PLATFORM} ${PLATFORM_PATH} ${PLATFORM_PATH} WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/gtest/) + execute_process(COMMAND mkdir ${PLATFORM_PATH}/output_files + WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/gtest/) + execute_process(COMMAND mkdir ${PLATFORM_PATH}/output_files/libs + WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/gtest/) + execute_process(COMMAND mkdir ${PLATFORM_PATH}/output_files/libs/external + WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/gtest/) + execute_process(COMMAND mv ${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googlemock/lib/libgtest.a ${EXTERNAL_LIBS_OUTPUT_PATH}/libgtest.a + WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/gtest/) + execute_process(COMMAND mv ${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googlemock/lib/libgmock.a ${EXTERNAL_LIBS_OUTPUT_PATH}/libgmock.a + WORKING_DIRECTORY ${EXTERNAL_SOURCE_PATH}/gtest/) +endif() if(${TARGET_PLATFORM} MATCHES ${DEFINE_LINUX}) message("linux mock api will be set.") diff --git a/test/middleware/LedTest/src/Led_Test.cpp b/test/middleware/LedTest/src/Led_Test.cpp index d048192f..78edbe61 100644 --- a/test/middleware/LedTest/src/Led_Test.cpp +++ b/test/middleware/LedTest/src/Led_Test.cpp @@ -14,7 +14,7 @@ TEST(Led_Test, Demo) IDeviceManager::GetInstance()->Init(); LedState _Led_State = LED_STATE_RED; - IDeviceManager::GetInstance()->ISetLedState("Led_testing", _Led_State, 10, 0); + IDeviceManager::GetInstance()->SetLedState("Led_testing", _Led_State, 10, 0); IDeviceManager::GetInstance()->UnInit(); } diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index a64cb10d..9e595ba6 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -10,3 +10,5 @@ add_subdirectory(LinuxApi) add_subdirectory(WebServer) add_subdirectory(McuProtocol) add_subdirectory(ModBusCRC16) +add_subdirectory(LedControl) +add_subdirectory(KeyControl) \ No newline at end of file diff --git a/utils/KeyControl/CMakeLists.txt b/utils/KeyControl/CMakeLists.txt new file mode 100644 index 00000000..414fdf85 --- /dev/null +++ b/utils/KeyControl/CMakeLists.txt @@ -0,0 +1,55 @@ +include(${CMAKE_SOURCE_DIR_IPCSDK}/build/global_config.cmake) +set(EXECUTABLE_OUTPUT_PATH ${EXEC_OUTPUT_PATH}) +set(LIBRARY_OUTPUT_PATH ${LIBS_OUTPUT_PATH}) + +include_directories( + ./src + ./include + # ${UTILS_SOURCE_PATH}/LinuxApi/include + ${UTILS_SOURCE_PATH}/StatusCode/include + ${UTILS_SOURCE_PATH}/ModBusCRC16/include + ${UTILS_SOURCE_PATH}/Log/include +) +# link_directories( +# ${EXTERNAL_SOURCE_PATH}/libconfig/libconfig-1.7.3/lib/.libs +# ) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +aux_source_directory(./src SRC_FILES) + +set(TARGET_NAME KeyControl) +add_library(${TARGET_NAME} STATIC ${SRC_FILES}) +target_link_libraries(${TARGET_NAME} StatusCode Log) + +if ("${CLANG_TIDY_SUPPORT}" MATCHES "true") +add_custom_target( + KeyControl_code_check + COMMAND ${CLANG_TIDY_EXE} + -checks='${CLANG_TIDY_CHECKS}' + --header-filter=.* + --system-headers=false + ${SRC_FILES} + ${CLANG_TIDY_CONFIG} + -p ${PLATFORM_PATH}/cmake-shell + WORKING_DIRECTORY ${UTILS_SOURCE_PATH}/KeyControl +) +file(GLOB_RECURSE HEADER_FILES *.h) +add_custom_target( + KeyControl_code_format + COMMAND ${CLANG_FORMAT_EXE} + -style=file + -i ${SRC_FILES} ${HEADER_FILES} + WORKING_DIRECTORY ${UTILS_SOURCE_PATH}/KeyControl +) +add_custom_command( + TARGET ${TARGET_NAME} + PRE_BUILD + COMMAND make KeyControl_code_check + COMMAND make KeyControl_code_format + WORKING_DIRECTORY ${PLATFORM_PATH}/cmake-shell/ +) +endif() + +define_file_name(${TARGET_NAME}) \ No newline at end of file diff --git a/utils/KeyControl/include/KeyControl.h b/utils/KeyControl/include/KeyControl.h new file mode 100644 index 00000000..691346db --- /dev/null +++ b/utils/KeyControl/include/KeyControl.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2023 Fancy Code. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef KEY_CONTROL_H +#define KEY_CONTROL_H +#include +#include +#include +constexpr long int KEY_DO_NOT_HOLD_PRESSING = -1; +constexpr int PERIPHERAL_CHECK_PERIOD_MS = 100; +constexpr int KEY_ACTION_LONG_CLICK = 1000 * 5; +constexpr int KEY_ACTION_SHORT_CLICK = 200; +constexpr int KEY_ACTION_HOLD_DWON = 500; +constexpr long int KEY_NOT_PRESSING = -1; +enum class KeyHalEvent +{ + PRESSING = 0, + NOT_PRESSING, + END +}; +enum class KeyEvent +{ + SHORT_CLICK = 0, + HOLD_DOWN, + HOLD_UP, + END +}; +class VKeyHal +{ +public: + VKeyHal() = default; + virtual ~VKeyHal() = default; + virtual void KeyEventTrigger(const KeyHalEvent &event) {} + virtual void TimerKeyEventTrigger(const KeyHalEvent &event) {} + virtual long int GetHoldPressingTimeMs(void) { return KEY_DO_NOT_HOLD_PRESSING; } +}; +class VKeyControl +{ +public: + VKeyControl() = default; + virtual ~VKeyControl() = default; + // virtual void SetKeyHalOwner(std::shared_ptr owner) {} + virtual const std::string GetKeyName(void) { return "undefine"; } +}; +using KeyActionReport = std::function; +class KeyControl : public VKeyControl, public VKeyHal, public std::enable_shared_from_this +{ +public: + KeyControl(); + KeyControl(std::shared_ptr &keyHal, const KeyActionReport &keyAction, + const long int &longClickTime = KEY_ACTION_LONG_CLICK); + ~KeyControl(); + void KeyEventTrigger(const KeyHalEvent &event) override; + void TimerKeyEventTrigger(const KeyHalEvent &event) override; + long int GetHoldPressingTimeMs(void) override; + void Init(void); + void UnInit(void); + void ActionReport(const std::string &key, const KeyHalEvent &keyEvent); + +private: + void KeyPressingTrigger(const std::string &key); + void KeyNotPressingTrigger(const std::string &key); + bool IsKeyPressing(void); + +private: + std::mutex mMutex; + // std::shared_ptr mKeyHal; + KeyActionReport mKeyActionReport; + long int mPressingTime; + long int mLongClickTime; +}; +#endif \ No newline at end of file diff --git a/utils/KeyControl/src/KeyControl.cpp b/utils/KeyControl/src/KeyControl.cpp new file mode 100644 index 00000000..7d9848d2 --- /dev/null +++ b/utils/KeyControl/src/KeyControl.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2023 Fancy Code. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "KeyControl.h" +#include "ILog.h" +constexpr long int KEY_PRESSING = 0; +constexpr unsigned int NOT_A_HOLD_KEY_ACTION = 0; +KeyControl::KeyControl() +{ + // mKeyHal = nullptr; + mKeyActionReport = nullptr; + mPressingTime = KEY_NOT_PRESSING; + mLongClickTime = 0; +} +KeyControl::KeyControl(std::shared_ptr &keyHal, const KeyActionReport &keyAction, + const long int &longClickTime) + : mKeyActionReport(keyAction), mLongClickTime(longClickTime) +{ + mPressingTime = KEY_NOT_PRESSING; +} +KeyControl::~KeyControl() {} +void KeyControl::KeyEventTrigger(const KeyHalEvent &event) +{ + std::lock_guard locker(mMutex); + ActionReport(GetKeyName(), event); +} +void KeyControl::TimerKeyEventTrigger(const KeyHalEvent &event) +{ + std::lock_guard locker(mMutex); + if (IsKeyPressing()) { + ActionReport(GetKeyName(), event); + } +} +long int KeyControl::GetHoldPressingTimeMs(void) { return mPressingTime; } +bool KeyControl::IsKeyPressing(void) { return mPressingTime >= KEY_PRESSING ? true : false; } +// void KeyControl::Init(void) { SetKeyHalOwner(shared_from_this()); } +void KeyControl::UnInit(void) {} +void KeyControl::ActionReport(const std::string &key, const KeyHalEvent &keyEvent) +{ + if (KEY_PRESSING <= mPressingTime) { + mPressingTime += PERIPHERAL_CHECK_PERIOD_MS; + } + switch (keyEvent) { + case KeyHalEvent::PRESSING: + KeyPressingTrigger(key); + break; + case KeyHalEvent::NOT_PRESSING: + KeyNotPressingTrigger(key); + break; + + default: + break; + } +} +void KeyControl::KeyPressingTrigger(const std::string &key) +{ + if (mLongClickTime <= mPressingTime) // Do not support long click, it should be count in application code. + { + if (mKeyActionReport) { + // mKeyActionReport(key, KeyEvent::SF_KEY_ACTION_LONG_CLICK, NOT_A_HOLD_KEY_ACTION); + } + } + if (mPressingTime != KEY_NOT_PRESSING && mPressingTime % KEY_ACTION_HOLD_DWON == 0) { + if (mKeyActionReport) { + mKeyActionReport(key, KeyEvent::HOLD_DOWN, mPressingTime); + } + } + if (KEY_NOT_PRESSING == mPressingTime) { + mPressingTime = KEY_PRESSING; + } +} +void KeyControl::KeyNotPressingTrigger(const std::string &key) +{ + if (KEY_ACTION_SHORT_CLICK <= mPressingTime && mPressingTime < KEY_ACTION_HOLD_DWON) { + if (mKeyActionReport) { + mKeyActionReport(key, KeyEvent::SHORT_CLICK, NOT_A_HOLD_KEY_ACTION); + } + } + if (KEY_ACTION_HOLD_DWON <= mPressingTime) { + if (mKeyActionReport) { + mKeyActionReport(key, KeyEvent::HOLD_UP, mPressingTime); + } + } + mPressingTime = KEY_NOT_PRESSING; +} \ No newline at end of file diff --git a/utils/LedControl/CMakeLists.txt b/utils/LedControl/CMakeLists.txt new file mode 100644 index 00000000..99dd892a --- /dev/null +++ b/utils/LedControl/CMakeLists.txt @@ -0,0 +1,55 @@ +include(${CMAKE_SOURCE_DIR_IPCSDK}/build/global_config.cmake) +set(EXECUTABLE_OUTPUT_PATH ${EXEC_OUTPUT_PATH}) +set(LIBRARY_OUTPUT_PATH ${LIBS_OUTPUT_PATH}) + +include_directories( + ./src + ./include + # ${UTILS_SOURCE_PATH}/LinuxApi/include + ${UTILS_SOURCE_PATH}/StatusCode/include + ${UTILS_SOURCE_PATH}/ModBusCRC16/include + ${UTILS_SOURCE_PATH}/Log/include +) +# link_directories( +# ${EXTERNAL_SOURCE_PATH}/libconfig/libconfig-1.7.3/lib/.libs +# ) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +aux_source_directory(./src SRC_FILES) + +set(TARGET_NAME LedControl) +add_library(${TARGET_NAME} STATIC ${SRC_FILES}) +target_link_libraries(${TARGET_NAME} StatusCode Log) + +if ("${CLANG_TIDY_SUPPORT}" MATCHES "true") +add_custom_target( + LedControl_code_check + COMMAND ${CLANG_TIDY_EXE} + -checks='${CLANG_TIDY_CHECKS}' + --header-filter=.* + --system-headers=false + ${SRC_FILES} + ${CLANG_TIDY_CONFIG} + -p ${PLATFORM_PATH}/cmake-shell + WORKING_DIRECTORY ${UTILS_SOURCE_PATH}/LedControl +) +file(GLOB_RECURSE HEADER_FILES *.h) +add_custom_target( + LedControl_code_format + COMMAND ${CLANG_FORMAT_EXE} + -style=file + -i ${SRC_FILES} ${HEADER_FILES} + WORKING_DIRECTORY ${UTILS_SOURCE_PATH}/LedControl +) +add_custom_command( + TARGET ${TARGET_NAME} + PRE_BUILD + COMMAND make LedControl_code_check + COMMAND make LedControl_code_format + WORKING_DIRECTORY ${PLATFORM_PATH}/cmake-shell/ +) +endif() + +define_file_name(${TARGET_NAME}) \ No newline at end of file diff --git a/utils/LedControl/include/LedControl.h b/utils/LedControl/include/LedControl.h new file mode 100644 index 00000000..b5a3c398 --- /dev/null +++ b/utils/LedControl/include/LedControl.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2023 Fancy Code. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LED_CONTROL_H +#define LED_CONTROL_H +#include "StatusCode.h" +#include +#include +constexpr unsigned int NEW_TOP_LED_STATE = 0; +constexpr unsigned int LED_NOT_BLINK = 0; +constexpr unsigned int BLINKING_FAST_MS = 500; +constexpr unsigned int BLINKING_SLOW_MS = 1000; +constexpr long int KEEP_ALIVE_FOREVER = 0; +constexpr unsigned int DELETED_LED_STATE = -1; +constexpr unsigned int DO_NOT_KEEP_ALIVE = -2; +enum class LedState +{ + OFF = 0, + ON, + GREEN, + RED, + YELLOW, + LEVEL_0, + LEVEL_1, + LEVEL_2, + LEVEL_3, + LEVEL_4, + LEVEL_END, + END +}; +class VSingleControl +{ +public: + VSingleControl() = default; + virtual ~VSingleControl() = default; + virtual StatusCode GetLedState(LedState &state) { return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION); } + virtual unsigned int GetKeepAliveTimeMs(void) { return KEEP_ALIVE_FOREVER; } + virtual unsigned int GetBlinkTimeMs(void) { return LED_NOT_BLINK; } +}; +class VLedControl +{ +public: + VLedControl() = default; + virtual ~VLedControl() = default; + virtual bool SetLedState(const LedState &state) { return false; } +}; +class LedControl : virtual public VLedControl +{ +public: + LedControl() = default; + virtual ~LedControl() = default; + void AddLedState(std::shared_ptr &state); + void CheckState(const unsigned int &period); + +private: + void NewLedStateStart(void); + void DeleteTopLedState(void); + void BlinkOff(std::shared_ptr &state); + void BlinkOn(std::shared_ptr &state, const LedState &onState); + +private: + std::vector> mStates; + LedState mCurrentState; + unsigned int mStateAliveTime; + unsigned int mBlinkPeriod; +}; +#endif \ No newline at end of file diff --git a/utils/LedControl/src/LedControl.cpp b/utils/LedControl/src/LedControl.cpp new file mode 100644 index 00000000..6acf7a84 --- /dev/null +++ b/utils/LedControl/src/LedControl.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2023 Fancy Code. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "LedControl.h" +#include "ILog.h" +void LedControl::AddLedState(std::shared_ptr &state) +{ + LogInfo("Add led state.\n"); + NewLedStateStart(); + LedState ledState = LedState::END; + state->GetLedState(ledState); + SetLedState(ledState); + mCurrentState = ledState; + if (DO_NOT_KEEP_ALIVE == state->GetKeepAliveTimeMs()) { + return; + } + mStates.push_back(state); +} +void LedControl::CheckState(const unsigned int &period) +{ + const int TOP_STATE_SHOW = mStates.size() - 1; + mStateAliveTime += period; + mBlinkPeriod += period; + if (TOP_STATE_SHOW >= 0) { + // LogInfo("TOP_STATE_SHOW = %d.\n", TOP_STATE_SHOW); + std::shared_ptr state = mStates[TOP_STATE_SHOW]; + LedState ledState = LedState::END; + if (state->GetKeepAliveTimeMs() == DELETED_LED_STATE || + (state->GetKeepAliveTimeMs() != KEEP_ALIVE_FOREVER && state->GetKeepAliveTimeMs() <= mStateAliveTime)) { + DeleteTopLedState(); + return; + } + state->GetLedState(ledState); + if (mCurrentState != ledState && LED_NOT_BLINK == state->GetBlinkTimeMs()) { + SetLedState(ledState); + mCurrentState = ledState; + } + else if (mCurrentState == ledState && state->GetBlinkTimeMs() != LED_NOT_BLINK) { + BlinkOff(state); + } + else if (mCurrentState == LedState::OFF && state->GetBlinkTimeMs() != LED_NOT_BLINK) { + BlinkOn(state, ledState); + } + } +} +void LedControl::NewLedStateStart(void) +{ + mCurrentState = LedState::END; + mStateAliveTime = NEW_TOP_LED_STATE; + mBlinkPeriod = 0; +} +void LedControl::DeleteTopLedState(void) +{ + const int TOP_STATE_SHOW = mStates.size() - 1; + if (TOP_STATE_SHOW < 0) { + return; + } + LogInfo("Delete led state.\n"); + NewLedStateStart(); + mStates.erase(mStates.begin() + TOP_STATE_SHOW); + const int NEXT_LED_STATE = mStates.size() - 1; + if (NEXT_LED_STATE < 0) { + return; + } + LogInfo("Top next led state.\n"); + std::shared_ptr state = mStates[NEXT_LED_STATE]; + LedState ledState = LedState::END; + state->GetLedState(ledState); + SetLedState(ledState); + mCurrentState = ledState; +} +void LedControl::BlinkOff(std::shared_ptr &state) +{ + if (state->GetBlinkTimeMs() < mBlinkPeriod) { + // LogInfo("blink off.\n"); + SetLedState(LedState::OFF); + mCurrentState = LedState::OFF; + mBlinkPeriod = 0; + } +} +void LedControl::BlinkOn(std::shared_ptr &state, const LedState &onState) +{ + if (state->GetBlinkTimeMs() < mBlinkPeriod) { + // LogInfo("blink on.\n"); + SetLedState(onState); + mCurrentState = onState; + mBlinkPeriod = 0; + } +} \ No newline at end of file diff --git a/utils/README.md b/utils/README.md new file mode 100644 index 00000000..869d9b8a --- /dev/null +++ b/utils/README.md @@ -0,0 +1,13 @@ +# 1. utils工具类库 + +  工具类库,常用的功能单一的通用的功能独立模块或者半功能模块。 + +## 1.1. 完整功能工具类库 + +  暴露头文件中的接口提供且仅提供了完整的独立功能的接口,使用者可直接使用完整的工具功能。往往暴露的头文件不会存在多余的用户数据接口和结构。 + +## 1.2. 半功能工具类库 + +  暴露头文件中的接口无法完成独立功能,往往带着部分未实现的虚函数,需要使用者重载才能实现完整功能。 + +  例如:McuProtocol类库,需要与读写数据模块组合封装成新类才能实现一个独立功能的模块。McuProtocol模块只完成了协议数据的组包和协议数据包的解析功能,需要与协议的读取/读取方式的模块组合封装成一个完整的功能模块。这样设计的初衷是让协议的处理和协议的收发解耦合,可以快速更换协议版本或者替换数据收发功能模块。 \ No newline at end of file