Skip to content

Commit

Permalink
[feat] add example
Browse files Browse the repository at this point in the history
  • Loading branch information
ChunelFeng committed Sep 15, 2023
1 parent cab0142 commit 0c1becc
Show file tree
Hide file tree
Showing 11 changed files with 230 additions and 69 deletions.
9 changes: 6 additions & 3 deletions CGraph-run-tutorials.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
#!/bin/bash

if [ ! -d "build" ]; then
echo -e "\033[31m[ERROR] Directory /build does not exist.\033[0m"
CGRAPH_TUTORIAL_DIR="build/tutorial/"

if [ ! -d $CGRAPH_TUTORIAL_DIR ]; then
echo -e "\033[31m[ERROR] Directory $CGRAPH_TUTORIAL_DIR does not exist.\033[0m"
exit 1
fi

cd build
# shellcheck disable=SC2164
cd $CGRAPH_TUTORIAL_DIR

for file in *; do
# 执行所有可执行文件,并且过滤掉文件夹
Expand Down
46 changes: 2 additions & 44 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,50 +18,8 @@ set(CMAKE_CXX_STANDARD 11)
# 如果开启此宏定义,则CGraph执行过程中,不会在控制台打印任何信息
# add_definitions(-D_CGRAPH_SILENCE_)

# 对应tutorial中的内容
set(CGRAPH_TUTORIAL_LIST
T00-HelloCGraph
T01-Simple
T02-Cluster
T03-Region
T04-Complex
T05-Param
T06-Condition
T07-MultiPipeline
T08-Template
T09-Aspect
T10-AspectParam
T11-Singleton
T12-Function
T13-Daemon
T14-Hold
T15-ElementParam
T16-MessageSendRecv
T17-MessagePubSub
T18-Event
T19-Cancel
T20-YieldResume
T21-MultiCondition
T22-Timeout
T23-Some
T24-Fence
T25-Coordinator

# 以下为工具类tutorial
TU01-ThreadPool
# TU02-Lru
# TU03-Trie
# TU04-Timer
# TU05-Distance
)

# add CGraph environment info
include(cmake/CGraph-env-include.cmake)

foreach(tut ${CGRAPH_TUTORIAL_LIST})
add_executable(${tut}
# 在自己的工程中引入CGraph功能,仅需引入 CGraph-env-include.cmake 后,加入这一句话即可
$<TARGET_OBJECTS:CGraph>
tutorial/${tut}.cpp
)
endforeach()
add_subdirectory(./tutorial)
add_subdirectory(./example)
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
```shell
$ sudo apt-get install cmake -y # 安装cmake
$ ./CGraph-build.sh # 编译CGraph工程,生成的内容在同级/build/文件夹中
$ ./build/T00-HelloCGraph # 运行第一个实例程序,并且在终端输出 Hello, CGraph.
$ ./build/tutorial/T00-HelloCGraph # 运行第一个实例程序,并且在终端输出 Hello, CGraph.
```

## 三. 使用Demo
Expand Down Expand Up @@ -323,6 +323,7 @@ int main() {
[2023.09.06 - v2.5.1 - Chunel]
* 提供`fence`(栅栏)功能
* 提供`coordinator`(协调)功能
* 添加`example`相关内容,针对不同行业,提供一些简单的实现用例
</details>
Expand Down
2 changes: 1 addition & 1 deletion README_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ You can transfer your params in many scenes. It is also possible to extend the f
```shell
$ sudo apt-get install cmake -y
$ ./CGraph-build.sh
$ ./build/T00-HelloCGraph
$ ./build/tutorial/T00-HelloCGraph
```

## 3. Demo
Expand Down
11 changes: 11 additions & 0 deletions example/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# 对应 example 中的内容
set(CGRAPH_EXAMPLE_LIST
E01-AutoPilot
)

foreach(example ${CGRAPH_EXAMPLE_LIST})
add_executable(${example}
$<TARGET_OBJECTS:CGraph>
${example}.cpp
)
endforeach()
155 changes: 155 additions & 0 deletions example/E01-AutoPilot.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/***************************
@Author: Chunel
@Contact: [email protected]
@File: E01-AutoPilot.cpp
@Time: 2023/9/15 20:03
@Desc: 本example主要展示,Camera 每隔1000ms,采集一张图片
LaneDetector 和 CarDetector同时消费这张图片,计算对应的内容
并且最终在Show中展示对应的结果信息
***************************/

#include <iostream>
#include <algorithm>

#include "CGraph.h"

using namespace CGraph;

static const int DEFAULT_IMAGE_SIZE = 64;
static const int DEFAULT_MESSAGE_BUF_SIZE = 16;
static const char* EXAMPLE_IMAGE_TOPIC = "/example/image/topic";
static const char* EXAMPLE_PARAM_KEY = "example-param-key";


struct ImageMParam : public GMessageParam {
int frame_id_ = 0;
char image_buf_[DEFAULT_IMAGE_SIZE] = {0};

ImageMParam& operator=(const ImageMParam& param) {
if (this == &param) {
return *this;
}

this->frame_id_ = param.frame_id_;
memset(image_buf_, 0, DEFAULT_IMAGE_SIZE);
memcpy(image_buf_, param.image_buf_, DEFAULT_IMAGE_SIZE);
return *this;
}
};


class CameraGDaemon : public GDaemon {
public:
CVoid daemonTask(GDaemonParamPtr param) override {
ImageMParam image;
image.frame_id_ = cur_index_;
std::string info = "this is " + std::to_string(cur_index_) + " image";
memcpy(image.image_buf_, info.c_str(), info.length());
cur_index_++;

CGRAPH_PUB_MPARAM(ImageMParam, EXAMPLE_IMAGE_TOPIC, image);
}

private:
int cur_index_ = 0;
};


struct DetectResultGParam : public GParam {
int lane_num_ = 0;
int car_num_ = 0;
int frame_id_ = 0;

CStatus setup() override {
lane_num_ = 0;
car_num_ = 0;
frame_id_ = 0;
return CStatus();
}
};


class LaneDetectorGNode : public GNode {
public:
CStatus init() override {
// 订阅 EXAMPLE_IMAGE_TOPIC 消息。每次 bind的返回值,是不一样的,用于区分
conn_id_ = CGRAPH_BIND_MESSAGE_TOPIC(ImageMParam, EXAMPLE_IMAGE_TOPIC, DEFAULT_MESSAGE_BUF_SIZE)
return CStatus();
}

CStatus run() override {
ImageMParam image;
auto status = CGRAPH_SUB_MPARAM(ImageMParam, conn_id_, image);
if (status.isErr()) {
return status;
}

auto param = CGRAPH_GET_GPARAM_WITH_NO_EMPTY(DetectResultGParam, EXAMPLE_PARAM_KEY)
// detector lane in image.image_buf_ ...
CGRAPH_ECHO("detecting lane in frame [%d], info is [%s]", image.frame_id_, image.image_buf_);
param->frame_id_ = image.frame_id_;
param->lane_num_ = std::abs((int)std::random_device{}()) % 10;
return CStatus();
}

private:
int conn_id_ = 0;
};


class CarDetectorGNode : public GNode {
public:
CStatus init() override {
conn_id_ = CGRAPH_BIND_MESSAGE_TOPIC(ImageMParam, EXAMPLE_IMAGE_TOPIC, DEFAULT_MESSAGE_BUF_SIZE)
return CStatus();
}

CStatus run() override {
ImageMParam image;
auto status = CGRAPH_SUB_MPARAM(ImageMParam, conn_id_, image);
if (status.isErr()) {
return status;
}

auto param = CGRAPH_GET_GPARAM_WITH_NO_EMPTY(DetectResultGParam, EXAMPLE_PARAM_KEY);
CGRAPH_ECHO("finding car in frame [%d], info is [%s]", image.frame_id_, image.image_buf_);
// find car in image.image_buf_ ...
param->car_num_ = std::abs((int)std::random_device{}()) % 5;
return CStatus();
}

private:
int conn_id_ = 0;
};


class ShowGNode : public GNode {
CStatus run() override {
auto param = CGRAPH_GET_GPARAM_WITH_NO_EMPTY(DetectResultGParam, EXAMPLE_PARAM_KEY);
CGRAPH_ECHO("find [%d] car and [%d] lane in frame [%d] \n", param->car_num_, param->lane_num_, param->frame_id_);
return CStatus();
}
};


void example_auto_pilot() {
GElementPtr lane, car, show = nullptr;
auto pipeline = GPipelineFactory::create();

pipeline->registerGElement<LaneDetectorGNode>(&lane, {}, "lane");
pipeline->registerGElement<CarDetectorGNode>(&car, {}, "car");
pipeline->registerGElement<ShowGNode>(&show, {lane, car}, "show");

pipeline->createGParam<DetectResultGParam>(EXAMPLE_PARAM_KEY);
pipeline->addGDaemon<CameraGDaemon>(1000); // 模拟相机,每间隔1000ms,生成一张图片

pipeline->process(10);
GPipelineFactory::clear();
CGRAPH_CLEAR_MESSAGES()
}


int main() {
example_auto_pilot();
return 0;
}
9 changes: 5 additions & 4 deletions src/GraphCtrl/GraphPipeline/GPipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,16 +98,17 @@ CStatus GPipeline::process(CSize runTimes) {
CGRAPH_FUNCTION_CHECK_STATUS

while (runTimes-- > 0
&& !status.isErr()
&& !repository_.isCancelState()) {
/**
* 1. 执行轮数(runTimes)没有结束
* 2. 没有进入取消状态
* 2. 执行结果正常
* 3. 没有进入取消状态
*/
status = run();
CGRAPH_FUNCTION_CHECK_STATUS
status += run();
}

status = destroy();
status += destroy();
CGRAPH_FUNCTION_END
}

Expand Down
2 changes: 1 addition & 1 deletion src/UtilsCtrl/ThreadPool/Queue/UAtomicRingBufferQueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ class UAtomicRingBufferQueue : public UQueueObject {
CGRAPH_RETURN_ERROR_STATUS("receive message timeout.")
}

value = std::move((*ring_buffer_queue_[head_]));
value = std::move(*ring_buffer_queue_[head_]);
head_ = (head_ + 1) % capacity_;
}
push_cv_.notify_one();
Expand Down
8 changes: 3 additions & 5 deletions src/UtilsCtrl/ThreadPool/UThreadPool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,17 +238,15 @@ CVoid UThreadPool::monitor() {
bool busy = !primary_threads_.empty() && std::all_of(primary_threads_.begin(), primary_threads_.end(),
[](UThreadPrimaryPtr ptr) { return nullptr != ptr && ptr->is_running_; });

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

// 判断 secondary 线程是否需要退出
{
CGRAPH_LOCK_GUARD lock(st_mutex_);
for (auto iter = secondary_threads_.begin(); iter != secondary_threads_.end(); ) {
(*iter)->freeze() ? secondary_threads_.erase(iter++) : iter++;
}
for (auto iter = secondary_threads_.begin(); iter != secondary_threads_.end(); ) {
(*iter)->freeze() ? secondary_threads_.erase(iter++) : iter++;
}
}
}
Expand Down
15 changes: 5 additions & 10 deletions src/UtilsCtrl/UtilsFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include <mutex>
#include <chrono>
#include <iomanip>
#include <ctime>
#include <cstdarg>
#include <algorithm>
Expand All @@ -35,16 +36,10 @@ inline CVoid CGRAPH_ECHO(const char *cmd, ...) {
#ifndef _WIN32
// 非windows系统,打印到毫秒
auto now = std::chrono::system_clock::now();
// 通过不同精度获取相差的毫秒数
uint64_t disMs = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count()
- std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()).count() * 1000;
time_t tt = std::chrono::system_clock::to_time_t(now);
auto localTime = localtime(&tt);
char strTime[32] = { 0 };
sprintf(strTime, "[%04d-%02d-%02d %02d:%02d:%02d.%03d]", localTime->tm_year + 1900,
localTime->tm_mon + 1, localTime->tm_mday, localTime->tm_hour,
localTime->tm_min, localTime->tm_sec, (int)disMs);
std::cout << "[CGraph] " << strTime << " ";
auto time = std::chrono::system_clock::to_time_t(now);
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count() % 1000;
std::cout << "[" << std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S.") \
<< std::setfill('0') << std::setw(3) << ms << "] ";
#else
// windows系统,打印到秒
time_t curTime;
Expand Down
39 changes: 39 additions & 0 deletions tutorial/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

# 对应tutorial中的内容
set(CGRAPH_TUTORIAL_LIST
T00-HelloCGraph
T01-Simple
T02-Cluster
T03-Region
T04-Complex
T05-Param
T06-Condition
T07-MultiPipeline
T08-Template
T09-Aspect
T10-AspectParam
T11-Singleton
T12-Function
T13-Daemon
T14-Hold
T15-ElementParam
T16-MessageSendRecv
T17-MessagePubSub
T18-Event
T19-Cancel
T20-YieldResume
T21-MultiCondition
T22-Timeout
T23-Some
T24-Fence
T25-Coordinator
)


foreach(tut ${CGRAPH_TUTORIAL_LIST})
add_executable(${tut}
# 在自己的工程中引入CGraph功能,仅需引入 CGraph-env-include.cmake 后,加入这一句话即可
$<TARGET_OBJECTS:CGraph>
${tut}.cpp
)
endforeach()

0 comments on commit 0c1becc

Please sign in to comment.