Browse Source

add cxx template

tags/v0.3.5-rc0
XxChang 1 year ago
parent
commit
e69ccc02eb
5 changed files with 171 additions and 26 deletions
  1. +56
    -0
      binaries/cli/src/template/cxx/cmake-template.txt
  2. +18
    -18
      binaries/cli/src/template/cxx/dataflow-template.yml
  3. +34
    -0
      binaries/cli/src/template/cxx/listener-template.cc
  4. +24
    -8
      binaries/cli/src/template/cxx/mod.rs
  5. +39
    -0
      binaries/cli/src/template/cxx/talker-template.cc

+ 56
- 0
binaries/cli/src/template/cxx/cmake-template.txt View File

@@ -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)

+ 18
- 18
binaries/cli/src/template/cxx/dataflow-template.yml View File

@@ -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

+ 34
- 0
binaries/cli/src/template/cxx/listener-template.cc View File

@@ -0,0 +1,34 @@
#include "dora-node-api.h" // adjust this path if necessary

#include <iostream>
#include <vector>

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<int>(ty) << std::endl;
}
}

return 0;;
}

+ 24
- 8
binaries/cli/src/template/cxx/mod.rs View File

@@ -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<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())?;

println!(
"Created new C++ dataflow at `{name}` at {}",
@@ -51,6 +56,19 @@ fn create_dataflow(name: String, path: Option<PathBuf>) -> 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<PathBuf>) -> 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<PathBuf>) -> Result<(), eyre::ErrR
Ok(())
}

fn create_custom_node(name: String, path: Option<PathBuf>) -> Result<(), eyre::ErrReport> {
const NODE: &str = include_str!("node-template.cc");

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");
}
@@ -100,7 +116,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.cc");
fs::write(&node_path, NODE)
fs::write(&node_path, template_scripts)
.with_context(|| format!("failed to write `{}`", node_path.display()))?;

// TODO: Makefile?


+ 39
- 0
binaries/cli/src/template/cxx/talker-template.cc View File

@@ -0,0 +1,39 @@
#include "dora-node-api.h" // adjust this path if necessary

#include <iostream>
#include <vector>


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<const uint8_t> message_slice{reinterpret_cast<const uint8_t*>(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<int>(ty) << std::endl;
}
}

return 0;
}

Loading…
Cancel
Save