Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update dora new #553

Merged
merged 19 commits into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,44 @@ jobs:
dora stop --name ci-python-test --grace-duration 5s
dora destroy

- name: "Test CLI (C)"
timeout-minutes: 30
# fail-fast by using bash shell explictly
shell: bash
if: runner.os == 'Linux'
run: |
# Test C template Project
dora new test_c_project --lang c --internal-create-with-path-dependencies
cd test_c_project
dora up
dora list
cmake -B build
cmake --build build
cmake --install build
dora start dataflow.yml --name ci-c-test
sleep 10
dora stop --name ci-c-test --grace-duration 5s
dora destroy

- name: "Test CLI (C++)"
timeout-minutes: 30
# fail-fast by using bash shell explictly
shell: bash
if: runner.os == 'Linux'
run: |
# Test C++ template Project
dora new test_cxx_project --lang cxx --internal-create-with-path-dependencies
cd test_cxx_project
dora up
dora list
cmake -B build
cmake --build build
cmake --install build
dora start dataflow.yml --name ci-cxx-test
sleep 10
dora stop --name ci-cxx-test --grace-duration 5s
dora destroy

clippy:
name: "Clippy"
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion binaries/cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ enum Command {
#[clap(value_name = "PATH", value_hint = clap::ValueHint::FilePath)]
dataflow: PathBuf,
},
/// Generate a new project, node or operator. Choose the language between Rust, Python, C or C++.
/// Generate a new project or node. Choose the language between Rust, Python, C or C++.
New {
#[clap(flatten)]
args: CommandNew,
Expand Down
79 changes: 79 additions & 0 deletions binaries/cli/src/template/c/cmake-template.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
cmake_minimum_required(VERSION 3.21)
project(cxx-dataflow LANGUAGES C)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "-fPIC")

set(DORA_ROOT_DIR "__DORA_PATH__" CACHE FILEPATH "Path to the root of dora")

set(dora_c_include_dir "${CMAKE_CURRENT_BINARY_DIR}/include/c")
if(DORA_ROOT_DIR)
include(ExternalProject)
ExternalProject_Add(Dora
SOURCE_DIR ${DORA_ROOT_DIR}
BUILD_IN_SOURCE True
CONFIGURE_COMMAND ""
BUILD_COMMAND
cargo build
--package dora-node-api-c
INSTALL_COMMAND ""
)

add_custom_command(OUTPUT ${dora_c_include_dir}
WORKING_DIRECTORY ${DORA_ROOT_DIR}
DEPENDS Dora
COMMAND
mkdir ${CMAKE_CURRENT_BINARY_DIR}/include/c -p
&&
cp apis/c/node ${CMAKE_CURRENT_BINARY_DIR}/include/c -r
)

add_custom_target(Dora_c DEPENDS ${dora_c_include_dir})
set(dora_link_dirs ${DORA_ROOT_DIR}/target/debug)
else()
include(ExternalProject)
ExternalProject_Add(Dora
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/dora
GIT_REPOSITORY https://github.com/dora-rs/dora.git
GIT_TAG main
BUILD_IN_SOURCE True
CONFIGURE_COMMAND ""
BUILD_COMMAND
cargo build
--package dora-node-api-c
--target-dir ${CMAKE_CURRENT_BINARY_DIR}/dora/src/Dora/target
INSTALL_COMMAND ""
)

add_custom_command(OUTPUT ${dora_c_include_dir}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/dora/src/Dora/target
DEPENDS Dora
COMMAND
mkdir ${CMAKE_CURRENT_BINARY_DIR}/include/c -p
&&
cp ../apis/c/node ${CMAKE_CURRENT_BINARY_DIR}/include/c -r
)

set(dora_link_dirs ${CMAKE_CURRENT_BINARY_DIR}/dora/src/Dora/target/debug)

add_custom_target(Dora_c DEPENDS ${dora_c_include_dir})
endif()

link_directories(${dora_link_dirs})

add_executable(talker_1 talker_1/node.c)
add_dependencies(talker_1 Dora_c)
target_include_directories(talker_1 PRIVATE ${dora_c_include_dir})
target_link_libraries(talker_1 dora_node_api_c m)

add_executable(talker_2 talker_2/node.c)
add_dependencies(talker_2 Dora_c)
target_include_directories(talker_2 PRIVATE ${dora_c_include_dir})
target_link_libraries(talker_2 dora_node_api_c m)

add_executable(listener_1 listener_1/node.c)
add_dependencies(listener_1 Dora_c)
target_include_directories(listener_1 PRIVATE ${dora_c_include_dir})
target_link_libraries(listener_1 dora_node_api_c m)

install(TARGETS listener_1 talker_1 talker_2 DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin)
30 changes: 14 additions & 16 deletions binaries/cli/src/template/c/dataflow-template.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
nodes:
- id: op_1
operator:
shared-library: build/op_1
- id: talker_1
custom:
source: bin/talker_1
inputs:
foo: dora/timer/millis/100
tick: dora/timer/millis/100
outputs:
- bar
- id: op_2
operator:
shared-library: build/op_2
- speech
- id: talker_2
custom:
source: bin/talker_2
inputs:
foo: dora/timer/secs/2
tick: dora/timer/secs/2
outputs:
- bar
- speech

- id: custom-node_1
- id: listener_1
custom:
source: build/node_1
source: bin/listener_1
inputs:
input-1: op_1/bar
input-2: op_2/bar
outputs:
- foo
input-1: talker_1/speech
XxChang marked this conversation as resolved.
Show resolved Hide resolved
input-2: talker_2/speech
69 changes: 69 additions & 0 deletions binaries/cli/src/template/c/listener/listener-template.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "node_api.h"

// sleep
#ifdef _WIN32
#include <Windows.h>
#else
#include <unistd.h>
#endif

int main()
{
void *dora_context = init_dora_context_from_env();
if (dora_context == NULL)
{
fprintf(stderr, "[c node] init dora context failed\n");
return -1;
}

printf("[c node] dora context initialized\n");

for (char i = 0; i < 20; i++)
{
void *event = dora_next_event(dora_context);
if (event == NULL)
{
printf("[c node] ERROR: unexpected end of event\n");
return -1;
}

enum DoraEventType ty = read_dora_event_type(event);

if (ty == DoraEventType_Input)
{
char *id_ptr;
size_t id_len;
read_dora_input_id(event, &id_ptr, &id_len);

char *data_ptr;
size_t data_len;
read_dora_input_data(event, &data_ptr, &data_len);

printf("I heard %s from %s\n", data_ptr, id_ptr);
}
else if (ty == DoraEventType_Stop)
{
printf("[c node] received stop event\n");
free_dora_event(event);
break;
}
else if (ty == DoraEventType_InputClosed) {
printf("[c node] received input closed event\n");
}
else
{
printf("[c node] received unexpected event: %d\n", ty);
free_dora_event(event);
break;
}

free_dora_event(event);
}

free_dora_context(dora_context);

return 0;
}
56 changes: 45 additions & 11 deletions binaries/cli/src/template/c/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ use std::{
path::{Path, PathBuf},
};

pub fn create(args: crate::CommandNew) -> eyre::Result<()> {
const NODE: &str = include_str!("node/node-template.c");
const TALKER: &str = include_str!("talker/talker-template.c");
const LISTENER: &str = include_str!("listener/listener-template.c");

pub fn create(args: crate::CommandNew, use_path_deps: bool) -> eyre::Result<()> {
let crate::CommandNew {
kind,
lang: _,
Expand All @@ -15,13 +19,19 @@ pub fn create(args: crate::CommandNew) -> eyre::Result<()> {
} = args;

match kind {
crate::Kind::Operator => create_operator(name, path),
crate::Kind::CustomNode => create_custom_node(name, path),
crate::Kind::Dataflow => create_dataflow(name, path),
crate::Kind::Operator => {
bail!("Operators are going to be depreciated, please don't use it")
}
XxChang marked this conversation as resolved.
Show resolved Hide resolved
crate::Kind::CustomNode => create_custom_node(name, path, NODE),
crate::Kind::Dataflow => create_dataflow(name, path, use_path_deps),
}
}

fn create_dataflow(name: String, path: Option<PathBuf>) -> Result<(), eyre::ErrReport> {
fn create_dataflow(
name: String,
path: Option<PathBuf>,
use_path_deps: bool,
) -> Result<(), eyre::ErrReport> {
const DATAFLOW_YML: &str = include_str!("dataflow-template.yml");

if name.contains('/') {
Expand All @@ -41,9 +51,10 @@ fn create_dataflow(name: String, path: Option<PathBuf>) -> Result<(), eyre::ErrR
fs::write(&dataflow_yml_path, dataflow_yml)
.with_context(|| format!("failed to write `{}`", dataflow_yml_path.display()))?;

create_operator("op_1".into(), Some(root.join("op_1")))?;
create_operator("op_2".into(), Some(root.join("op_2")))?;
create_custom_node("node_1".into(), Some(root.join("node_1")))?;
create_custom_node("talker_1".into(), Some(root.join("talker_1")), TALKER)?;
create_custom_node("talker_2".into(), Some(root.join("talker_2")), TALKER)?;
create_custom_node("listener_1".into(), Some(root.join("listener_1")), LISTENER)?;
create_cmakefile(root.to_path_buf(), use_path_deps)?;

println!(
"Created new C dataflow at `{name}` at {}",
Expand All @@ -53,6 +64,8 @@ fn create_dataflow(name: String, path: Option<PathBuf>) -> Result<(), eyre::ErrR
Ok(())
}

#[deprecated(since = "0.3.4")]
#[allow(unused)]
fn create_operator(name: String, path: Option<PathBuf>) -> Result<(), eyre::ErrReport> {
const OPERATOR: &str = include_str!("operator/operator-template.c");

Expand Down Expand Up @@ -91,9 +104,30 @@ fn create_operator(name: String, path: Option<PathBuf>) -> Result<(), eyre::ErrR
Ok(())
}

fn create_custom_node(name: String, path: Option<PathBuf>) -> Result<(), eyre::ErrReport> {
const NODE: &str = include_str!("node/node-template.c");
fn create_cmakefile(root: PathBuf, use_path_deps: bool) -> Result<(), eyre::ErrReport> {
const CMAKEFILE: &str = include_str!("cmake-template.txt");

let cmake_file = if use_path_deps {
let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
let workspace_dir = manifest_dir.parent().unwrap().parent().unwrap();
CMAKEFILE.replace("__DORA_PATH__", workspace_dir.to_str().unwrap())
} else {
CMAKEFILE.replace("__DORA_PATH__", "")
};

let cmake_path = root.join("CMakeLists.txt");
fs::write(&cmake_path, cmake_file)
.with_context(|| format!("failed to write `{}`", cmake_path.display()))?;

println!("Created new CMakeLists.txt at {}", cmake_path.display());
Ok(())
}

fn create_custom_node(
name: String,
path: Option<PathBuf>,
template_scripts: &str,
) -> Result<(), eyre::ErrReport> {
if name.contains('/') {
bail!("node name must not contain `/` separators");
}
Expand All @@ -107,7 +141,7 @@ fn create_custom_node(name: String, path: Option<PathBuf>) -> Result<(), eyre::E
.with_context(|| format!("failed to create directory `{}`", root.display()))?;

let node_path = root.join("node.c");
fs::write(&node_path, NODE)
fs::write(&node_path, template_scripts)
.with_context(|| format!("failed to write `{}`", node_path.display()))?;
let header_path = root.join("node_api.h");
fs::write(&header_path, HEADER_NODE_API)
Expand Down
Loading
Loading