Skip to content

Commit 0c1becc

Browse files
committed
[feat] add example
1 parent cab0142 commit 0c1becc

11 files changed

Lines changed: 230 additions & 69 deletions

File tree

CGraph-run-tutorials.sh

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
#!/bin/bash
22

3-
if [ ! -d "build" ]; then
4-
echo -e "\033[31m[ERROR] Directory /build does not exist.\033[0m"
3+
CGRAPH_TUTORIAL_DIR="build/tutorial/"
4+
5+
if [ ! -d $CGRAPH_TUTORIAL_DIR ]; then
6+
echo -e "\033[31m[ERROR] Directory $CGRAPH_TUTORIAL_DIR does not exist.\033[0m"
57
exit 1
68
fi
79

8-
cd build
10+
# shellcheck disable=SC2164
11+
cd $CGRAPH_TUTORIAL_DIR
912

1013
for file in *; do
1114
# 执行所有可执行文件,并且过滤掉文件夹

CMakeLists.txt

Lines changed: 2 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -18,50 +18,8 @@ set(CMAKE_CXX_STANDARD 11)
1818
# 如果开启此宏定义,则CGraph执行过程中,不会在控制台打印任何信息
1919
# add_definitions(-D_CGRAPH_SILENCE_)
2020

21-
# 对应tutorial中的内容
22-
set(CGRAPH_TUTORIAL_LIST
23-
T00-HelloCGraph
24-
T01-Simple
25-
T02-Cluster
26-
T03-Region
27-
T04-Complex
28-
T05-Param
29-
T06-Condition
30-
T07-MultiPipeline
31-
T08-Template
32-
T09-Aspect
33-
T10-AspectParam
34-
T11-Singleton
35-
T12-Function
36-
T13-Daemon
37-
T14-Hold
38-
T15-ElementParam
39-
T16-MessageSendRecv
40-
T17-MessagePubSub
41-
T18-Event
42-
T19-Cancel
43-
T20-YieldResume
44-
T21-MultiCondition
45-
T22-Timeout
46-
T23-Some
47-
T24-Fence
48-
T25-Coordinator
49-
50-
# 以下为工具类tutorial
51-
TU01-ThreadPool
52-
# TU02-Lru
53-
# TU03-Trie
54-
# TU04-Timer
55-
# TU05-Distance
56-
)
57-
5821
# add CGraph environment info
5922
include(cmake/CGraph-env-include.cmake)
6023

61-
foreach(tut ${CGRAPH_TUTORIAL_LIST})
62-
add_executable(${tut}
63-
# 在自己的工程中引入CGraph功能,仅需引入 CGraph-env-include.cmake 后,加入这一句话即可
64-
$<TARGET_OBJECTS:CGraph>
65-
tutorial/${tut}.cpp
66-
)
67-
endforeach()
24+
add_subdirectory(./tutorial)
25+
add_subdirectory(./example)

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
```shell
7070
$ sudo apt-get install cmake -y # 安装cmake
7171
$ ./CGraph-build.sh # 编译CGraph工程,生成的内容在同级/build/文件夹中
72-
$ ./build/T00-HelloCGraph # 运行第一个实例程序,并且在终端输出 Hello, CGraph.
72+
$ ./build/tutorial/T00-HelloCGraph # 运行第一个实例程序,并且在终端输出 Hello, CGraph.
7373
```
7474

7575
## 三. 使用Demo
@@ -323,6 +323,7 @@ int main() {
323323
[2023.09.06 - v2.5.1 - Chunel]
324324
* 提供`fence`(栅栏)功能
325325
* 提供`coordinator`(协调)功能
326+
* 添加`example`相关内容,针对不同行业,提供一些简单的实现用例
326327

327328
</details>
328329

README_en.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ You can transfer your params in many scenes. It is also possible to extend the f
6060
```shell
6161
$ sudo apt-get install cmake -y
6262
$ ./CGraph-build.sh
63-
$ ./build/T00-HelloCGraph
63+
$ ./build/tutorial/T00-HelloCGraph
6464
```
6565

6666
## 3. Demo

example/CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# 对应 example 中的内容
2+
set(CGRAPH_EXAMPLE_LIST
3+
E01-AutoPilot
4+
)
5+
6+
foreach(example ${CGRAPH_EXAMPLE_LIST})
7+
add_executable(${example}
8+
$<TARGET_OBJECTS:CGraph>
9+
${example}.cpp
10+
)
11+
endforeach()

example/E01-AutoPilot.cpp

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
/***************************
2+
@Author: Chunel
3+
4+
@File: E01-AutoPilot.cpp
5+
@Time: 2023/9/15 20:03
6+
@Desc: 本example主要展示,Camera 每隔1000ms,采集一张图片
7+
LaneDetector 和 CarDetector同时消费这张图片,计算对应的内容
8+
并且最终在Show中展示对应的结果信息
9+
***************************/
10+
11+
#include <iostream>
12+
#include <algorithm>
13+
14+
#include "CGraph.h"
15+
16+
using namespace CGraph;
17+
18+
static const int DEFAULT_IMAGE_SIZE = 64;
19+
static const int DEFAULT_MESSAGE_BUF_SIZE = 16;
20+
static const char* EXAMPLE_IMAGE_TOPIC = "/example/image/topic";
21+
static const char* EXAMPLE_PARAM_KEY = "example-param-key";
22+
23+
24+
struct ImageMParam : public GMessageParam {
25+
int frame_id_ = 0;
26+
char image_buf_[DEFAULT_IMAGE_SIZE] = {0};
27+
28+
ImageMParam& operator=(const ImageMParam& param) {
29+
if (this == &param) {
30+
return *this;
31+
}
32+
33+
this->frame_id_ = param.frame_id_;
34+
memset(image_buf_, 0, DEFAULT_IMAGE_SIZE);
35+
memcpy(image_buf_, param.image_buf_, DEFAULT_IMAGE_SIZE);
36+
return *this;
37+
}
38+
};
39+
40+
41+
class CameraGDaemon : public GDaemon {
42+
public:
43+
CVoid daemonTask(GDaemonParamPtr param) override {
44+
ImageMParam image;
45+
image.frame_id_ = cur_index_;
46+
std::string info = "this is " + std::to_string(cur_index_) + " image";
47+
memcpy(image.image_buf_, info.c_str(), info.length());
48+
cur_index_++;
49+
50+
CGRAPH_PUB_MPARAM(ImageMParam, EXAMPLE_IMAGE_TOPIC, image);
51+
}
52+
53+
private:
54+
int cur_index_ = 0;
55+
};
56+
57+
58+
struct DetectResultGParam : public GParam {
59+
int lane_num_ = 0;
60+
int car_num_ = 0;
61+
int frame_id_ = 0;
62+
63+
CStatus setup() override {
64+
lane_num_ = 0;
65+
car_num_ = 0;
66+
frame_id_ = 0;
67+
return CStatus();
68+
}
69+
};
70+
71+
72+
class LaneDetectorGNode : public GNode {
73+
public:
74+
CStatus init() override {
75+
// 订阅 EXAMPLE_IMAGE_TOPIC 消息。每次 bind的返回值,是不一样的,用于区分
76+
conn_id_ = CGRAPH_BIND_MESSAGE_TOPIC(ImageMParam, EXAMPLE_IMAGE_TOPIC, DEFAULT_MESSAGE_BUF_SIZE)
77+
return CStatus();
78+
}
79+
80+
CStatus run() override {
81+
ImageMParam image;
82+
auto status = CGRAPH_SUB_MPARAM(ImageMParam, conn_id_, image);
83+
if (status.isErr()) {
84+
return status;
85+
}
86+
87+
auto param = CGRAPH_GET_GPARAM_WITH_NO_EMPTY(DetectResultGParam, EXAMPLE_PARAM_KEY)
88+
// detector lane in image.image_buf_ ...
89+
CGRAPH_ECHO("detecting lane in frame [%d], info is [%s]", image.frame_id_, image.image_buf_);
90+
param->frame_id_ = image.frame_id_;
91+
param->lane_num_ = std::abs((int)std::random_device{}()) % 10;
92+
return CStatus();
93+
}
94+
95+
private:
96+
int conn_id_ = 0;
97+
};
98+
99+
100+
class CarDetectorGNode : public GNode {
101+
public:
102+
CStatus init() override {
103+
conn_id_ = CGRAPH_BIND_MESSAGE_TOPIC(ImageMParam, EXAMPLE_IMAGE_TOPIC, DEFAULT_MESSAGE_BUF_SIZE)
104+
return CStatus();
105+
}
106+
107+
CStatus run() override {
108+
ImageMParam image;
109+
auto status = CGRAPH_SUB_MPARAM(ImageMParam, conn_id_, image);
110+
if (status.isErr()) {
111+
return status;
112+
}
113+
114+
auto param = CGRAPH_GET_GPARAM_WITH_NO_EMPTY(DetectResultGParam, EXAMPLE_PARAM_KEY);
115+
CGRAPH_ECHO("finding car in frame [%d], info is [%s]", image.frame_id_, image.image_buf_);
116+
// find car in image.image_buf_ ...
117+
param->car_num_ = std::abs((int)std::random_device{}()) % 5;
118+
return CStatus();
119+
}
120+
121+
private:
122+
int conn_id_ = 0;
123+
};
124+
125+
126+
class ShowGNode : public GNode {
127+
CStatus run() override {
128+
auto param = CGRAPH_GET_GPARAM_WITH_NO_EMPTY(DetectResultGParam, EXAMPLE_PARAM_KEY);
129+
CGRAPH_ECHO("find [%d] car and [%d] lane in frame [%d] \n", param->car_num_, param->lane_num_, param->frame_id_);
130+
return CStatus();
131+
}
132+
};
133+
134+
135+
void example_auto_pilot() {
136+
GElementPtr lane, car, show = nullptr;
137+
auto pipeline = GPipelineFactory::create();
138+
139+
pipeline->registerGElement<LaneDetectorGNode>(&lane, {}, "lane");
140+
pipeline->registerGElement<CarDetectorGNode>(&car, {}, "car");
141+
pipeline->registerGElement<ShowGNode>(&show, {lane, car}, "show");
142+
143+
pipeline->createGParam<DetectResultGParam>(EXAMPLE_PARAM_KEY);
144+
pipeline->addGDaemon<CameraGDaemon>(1000); // 模拟相机,每间隔1000ms,生成一张图片
145+
146+
pipeline->process(10);
147+
GPipelineFactory::clear();
148+
CGRAPH_CLEAR_MESSAGES()
149+
}
150+
151+
152+
int main() {
153+
example_auto_pilot();
154+
return 0;
155+
}

src/GraphCtrl/GraphPipeline/GPipeline.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,16 +98,17 @@ CStatus GPipeline::process(CSize runTimes) {
9898
CGRAPH_FUNCTION_CHECK_STATUS
9999

100100
while (runTimes-- > 0
101+
&& !status.isErr()
101102
&& !repository_.isCancelState()) {
102103
/**
103104
* 1. 执行轮数(runTimes)没有结束
104-
* 2. 没有进入取消状态
105+
* 2. 执行结果正常
106+
* 3. 没有进入取消状态
105107
*/
106-
status = run();
107-
CGRAPH_FUNCTION_CHECK_STATUS
108+
status += run();
108109
}
109110

110-
status = destroy();
111+
status += destroy();
111112
CGRAPH_FUNCTION_END
112113
}
113114

src/UtilsCtrl/ThreadPool/Queue/UAtomicRingBufferQueue.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ class UAtomicRingBufferQueue : public UQueueObject {
8888
CGRAPH_RETURN_ERROR_STATUS("receive message timeout.")
8989
}
9090

91-
value = std::move((*ring_buffer_queue_[head_]));
91+
value = std::move(*ring_buffer_queue_[head_]);
9292
head_ = (head_ + 1) % capacity_;
9393
}
9494
push_cv_.notify_one();

src/UtilsCtrl/ThreadPool/UThreadPool.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -238,17 +238,15 @@ CVoid UThreadPool::monitor() {
238238
bool busy = !primary_threads_.empty() && std::all_of(primary_threads_.begin(), primary_threads_.end(),
239239
[](UThreadPrimaryPtr ptr) { return nullptr != ptr && ptr->is_running_; });
240240

241+
CGRAPH_LOCK_GUARD lock(st_mutex_);
241242
// 如果忙碌或者priority_task_queue_中有任务,则需要添加 secondary线程
242243
if (busy || !priority_task_queue_.empty()) {
243244
createSecondaryThread(1);
244245
}
245246

246247
// 判断 secondary 线程是否需要退出
247-
{
248-
CGRAPH_LOCK_GUARD lock(st_mutex_);
249-
for (auto iter = secondary_threads_.begin(); iter != secondary_threads_.end(); ) {
250-
(*iter)->freeze() ? secondary_threads_.erase(iter++) : iter++;
251-
}
248+
for (auto iter = secondary_threads_.begin(); iter != secondary_threads_.end(); ) {
249+
(*iter)->freeze() ? secondary_threads_.erase(iter++) : iter++;
252250
}
253251
}
254252
}

src/UtilsCtrl/UtilsFunction.h

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include <mutex>
1313
#include <chrono>
14+
#include <iomanip>
1415
#include <ctime>
1516
#include <cstdarg>
1617
#include <algorithm>
@@ -35,16 +36,10 @@ inline CVoid CGRAPH_ECHO(const char *cmd, ...) {
3536
#ifndef _WIN32
3637
// 非windows系统,打印到毫秒
3738
auto now = std::chrono::system_clock::now();
38-
// 通过不同精度获取相差的毫秒数
39-
uint64_t disMs = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count()
40-
- std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()).count() * 1000;
41-
time_t tt = std::chrono::system_clock::to_time_t(now);
42-
auto localTime = localtime(&tt);
43-
char strTime[32] = { 0 };
44-
sprintf(strTime, "[%04d-%02d-%02d %02d:%02d:%02d.%03d]", localTime->tm_year + 1900,
45-
localTime->tm_mon + 1, localTime->tm_mday, localTime->tm_hour,
46-
localTime->tm_min, localTime->tm_sec, (int)disMs);
47-
std::cout << "[CGraph] " << strTime << " ";
39+
auto time = std::chrono::system_clock::to_time_t(now);
40+
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count() % 1000;
41+
std::cout << "[" << std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S.") \
42+
<< std::setfill('0') << std::setw(3) << ms << "] ";
4843
#else
4944
// windows系统,打印到秒
5045
time_t curTime;

0 commit comments

Comments
 (0)