From 7c7827fddb7de9a61c098198cd2c9f2c97dec642 Mon Sep 17 00:00:00 2001 From: ovizro Date: Fri, 27 Dec 2024 20:49:00 +0800 Subject: [PATCH] refactor(event): optimize event handling and remove inicpp dependency - Update event handling logic for better performance - Remove unused inicpp dependency - Fix typos and improve code readability - Update build script for better portability --- README.md | 2 +- include/external_interface_event.h | 2 +- include/inicpp.hpp | 687 ----------------------------- mak | 13 +- src/event.cpp | 13 +- src/external_interface.cpp | 2 +- tests/test_event.cpp | 2 + 7 files changed, 18 insertions(+), 703 deletions(-) delete mode 100644 include/inicpp.hpp diff --git a/README.md b/README.md index adc2b2f..b67d35f 100644 --- a/README.md +++ b/README.md @@ -46,4 +46,4 @@ cmake --build build -j6 --target test - `type`:数据包类型 - `len`:数据包长度,对于字符串类型数据应包含后缀`\0`的长度。 - `data`:数据包数据 -6. `void exint_finialize()`:模块销毁函数,调用后模块会终止所有内部线程,释放所有资源。 +6. `void exint_finalize()`:模块销毁函数,调用后模块会终止所有内部线程,释放所有资源。 diff --git a/include/external_interface_event.h b/include/external_interface_event.h index b1c1acb..ca113a4 100644 --- a/include/external_interface_event.h +++ b/include/external_interface_event.h @@ -27,12 +27,12 @@ typedef struct _EventTrigger { uint8_t args[ET_EVENT_TRIGGER_BUFFER_SIZE]; } EventTrigger; -#define EXINT_EVENT_PUBLIC static __inline #ifndef EXINT_EVENT #define EXINT_EVENT_PUBLIC_FUNC_NAME(name) exint_ ## name #else #define EXINT_EVENT_PUBLIC_FUNC_NAME(name) exint_public_ ## name #endif +#define EXINT_EVENT_PUBLIC static __inline #define EXINT_EVENT_PUBLIC_FUNC(name) EXINT_EVENT_PUBLIC void EXINT_EVENT_PUBLIC_FUNC_NAME(name) EXINT_EVENT_PUBLIC_FUNC(event) diff --git a/include/inicpp.hpp b/include/inicpp.hpp deleted file mode 100644 index f3cd06e..0000000 --- a/include/inicpp.hpp +++ /dev/null @@ -1,687 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2023 dujingning - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef __JN_INICPP_H__ -#define __JN_INICPP_H__ - -#include - -#include -#include -#include -#include -#include - -// for std::string <==> std::wstring convert -#include -#include - -#ifdef INICPP_DEBUG - -#include -#include -#include - -class TimeFormatter -{ -public: - static std::string format(const std::string &format = "%Y-%m-%d %H:%M:%S") - { - std::time_t t = std::time(nullptr); - std::tm tm = *std::localtime(&t); - std::array buffer; - std::strftime(buffer.data(), buffer.size(), format.c_str(), &tm); - return buffer.data(); - } -}; - -#define CODE_INFO std::string(" | Code:\'file:") + std::string(__FILE__) + ",function:" + std::string(__FUNCTION__) + ",line:" + std::to_string(__LINE__) + '\'' -#define INI_DEBUG(x) std::cout << "INICPP " << TimeFormatter::format() << " : " << x << CODE_INFO << std::endl - -#else // #ifdef INICPP_DEBUG -#define INI_DEBUG(x) -#endif // #ifdef INICPP_DEBUG - -namespace inicpp -{ - - typedef struct KeyValueNode - { - std::string Value = ""; - int lineNumber = -1; // text line start with 1 - } KeyValueNode; - - class section - { - public: - section() : _sectionName() - { - } - - explicit section(const std::string §ionName) : _sectionName(sectionName) - { - } - - const std::string &name() - { - return _sectionName; - } - - const std::string getValue(const std::string &Key) - { - if (!_sectionMap.count(Key)) - { - return ""; - } - return _sectionMap[Key].Value; - } - - void setName(const std::string &name, const int &lineNumber) - { - _sectionName = name; - _lineNumber = lineNumber; - } - - void setValue(const std::string &Key, const std::string &Value, const int line) - { - _sectionMap[Key].Value = Value; - _sectionMap[Key].lineNumber = line; - } - - void append(section &sec) - { - _sectionMap.insert(sec._sectionMap.begin(), sec._sectionMap.end()); - } - - bool isKeyExist(const std::string &Key) - { - return !_sectionMap.count(Key) ? false : true; - } - - int getEndSection() - { - int line = -1; - - if (_sectionMap.empty() && _sectionName != "") - { - return _lineNumber; - } - - for (const auto &data : _sectionMap) - { - if (data.second.lineNumber > line) - { - line = data.second.lineNumber; - } - } - return line; - } - - int getLine(const std::string &Key) - { - if (!_sectionMap.count(Key)) - { - return -1; - } - return _sectionMap[Key].lineNumber; - } - - const std::string operator[](const std::string &Key) - { - if (!_sectionMap.count(Key)) - { - return ""; - } - return _sectionMap[Key].Value; - } - - void clear() - { - _lineNumber = -1; - _sectionName.clear(); - _sectionMap.clear(); - } - - bool isEmpty() const - { - return _sectionMap.empty(); - } - - int toInt(const std::string &Key) - { - if (!_sectionMap.count(Key)) - { - return 0; - } - - int result = 0; - - try - { - result = std::stoi(_sectionMap[Key].Value); - } - catch (const std::invalid_argument &e) - { - INI_DEBUG("Invalid argument: " << e.what() << ",input:\'" << _sectionMap[Key].Value << "\'"); - } - catch (const std::out_of_range &e) - { - INI_DEBUG("Out of range: " << e.what() << ",input:\'" << _sectionMap[Key].Value << "\'"); - } - - return result; - } - - std::string toString(const std::string &Key) - { - if (!_sectionMap.count(Key)) - { - return ""; - } - return _sectionMap[Key].Value; - } - - std::wstring toWString(const std::string &Key) - { - std::wstring_convert> converter; - return converter.from_bytes(toString(Key)); - } - - double toDouble(const std::string &Key) - { - if (!_sectionMap.count(Key)) - { - return 0.0; - } - - double result = 0.0; - - try - { - result = std::stod(_sectionMap[Key].Value); - } - catch (const std::invalid_argument &e) - { - INI_DEBUG("Invalid argument: " << e.what() << ",input:\'" << _sectionMap[Key].Value << "\'"); - } - catch (const std::out_of_range &e) - { - INI_DEBUG("Out of range: " << e.what() << ",input:\'" << _sectionMap[Key].Value << "\'"); - } - - return result; - } - - // todo : add toString() / toInt() / toDouble() - - private: - std::string _sectionName; - std::map _sectionMap; - int _lineNumber = -1; // text line start with 1 - }; - - class ini - { - public: - void addSection(section &sec) - { - if (_iniInfoMap.count(sec.name())) // if exist,need to merge - { - _iniInfoMap[sec.name()].append(sec); - return; - } - _iniInfoMap.emplace(sec.name(), sec); - return; - } - - void removeSection(const std::string §ionName) - { - if (!_iniInfoMap.count(sectionName)) - { - return; - } - _iniInfoMap.erase(sectionName); - return; - } - - bool isSectionExists(const std::string §ionName) - { - return !_iniInfoMap.count(sectionName) ? false : true; - } - - // may contains default of Unnamed section with "" - std::list getSectionsList() - { - std::list sectionList; - for (const auto &data : _iniInfoMap) - { - if (data.first == "" && data.second.isEmpty()) // default section: no section name,if empty,not count it. - { - continue; - } - sectionList.emplace_back(data.first); - } - return sectionList; - } - - const section &operator[](const std::string §ionName) - { - if (!_iniInfoMap.count(sectionName)) - { - return _iniInfoMap[""]; - } - return _iniInfoMap[sectionName]; - } - - inline std::size_t getSectionSize() - { - return _iniInfoMap.size(); - } - - std::string getValue(const std::string §ionName, const std::string &Key) - { - if (!_iniInfoMap.count(sectionName)) - { - return ""; - } - return _iniInfoMap[sectionName][Key]; - } - - // for none section - int getLine(const std::string &Key) - { - if (!_iniInfoMap.count("")) - { - return -1; - } - return _iniInfoMap[""].getLine(Key); - } - - // for section-key - int getLine(const std::string §ionName, const std::string &Key) - { - if (!_iniInfoMap.count(sectionName)) - { - return -1; - } - return _iniInfoMap[sectionName].getLine(Key); - } - - inline void clear() { _iniInfoMap.clear(); } - inline bool empty() { return _iniInfoMap.empty(); } - - protected: - std::map _iniInfoMap; - }; - - // todo if file is modified,never write back - class IniManager - { - public: - explicit IniManager(const std::string &configFileName) : _configFileName(configFileName) - { - parse(); - } - - ~IniManager() - { - _iniFile.close(); - } - - section operator[](const std::string §ionName) - { - return _iniData[sectionName]; - } - - void parse() - { - _iniFile.open(_configFileName, std::ifstream::in | std::ifstream::out | std::fstream::app); - if (!_iniFile.is_open()) - { - INI_DEBUG("Failed to open the input INI file for parsing!"); - return; - } - - _iniData.clear(); - - _iniFile.seekg(0, _iniFile.beg); - std::string data, sectionName; - int sectionLine = -1; - - section sectionRecord; - - _SumOfLines = 1; - do - { - std::getline(_iniFile, data); - - if (!filterData(data)) - { - ++_SumOfLines; - continue; - } - - if (data.find('[') == 0) // section - { - if (!sectionRecord.isEmpty() || sectionRecord.name() != "") - { - _iniData.addSection(sectionRecord); - } - - size_t first = data.find('['); - size_t last = data.find(']'); - - if (last == std::string::npos) - { - ++_SumOfLines; - continue; - } - - sectionName = data.substr(first + 1, last - first - 1); - sectionLine = _SumOfLines; - - sectionRecord.clear(); - sectionRecord.setName(sectionName, sectionLine); - } - - size_t pos = data.find('='); - if (pos != std::string::npos) - { // k=v - std::string key = data.substr(0, pos); - std::string value = data.substr(pos + 1); - - trimEdges(key); - trimEdges(value); - - sectionRecord.setValue(key, value, _SumOfLines); - } - - ++_SumOfLines; - - } while (!_iniFile.eof()); - - if (!sectionRecord.isEmpty()) - { - sectionRecord.setName(sectionName, -1); - _iniData.addSection(sectionRecord); - } - - if (_iniFile.is_open()) - { - _iniFile.close(); - } - } - - bool modify(const std::string &Section, const std::string &Key, const std::string &Value, const std::string &comment = "") - { // todo: insert comment before k=v - parse(); - - if (Key == "" || Value == "") - { - INI_DEBUG("Invalid parameter input: Key[" << Key << "],Value[" << Value << "]"); - return false; - } - - std::string keyValueData = Key + "=" + Value + "\n"; - if (comment.length() > 0) - { - keyValueData = comment + "\n" + keyValueData; - if (comment[0] != ';') - { - keyValueData = ";" + keyValueData; - } - } - - const std::string &tempFile = ".temp.ini"; - std::fstream input(_configFileName, std::ifstream::in | std::ifstream::out | std::fstream::app); - std::ofstream output(tempFile); - - if (!input.is_open()) - { - INI_DEBUG("Failed to open the input INI file for modification!"); - return false; - } - - if (!output.is_open()) - { - INI_DEBUG("Failed to open the input INI file for modification!"); - return false; - } - - int line_number_mark = -1; - bool isInputDataWited = false; - - do - { - // exist key at one section replace it, or need to create it - if (_iniData.isSectionExists(Section)) - { - line_number_mark = (*this)[Section].getLine(Key); - - if (line_number_mark == -1) - { // section exist, key not exist - line_number_mark = (*this)[Section].getEndSection(); - - std::string lineData; - int input_line_number = 0; - while (std::getline(input, lineData)) - { - ++input_line_number; - - if (input_line_number == (line_number_mark + 1)) - { // new line,append to next line - isInputDataWited = true; - output << keyValueData; - } - - output << lineData << "\n"; - } - - if (input.eof() && !isInputDataWited) - { - isInputDataWited = true; - output << keyValueData; - } - - break; - } - } - - if (line_number_mark <= 0) // not found key at config file - { - input.seekg(0, input.beg); - - bool isHoldSection = false; - std::string newLine = "\n\n"; - if (Section != "" && Section.find("[") == std::string::npos && Section.find("]") == std::string::npos && Section.find("=") == std::string::npos) - { - if (_iniData.empty() || _iniData.getSectionSize() <= 0) - { - newLine.clear(); - } - - isHoldSection = true; - } - - // 1.section is exist or empty section - if (_iniData.isSectionExists(Section) || Section == "") - { - // write key/value to head - if (isHoldSection) - { - output << newLine << "[" << Section << "]" << "\n"; - } - output << keyValueData; - // write others - std::string lineData; - while (std::getline(input, lineData)) - { - output << lineData << "\n"; - } - } - // 2.section is not exist - else - { - // write others - std::string lineData; - while (std::getline(input, lineData)) - { - output << lineData << "\n"; - } - // write key/value to end - if (isHoldSection) - { - output << newLine << "[" << Section << "]" << "\n"; - } - output << keyValueData; - } - - break; - } - else - { // found, replace it - - std::string lineData; - int input_line_number = 0; - - while (std::getline(input, lineData)) - { - ++input_line_number; - - // delete old comment if new comment is set - if (input_line_number == (line_number_mark - 1) && lineData.length() > 0 && lineData[0] == ';' && comment != "") - { - continue; - } - - if (input_line_number == line_number_mark) - { // replace to this line - output << keyValueData; - } - else - { - output << lineData << "\n"; - } - } - break; - } - - INI_DEBUG("error! inicpp lost process of modify function"); - return false; - - } while (false); - - // clear work - input.close(); - output.close(); - - std::remove(_configFileName.c_str()); - std::rename(tempFile.c_str(), _configFileName.c_str()); - - // reload - parse(); - - return true; - } - - bool modify(const std::string &Section, const std::string &Key, const int &Value, const std::string &comment = "") - { - std::string stringValue = std::to_string(Value); - return modify(Section, Key, stringValue, comment); - } - - bool modify(const std::string &Section, const std::string &Key, const double &Value, const std::string &comment = "") - { - std::string stringValue = std::to_string(Value); - return modify(Section, Key, stringValue, comment); - } - - bool modify(const std::string &Section, const std::string &Key, const std::wstring &Value, const std::string &comment = "") - { - std::wstring_convert> converter; - std::string stringValue = converter.to_bytes(Value); - - return modify(Section, Key, stringValue, comment); - } - - bool modifyComment(const std::string &Section, const std::string &Key, const std::string &comment) - { - return modify(Section, Key, (*this)[Section][Key], comment); - } - - bool isSectionExists(const std::string §ionName) - { - return _iniData.isSectionExists(sectionName); - } - - inline std::list getSectionsList() - { - return _iniData.getSectionsList(); - } - - private: - bool filterData(std::string &data) - { - if (data.length() == 0) - { - return false; - } - - if (data[0] == ';') - { - return false; - } - - if (data[0] == '#') - { - return false; - } - - return true; - } - - void trimEdges(std::string &data) - { - // remove left ' ' and '\t' - data.erase(data.begin(), std::find_if(data.begin(), data.end(), [](unsigned char c) - { return !std::isspace(c); })); - // remove right ' ' and '\t' - data.erase(std::find_if(data.rbegin(), data.rend(), [](unsigned char c) - { return !std::isspace(c); }) - .base(), - data.end()); - - INI_DEBUG( "trimEdges data:|" << data << "|"); - } - - private: - ini _iniData; - int _SumOfLines; - std::fstream _iniFile; - std::string _configFileName; - }; - -} - -#endif diff --git a/mak b/mak index 1b75115..3b5694c 100755 --- a/mak +++ b/mak @@ -1,5 +1,8 @@ #!/bin/bash -mkdir -p build && cd $(dirname $0)/build +set -e + +BASEDIR=$(cd "$(dirname "$0")"; pwd) +mkdir -p ${BASEDIR}/build && cd ${BASEDIR}/build if echo "$@" | grep -iq r; then BUILD_TYPE=RELEASE @@ -9,15 +12,15 @@ fi if echo "$@" | grep -iq e; then #------ compile for euler ------------------- - TOOLCHAIN=../../toolchains/armv7l_openeuler_setup.cmake + TOOLCHAIN=${BASEDIR}/toolchains/armv7l_openeuler_setup.cmake BUILD_PREFIX=armv7l-openeular else #------- compile for arm32 ------------------ - TOOLCHAIN=../../toolchains/armv7l_linux_setup.cmake + TOOLCHAIN=${BASEDIR}/toolchains/armv7l_linux_setup.cmake BUILD_PREFIX=armv7l-linux fi mkdir -p ${BUILD_PREFIX} && cd ${BUILD_PREFIX} rm -f CMakeCache.txt -cmake -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN} -DEXECUTABLE_OUTPUT_PATH=../../bin/${BUILD_PREFIX} -DLIBRARY_OUTPUT_PATH=../../lib/${BUILD_PREFIX} ../.. -cmake --build . -j 4 -- +cmake -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN} -DEXECUTABLE_OUTPUT_PATH=${BASEDIR}/bin/${BUILD_PREFIX} -DLIBRARY_OUTPUT_PATH=${BASEDIR}/lib/${BUILD_PREFIX} ../.. +cmake --build . -j 6 -- diff --git a/src/event.cpp b/src/event.cpp index 2461738..d7bfe84 100644 --- a/src/event.cpp +++ b/src/event.cpp @@ -29,20 +29,17 @@ void exint_event(const char *event_name, size_t args_size, void *args) { logger.warn("Event '%s' not found", event_name); return; } - std::shared_ptr data(new uint8_t[args_size]); - memcpy(data.get(), args, args_size); + std::shared_ptr data; for (auto &pair : it->second) { if (!_event_thread_count.load()) { + logger.debug("Run event %s synchronous", event_name); pair.first(event_name, args_size, args, pair.second); continue; } - uint8_t* args_copy; - if (args_size == 0) { - args_copy = NULL; - } else { - args_copy = new uint8_t[args_size]; - memcpy(args_copy, args, args_size); + if (!data && args_size != 0) { + data = std::shared_ptr(new uint8_t[args_size]); + memcpy(data.get(), args, args_size); } _event_queue.Push(std::make_tuple(event_name, pair.first, args_size, data, pair.second)); } diff --git a/src/external_interface.cpp b/src/external_interface.cpp index e287ef7..fe296c7 100644 --- a/src/external_interface.cpp +++ b/src/external_interface.cpp @@ -1,8 +1,8 @@ #include +#include #include "logging/logger.hpp" #include "comframe.h" #include "CCfgFileParser.h" -#include "inicpp.hpp" #include "transport/serial_port.hpp" #include "transport/udp.hpp" #include "exint/detail.hpp" diff --git a/tests/test_event.cpp b/tests/test_event.cpp index 4b5aa92..8c51529 100644 --- a/tests/test_event.cpp +++ b/tests/test_event.cpp @@ -1,6 +1,7 @@ #include #include #include +#include "logging/interface.h" #include "exint/event.h" #include "exint/detail.hpp" #include "c_testcase.h" @@ -13,6 +14,7 @@ ON_EVENT_EX(test, _test_handler, nullptr) { } SETUP { + log_set_level(LOG_LEVEL_DEBUG); g_vec.clear(); return 0; }