From e69ccc02eb46092ff0d87f207dd70b4367e38ee9 Mon Sep 17 00:00:00 2001 From: XxChang Date: Thu, 13 Jun 2024 10:34:54 +0800 Subject: [PATCH] add cxx template --- .../cli/src/template/cxx/cmake-template.txt | 56 +++++++++++++++++++ .../src/template/cxx/dataflow-template.yml | 36 ++++++------ .../cli/src/template/cxx/listener-template.cc | 34 +++++++++++ binaries/cli/src/template/cxx/mod.rs | 32 ++++++++--- .../cli/src/template/cxx/talker-template.cc | 39 +++++++++++++ 5 files changed, 171 insertions(+), 26 deletions(-) create mode 100644 binaries/cli/src/template/cxx/cmake-template.txt create mode 100644 binaries/cli/src/template/cxx/listener-template.cc create mode 100644 binaries/cli/src/template/cxx/talker-template.cc diff --git a/binaries/cli/src/template/cxx/cmake-template.txt b/binaries/cli/src/template/cxx/cmake-template.txt new file mode 100644 index 00000000..6ca462a0 --- /dev/null +++ b/binaries/cli/src/template/cxx/cmake-template.txt @@ -0,0 +1,56 @@ +cmake_minimum_required(VERSION 3.21) +project(cxx-dataflow LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_FLAGS "-fPIC") + +set(dora_cxx_include_dir "${CMAKE_CURRENT_BINARY_DIR}/include/cxx") +set(node_bridge "${CMAKE_CURRENT_BINARY_DIR}/node_bridge.cc") + +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-cxx + --target-dir ${CMAKE_CURRENT_BINARY_DIR}/dora/src/Dora/target + INSTALL_COMMAND "" +) + +add_custom_command(OUTPUT ${node_bridge} ${dora_cxx_include_dir} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/dora/src/Dora/target + DEPENDS Dora + COMMAND + mkdir ${dora_cxx_include_dir} -p + && + cp cxxbridge/dora-node-api-cxx/src/lib.rs.cc ${node_bridge} + && + cp cxxbridge/dora-node-api-cxx/src/lib.rs.h ${dora_cxx_include_dir}/dora-node-api.h +) + +set(dora_link_dirs ${CMAKE_CURRENT_BINARY_DIR}/dora/src/Dora/target/debug) + +add_custom_target(Dora_cxx DEPENDS ${node_bridge} ${dora_cxx_include_dir}) + +link_directories(${dora_link_dirs}) + +add_executable(talker_1 talker_1/node.cc ${node_bridge}) +add_dependencies(talker_1 Dora_cxx) +target_include_directories(talker_1 PRIVATE ${dora_cxx_include_dir}) +target_link_libraries(talker_1 dora_node_api_cxx) + +add_executable(talker_2 talker_2/node.cc ${node_bridge}) +add_dependencies(talker_2 Dora_cxx) +target_include_directories(talker_2 PRIVATE ${dora_cxx_include_dir}) +target_link_libraries(talker_2 dora_node_api_cxx) + +add_executable(listener_1 listener_1/node.cc ${node_bridge}) +add_dependencies(listener_1 Dora_cxx) +target_include_directories(listener_1 PRIVATE ${dora_cxx_include_dir}) +target_link_libraries(listener_1 dora_node_api_cxx) + +install(TARGETS listener_1 talker_1 talker_2 DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin) \ No newline at end of file diff --git a/binaries/cli/src/template/cxx/dataflow-template.yml b/binaries/cli/src/template/cxx/dataflow-template.yml index 9559eb88..afd4177d 100644 --- a/binaries/cli/src/template/cxx/dataflow-template.yml +++ b/binaries/cli/src/template/cxx/dataflow-template.yml @@ -1,23 +1,23 @@ nodes: - - id: runtime-node_1 - operators: - - id: op_1 - shared-library: build/op_1 - inputs: - tick: dora/timer/millis/100 - outputs: - - some-output - - id: op_2 - shared-library: build/op_2 - inputs: - tick: dora/timer/secs/2 - outputs: - - some-output + - id: talker_1 + custom: + source: build/talker_1 + inputs: + tick: dora/timer/millis/100 + outputs: + - speech + - id: talker_2 + custom: + source: build/talker_2 + inputs: + tick: dora/timer/secs/2 + outputs: + - speech - - id: custom-node_1 + - id: listener_1 custom: - source: build/node_1 + source: build/listener_1 inputs: tick: dora/timer/secs/1 - input-1: op_1/some-output - input-2: op_2/some-output + input-1: talker_1/speech + input-2: talker_2/speech diff --git a/binaries/cli/src/template/cxx/listener-template.cc b/binaries/cli/src/template/cxx/listener-template.cc new file mode 100644 index 00000000..0f62a8ce --- /dev/null +++ b/binaries/cli/src/template/cxx/listener-template.cc @@ -0,0 +1,34 @@ +#include "dora-node-api.h" // adjust this path if necessary + +#include +#include + +int main() +{ + std::cout << "HELLO FROM C++" << std::endl; + unsigned char counter = 0; + + auto dora_node = init_dora_node(); + + while (1) + { + auto event = dora_node.events->next(); + auto ty = event_type(event); + + if (ty == DoraEventType::AllInputsClosed) + { + break; + } + else if (ty == DoraEventType::Input) + { + auto input = event_as_input(std::move(event)); + auto input_id = input.id; + std::cout << "I heard from " << std::string(input_id) << std::endl; + } + else { + std::cerr << "Unknown event type " << static_cast(ty) << std::endl; + } + } + + return 0;; +} diff --git a/binaries/cli/src/template/cxx/mod.rs b/binaries/cli/src/template/cxx/mod.rs index ebbfc439..3b9e680a 100644 --- a/binaries/cli/src/template/cxx/mod.rs +++ b/binaries/cli/src/template/cxx/mod.rs @@ -4,6 +4,10 @@ use std::{ path::{Path, PathBuf}, }; +const NODE: &str = include_str!("node-template.cc"); +const TALKER: &str = include_str!("talker-template.cc"); +const LISTENER: &str = include_str!("listener-template.cc"); + pub fn create(args: crate::CommandNew) -> eyre::Result<()> { let crate::CommandNew { kind, @@ -14,7 +18,7 @@ pub fn create(args: crate::CommandNew) -> eyre::Result<()> { match kind { crate::Kind::Operator => { bail!("Operators are going to be depreciated, please don't use it") }, - crate::Kind::CustomNode => create_custom_node(name, path), + crate::Kind::CustomNode => create_custom_node(name, path, NODE), crate::Kind::Dataflow => create_dataflow(name, path), } } @@ -39,9 +43,10 @@ fn create_dataflow(name: String, path: Option) -> 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())?; println!( "Created new C++ dataflow at `{name}` at {}", @@ -51,6 +56,19 @@ fn create_dataflow(name: String, path: Option) -> Result<(), eyre::ErrR Ok(()) } +fn create_cmakefile(root: PathBuf) -> Result<(), eyre::ErrReport> { + const CMAKEFILE: &str = include_str!("cmake-template.txt"); + + let cmake_path = root.join("CMakeLists.txt"); + fs::write(&cmake_path, CMAKEFILE) + .with_context(|| format!("failed to write `{}`", cmake_path.display()))?; + + println!("Created new CMakeLists.txt at {}", cmake_path.display()); + Ok(()) +} + +#[deprecated(since = "0.3.4")] +#[allow(unused)] fn create_operator(name: String, path: Option) -> Result<(), eyre::ErrReport> { const OPERATOR: &str = include_str!("operator-template.cc"); const HEADER: &str = include_str!("operator-template.h"); @@ -84,9 +102,7 @@ fn create_operator(name: String, path: Option) -> Result<(), eyre::ErrR Ok(()) } -fn create_custom_node(name: String, path: Option) -> Result<(), eyre::ErrReport> { - const NODE: &str = include_str!("node-template.cc"); - +fn create_custom_node(name: String, path: Option, template_scripts: &str) -> Result<(), eyre::ErrReport> { if name.contains('/') { bail!("node name must not contain `/` separators"); } @@ -100,7 +116,7 @@ fn create_custom_node(name: String, path: Option) -> Result<(), eyre::E .with_context(|| format!("failed to create directory `{}`", root.display()))?; let node_path = root.join("node.cc"); - fs::write(&node_path, NODE) + fs::write(&node_path, template_scripts) .with_context(|| format!("failed to write `{}`", node_path.display()))?; // TODO: Makefile? diff --git a/binaries/cli/src/template/cxx/talker-template.cc b/binaries/cli/src/template/cxx/talker-template.cc new file mode 100644 index 00000000..e3fb9d2e --- /dev/null +++ b/binaries/cli/src/template/cxx/talker-template.cc @@ -0,0 +1,39 @@ +#include "dora-node-api.h" // adjust this path if necessary + +#include +#include + + +int main() +{ + auto dora_node = init_dora_node(); + + for (int i = 0; i < 20; i++) + { + auto event = dora_node.events->next(); + auto ty = event_type(event); + + if (ty == DoraEventType::AllInputsClosed) + { + break; + } + else if (ty == DoraEventType::Input) + { + std::string message{"Hello World!"}; + rust::Slice message_slice{reinterpret_cast(message.c_str()), message.size()}; + auto result = send_output(dora_node.send_output, "speech", message_slice); + auto error = std::string(result.error); + if (!error.empty()) + { + std::cerr << "Error: " << error << std::endl; + return -1; + } + } + else + { + std::cerr << "Unknown event type " << static_cast(ty) << std::endl; + } + } + + return 0; +} \ No newline at end of file