Key and Led control utils module.

This commit is contained in:
Fancy code 2024-02-14 11:27:43 -08:00
parent 677544e458
commit 1f862db3de
21 changed files with 569 additions and 86 deletions

View File

@ -51,4 +51,6 @@ add_custom_command(
COMMAND make DeviceManager_code_format
WORKING_DIRECTORY ${PLATFORM_PATH}/cmake-shell/
)
endif()
endif()
define_file_name(${TARGET_NAME})

View File

@ -14,39 +14,33 @@
*/
#ifndef IDEVICEMANAGER_H
#define IDEVICEMANAGER_H
#include "ILog.h"
#include "StatusCode.h"
#include <iostream>
#include <memory>
#include <vector>
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<IDeviceManager> &GetInstance(std::shared_ptr<IDeviceManager> *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 &currentState,
const unsigned int &KeepAliveTime, const unsigned int &blinkPeriod);
};
bool CreateDeviceManagerModule(void);
#endif

View File

@ -14,6 +14,7 @@
*/
#include "DeviceManager.h"
#include "ILog.h"
#include "LedTimer.h"
#include <vector>
@ -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 &currentState,
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<LedManager> ledOut = *it;
if (ledOut->GetLedHal()->GetLedName() == ledName) {
ledOut->SetLedState(CurrentState, KeepAliveTime, BlinkPeriod);
ledOut->SetLedState(currentState, KeepAliveTime, blinkPeriod);
return CreateStatusCode(STATUS_CODE_OK);
}
}

View File

@ -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 &currentState,
const unsigned int &keepAliveTime = DEFAULT_KEEP_ALIVE_TIME,
const unsigned int &blinkPeriod = LED_NOT_BLINK) override;
private:
std::vector<std::shared_ptr<LedManager>> mLedManagers;

View File

@ -30,7 +30,13 @@ std::shared_ptr<DeviceManagerMakePtr> &DeviceManagerMakePtr::GetInstance(std::sh
{
static auto instance = std::make_shared<DeviceManagerMakePtr>();
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;
}

View File

@ -27,4 +27,11 @@ std::shared_ptr<IDeviceManager> &IDeviceManager::GetInstance(std::shared_ptr<IDe
}
}
return instance;
}
const StatusCode IDeviceManager::Init(void) { return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION); }
const StatusCode IDeviceManager::UnInit(void) { return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION); }
const StatusCode IDeviceManager::SetLedState(const std::string &ledName, const LedState &currentState,
const unsigned int &KeepAliveTime, const unsigned int &blinkPeriod)
{
return CreateStatusCode(STATUS_CODE_VIRTUAL_FUNCTION);
}

View File

@ -68,12 +68,12 @@ void KeyManager::KeyPressingTrigger(const std::string &key)
if (mLongClickTime <= mPressingTime) // Do not support long click, it should be count in application code.
{
if (mKeyActionReport) {
// mKeyActionReport(key, KeyAction::SF_KEY_ACTION_LONG_CLICK, NOT_A_HOLD_KEY_ACTION);
// 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, KeyAction::HOLD_DOWN, mPressingTime);
mKeyActionReport(key, KeyEvent::HOLD_DOWN, mPressingTime);
}
}
if (KEY_NOT_PRESSING == mPressingTime) {
@ -84,12 +84,12 @@ void KeyManager::KeyNotPressingTrigger(const std::string &key)
{
if (KEY_ACTION_SHORT_CLICK <= mPressingTime && mPressingTime < KEY_ACTION_HOLD_DWON) {
if (mKeyActionReport) {
mKeyActionReport(key, KeyAction::SHORT_CLICK, NOT_A_HOLD_KEY_ACTION);
mKeyActionReport(key, KeyEvent::SHORT_CLICK, NOT_A_HOLD_KEY_ACTION);
}
}
if (KEY_ACTION_HOLD_DWON <= mPressingTime) {
if (mKeyActionReport) {
mKeyActionReport(key, KeyAction::HOLD_UP, mPressingTime);
mKeyActionReport(key, KeyEvent::HOLD_UP, mPressingTime);
}
}
mPressingTime = KEY_NOT_PRESSING;

View File

@ -18,7 +18,7 @@
#include "IHalCpp.h"
#include <functional>
#include <mutex>
using KeyActionReport = std::function<void(const std::string &, const KeyAction &, const unsigned int &)>;
using KeyActionReport = std::function<void(const std::string &, const KeyEvent &, const unsigned int &)>;
constexpr int KEY_ACTION_LONG_CLICK = 1000 * 5;
constexpr int KEY_ACTION_SHORT_CLICK = 200;
constexpr int KEY_ACTION_HOLD_DWON = 500;

View File

@ -25,34 +25,34 @@ LedManager::LedManager()
mStateAliveTime = 0;
}
LedManager::LedManager(std::shared_ptr<VLedHal> &LedHal, const LedState &CurrentState,
const unsigned int &KeepAliveTime, const unsigned int &BlinkPeriod)
LedManager::LedManager(std::shared_ptr<VLedHal> &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<VLedHal> LedManager::GetLedHal(void) { return mLedHal; }
StatusCode LedManager::SetLedState(LedState &CurrentState, const unsigned int &KeepAliveTime,
const unsigned int &BlinkPeriod)
StatusCode LedManager::SetLedState(const LedState &currentState, 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);
// }

View File

@ -20,7 +20,7 @@
#include <functional>
#include <mutex>
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<VLedHal> &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<VLedHal> 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<VLedHal> mLedHal;
LedState mCurrentState; // 当前状态
unsigned int mBlinkPeriod; // 闪烁频率
unsigned int mKeepAliveTime; // 保持存活时间
unsigned int mStateAliveTime; // 状态保持时间
LedState mCurrentState;
unsigned int mBlinkPeriod;
unsigned int mKeepAliveTime;
unsigned int mStateAliveTime;
};
#endif

View File

@ -14,7 +14,7 @@
*/
#include "LedTimer.h"
// #include "Log.h"
#include "ILog.h"
LedTimer::LedTimer() { mTimerRuning = false; }
std::shared_ptr<LedTimer> &LedTimer::GetInstance(std::shared_ptr<LedTimer> *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> LedManager = *it;
LogInfo("%s %d count = %d\n\n", __func__, __LINE__, count++);
}
return CreateStatusCode(STATUS_CODE_OK);
}

View File

@ -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.")

View File

@ -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();
}

View File

@ -10,3 +10,5 @@ add_subdirectory(LinuxApi)
add_subdirectory(WebServer)
add_subdirectory(McuProtocol)
add_subdirectory(ModBusCRC16)
add_subdirectory(LedControl)
add_subdirectory(KeyControl)

View File

@ -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})

View File

@ -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 <functional>
#include <memory>
#include <mutex>
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<VKeyHal> owner) {}
virtual const std::string GetKeyName(void) { return "undefine"; }
};
using KeyActionReport = std::function<void(const std::string &, const KeyEvent &, const unsigned int &)>;
class KeyControl : public VKeyControl, public VKeyHal, public std::enable_shared_from_this<KeyControl>
{
public:
KeyControl();
KeyControl(std::shared_ptr<VKeyControl> &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<VKeyControl> mKeyHal;
KeyActionReport mKeyActionReport;
long int mPressingTime;
long int mLongClickTime;
};
#endif

View File

@ -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<VKeyControl> &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<std::mutex> locker(mMutex);
ActionReport(GetKeyName(), event);
}
void KeyControl::TimerKeyEventTrigger(const KeyHalEvent &event)
{
std::lock_guard<std::mutex> 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;
}

View File

@ -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})

View File

@ -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 <memory>
#include <vector>
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<VSingleControl> &state);
void CheckState(const unsigned int &period);
private:
void NewLedStateStart(void);
void DeleteTopLedState(void);
void BlinkOff(std::shared_ptr<VSingleControl> &state);
void BlinkOn(std::shared_ptr<VSingleControl> &state, const LedState &onState);
private:
std::vector<std::shared_ptr<VSingleControl>> mStates;
LedState mCurrentState;
unsigned int mStateAliveTime;
unsigned int mBlinkPeriod;
};
#endif

View File

@ -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<VSingleControl> &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<VSingleControl> 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<VSingleControl> state = mStates[NEXT_LED_STATE];
LedState ledState = LedState::END;
state->GetLedState(ledState);
SetLedState(ledState);
mCurrentState = ledState;
}
void LedControl::BlinkOff(std::shared_ptr<VSingleControl> &state)
{
if (state->GetBlinkTimeMs() < mBlinkPeriod) {
// LogInfo("blink off.\n");
SetLedState(LedState::OFF);
mCurrentState = LedState::OFF;
mBlinkPeriod = 0;
}
}
void LedControl::BlinkOn(std::shared_ptr<VSingleControl> &state, const LedState &onState)
{
if (state->GetBlinkTimeMs() < mBlinkPeriod) {
// LogInfo("blink on.\n");
SetLedState(onState);
mCurrentState = onState;
mBlinkPeriod = 0;
}
}

13
utils/README.md Normal file
View File

@ -0,0 +1,13 @@
# 1. utils工具类库
&emsp;&emsp;工具类库,常用的功能单一的通用的功能独立模块或者半功能模块。
## 1.1. 完整功能工具类库
&emsp;&emsp;暴露头文件中的接口提供且仅提供了完整的独立功能的接口,使用者可直接使用完整的工具功能。往往暴露的头文件不会存在多余的用户数据接口和结构。
## 1.2. 半功能工具类库
&emsp;&emsp;暴露头文件中的接口无法完成独立功能,往往带着部分未实现的虚函数,需要使用者重载才能实现完整功能。
&emsp;&emsp;例如McuProtocol类库需要与读写数据模块组合封装成新类才能实现一个独立功能的模块。McuProtocol模块只完成了协议数据的组包和协议数据包的解析功能需要与协议的读取/读取方式的模块组合封装成一个完整的功能模块。这样设计的初衷是让协议的处理和协议的收发解耦合,可以快速更换协议版本或者替换数据收发功能模块。