diff --git a/CMakeLists.txt b/CMakeLists.txt index f93d9c70..fcd0d41a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ message("* * * * * * * * * * * * * * * * * * * * * * * * * * * * *") cmake_minimum_required(VERSION 3.2.5) -project(CGraph VERSION 2.5.1) +project(CGraph VERSION 2.5.2) # CGraph默认使用C++11版本,推荐使用C++17版本。暂不支持C++11以下版本 set(CMAKE_CXX_STANDARD 11) diff --git a/README.md b/README.md index 4873cf39..7be6d282 100644 --- a/README.md +++ b/README.md @@ -323,8 +323,10 @@ int main() { [2023.09.15 - v2.5.1 - Chunel] * 提供`fence`(栅栏)功能 * 提供`coordinator`(协调)功能 + +[2023.09.16 - v2.5.2 - Chunel] * 优化`message`(消息)功能,可以设定写入阻塞时的处理方式 -* 添加`example`相关内容,针对不同行业,提供一些简单的实现用例 +* 添加`example`相关内容,针对不同行业,提供一些简单实现 diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index a8d10d5a..50a2896a 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -1,6 +1,7 @@ # 对应 example 中的内容 set(CGRAPH_EXAMPLE_LIST E01-AutoPilot + E02-MockGUI ) foreach(example ${CGRAPH_EXAMPLE_LIST}) diff --git a/example/E02-MockGUI.cpp b/example/E02-MockGUI.cpp new file mode 100644 index 00000000..4680b52c --- /dev/null +++ b/example/E02-MockGUI.cpp @@ -0,0 +1,104 @@ +/*************************** +@Author: Chunel +@Contact: chunel@foxmail.com +@File: E02-MockGUI.cpp +@Time: 2023/9/16 21:22 +@Desc: 本example主要展示,在不修改之前任何功能(node中的逻辑)的情况下, + 通过aspect和event功能,在界面上展示当前正在执行的node, + 模拟 GUI 中node的变亮(或者变暗)的操作。 +***************************/ + +#include +#include +#include + +#include "CGraph.h" + +using namespace CGraph; + +const static char* EXAMPLE_PARAM_KEY = "example-param-key"; +const static char* EXAMPLE_EVENT_KEY = "example-event-key"; + +struct ProcessParam : public GParam { + CVoid change(const std::string& name, bool isBegin) { + if (isBegin) { + running_elements_.insert(name); + } else { + running_elements_.erase(name); + } + } + + CVoid print() { + std::cout << "<"; + for (const auto& cur : running_elements_) { + std::cout << " " << cur << " "; + } + std::cout << "> is running..." << std::endl; + } + +protected: + std::set running_elements_; +}; + + +class ShowEvent : public GEvent { + CVoid trigger(GEventParamPtr param) override { + auto p = CGRAPH_GET_GPARAM_WITH_NO_EMPTY(ProcessParam, EXAMPLE_PARAM_KEY); + // CGRAPH_PARAM_READ_CODE_BLOCK(p); // 本例中,对 param的处理,并未考虑并发之间的影响。实际操作中,需要注意 + p->print(); + } +}; + + +class SwitchAspect : public GAspect { +public: + CStatus beginRun() override { + auto p = CGRAPH_GET_GPARAM_WITH_NO_EMPTY(ProcessParam, EXAMPLE_PARAM_KEY); + p->change(this->getName(), true); + + notify(EXAMPLE_EVENT_KEY, GEventType::SYNC); + return CStatus(); + } + + CVoid finishRun(const CStatus& curStatus) override { + auto p = CGRAPH_GET_GPARAM_WITH_NO_EMPTY(ProcessParam, EXAMPLE_PARAM_KEY); + p->change(this->getName(), false); + notify(EXAMPLE_EVENT_KEY, GEventType::SYNC); + } +}; + + +class ActionGNode : public GNode { + CStatus run() override { + int ms = std::abs((int)std::random_device{}()) % 4000 + 1000; + CGRAPH_SLEEP_MILLISECOND(ms); // 一个算子,随机休息一段时间,时长 1000~5000 ms + return CStatus(); + } +}; + + +void example_mock_gui() { + GElementPtr a, b, c, d, e, f, g = nullptr; + auto pipeline = GPipelineFactory::create(); + + pipeline->registerGElement(&a, {}, "nodeA"); + pipeline->registerGElement(&b, {a}, "nodeB"); + pipeline->registerGElement(&c, {a}, "nodeC"); + pipeline->registerGElement(&d, {b}, "nodeD"); + pipeline->registerGElement(&e, {b, c}, "nodeE"); + pipeline->registerGElement(&f, {d, e}, "nodeF"); + pipeline->registerGElement(&g, {e}, "nodeG"); + + pipeline->createGParam(EXAMPLE_PARAM_KEY); + pipeline->addGEvent(EXAMPLE_EVENT_KEY); + pipeline->addGAspect(); // 在每个node,开始和结束的时候,去触发 EXAMPLE_EVENT_KEY 事件,显示当前正在running的node信息 + + pipeline->process(); + GPipelineFactory::clear(); +} + + +int main() { + example_mock_gui(); + return 0; +} diff --git a/src/GraphCtrl/GraphAspect/GAspectManager.h b/src/GraphCtrl/GraphAspect/GAspectManager.h index 27e766aa..ec8d1bde 100644 --- a/src/GraphCtrl/GraphAspect/GAspectManager.h +++ b/src/GraphCtrl/GraphAspect/GAspectManager.h @@ -26,8 +26,12 @@ class GAspectManager : public GAspectObject, /** * 执行切面逻辑 + * @param type + * @param curStatus + * @return */ - CStatus reflect(const GAspectType& type, const CStatus& curStatus = CStatus()) { + CStatus reflect(const GAspectType& type, + const CStatus& curStatus = CStatus()) { CGRAPH_FUNCTION_BEGIN for (GAspectPtr aspect : aspect_arr_) { @@ -108,9 +112,7 @@ class GAspectManager : public GAspectObject, */ CStatus popLast() { CGRAPH_FUNCTION_BEGIN - if (0 == getSize()) { - CGRAPH_RETURN_ERROR_STATUS("no aspect to pop") - } + CGRAPH_RETURN_ERROR_STATUS_BY_CONDITION(0 == getSize(), "no aspect to pop") auto* last = aspect_arr_.back(); CGRAPH_DELETE_PTR(last); diff --git a/src/GraphCtrl/GraphElement/GElement.inl b/src/GraphCtrl/GraphElement/GElement.inl index 68569f84..c57d5c16 100644 --- a/src/GraphCtrl/GraphElement/GElement.inl +++ b/src/GraphCtrl/GraphElement/GElement.inl @@ -34,7 +34,7 @@ GElementPtr GElement::addGAspect(TParam* param) { template, TAspect>::value, int>> -GElement* GElement::addGAspect(Args... args) { +GElementPtr GElement::addGAspect(Args... args) { if (!aspect_manager_) { aspect_manager_ = CGRAPH_SAFE_MALLOC_COBJECT(GAspectManager) } diff --git a/src/GraphCtrl/GraphElement/GElementRepository.cpp b/src/GraphCtrl/GraphElement/GElementRepository.cpp index d5740f6d..83cdfdd1 100644 --- a/src/GraphCtrl/GraphElement/GElementRepository.cpp +++ b/src/GraphCtrl/GraphElement/GElementRepository.cpp @@ -135,5 +135,4 @@ GElementRepository::~GElementRepository() { } } - CGRAPH_NAMESPACE_END \ No newline at end of file diff --git a/src/UtilsCtrl/ThreadPool/Queue/UAtomicRingBufferQueue.h b/src/UtilsCtrl/ThreadPool/Queue/UAtomicRingBufferQueue.h index be88380b..9046e634 100644 --- a/src/UtilsCtrl/ThreadPool/Queue/UAtomicRingBufferQueue.h +++ b/src/UtilsCtrl/ThreadPool/Queue/UAtomicRingBufferQueue.h @@ -119,11 +119,19 @@ class UAtomicRingBufferQueue : public UQueueObject { } protected: + /** + * 当前队列是否为满 + * @return + */ CBool isFull() { // 空出来一个位置,这个时候不让 tail写入 return head_ == (tail_ + 1) % capacity_; } + /** + * 当前队列是否为空 + * @return + */ CBool isEmpty() { return head_ == tail_; }