Skip to content

Commit

Permalink
added a simplelogger
Browse files Browse the repository at this point in the history
  • Loading branch information
gbin committed May 18, 2024
1 parent f1dec2e commit 2c75722
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 36 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[workspace]
members = ["copper", "copper_derive", "copper_derive_test", "examples/pluginload", "examples/v4lsrc"]
members = ["copper", "copper_derive", "copper_derive_test", "examples/pluginload", "examples/simplelogger", "examples/v4lsrc"]
resolver = "2"
62 changes: 40 additions & 22 deletions copper/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use petgraph::dot::Dot;
use std::collections::HashMap;

use petgraph::dot::Config as PetConfig;
use petgraph::dot::Dot;
use petgraph::stable_graph::StableDiGraph;
use serde::{Serialize, Deserialize};
use uom::si::rational::Time;
use uom::si::time::nanosecond;
use ron::Options;
use ron::extensions::Extensions;
use std::collections::HashMap;
use ron::Options;
use ron::value::Value as RonValue;

use serde::{Deserialize, Serialize};
use uom::si::rational::Time;
use uom::si::time::nanosecond;

pub type ConfigNodeId = u32;
pub type NodeConfig = HashMap<String, Value>;
Expand Down Expand Up @@ -71,7 +71,6 @@ impl From<Value> for String {
}
}


#[derive(Serialize, Deserialize, Debug)]
pub struct ConfigNode {
instance_name: String,
Expand All @@ -80,7 +79,7 @@ pub struct ConfigNode {
#[serde(skip_serializing_if = "Option::is_none")]
base_period_ns: Option<isize>,
#[serde(skip_serializing_if = "Option::is_none")]
instance_config:Option<NodeConfig>,
instance_config: Option<NodeConfig>,
}

impl ConfigNode {
Expand All @@ -101,7 +100,8 @@ impl ConfigNode {

#[allow(dead_code)]
pub fn base_period(&self) -> Option<Time> {
self.base_period_ns.map(|frequency| Time::new::<nanosecond>(frequency.into()))
self.base_period_ns
.map(|frequency| Time::new::<nanosecond>(frequency.into()))
}

pub fn set_base_period(mut self, period: Time) -> Self {
Expand All @@ -121,12 +121,13 @@ impl ConfigNode {
if self.instance_config.is_none() {
self.instance_config = Some(HashMap::new());
}
self.instance_config.as_mut().unwrap().insert(key.to_string(), value.into());
self.instance_config
.as_mut()
.unwrap()
.insert(key.to_string(), value.into());
}

}


#[derive(Serialize, Deserialize, Debug)]
pub struct CopperConfig {
pub graph: StableDiGraph<ConfigNode, String, ConfigNodeId>,
Expand All @@ -147,7 +148,8 @@ impl CopperConfig {
}

pub fn connect(&mut self, source: ConfigNodeId, target: ConfigNodeId, msg_type: &str) {
self.graph.add_edge(source.into(), target.into(), msg_type.to_string());
self.graph
.add_edge(source.into(), target.into(), msg_type.to_string());
}

pub fn get_options() -> Options {
Expand All @@ -164,7 +166,9 @@ impl CopperConfig {
}

pub fn deserialize(ron: &str) -> Self {
Self::get_options().from_str(ron).expect("Syntax Error in config")
Self::get_options()
.from_str(ron)
.expect("Syntax Error in config")
}

pub fn render(&self, output: &mut dyn std::io::Write) {
Expand All @@ -176,9 +180,10 @@ impl CopperConfig {
// tests
#[cfg(test)]
mod tests {
use super::*;
use uom::si::time::second;
use uom::si::time::millisecond;
use uom::si::time::second;

use super::*;

#[test]
fn test_base_period() {
Expand All @@ -189,10 +194,15 @@ mod tests {
base_period_ns: Some(1_000_000_000),
};
assert_eq!(node.base_period(), Some(Time::new::<second>(1.into())));

let node = ConfigNode::new("test2", "package::Plugin").set_base_period(Time::new::<millisecond>(500.into()));

let node =
ConfigNode::new("test2", "package::Plugin")
.set_base_period(Time::new::<millisecond>(500.into()));
assert_eq!(node.base_period_ns, Some(500_000_000));
assert_eq!(node.base_period(), Some(Time::new::<nanosecond>(500_000_000.into())));
assert_eq!(
node.base_period(),
Some(Time::new::<nanosecond>(500_000_000.into()))
);
}

#[test]
Expand All @@ -210,12 +220,20 @@ mod tests {
#[test]
fn test_serialize_with_params() {
let mut config = CopperConfig::new();
let mut camera = ConfigNode::new("copper-camera", "camerapkg::Camera").set_base_period(Time::new::<second>(60.into()));
let mut camera = ConfigNode::new("copper-camera", "camerapkg::Camera")
.set_base_period(Time::new::<second>(60.into()));
camera.set_param::<Value>("resolution-height", 1080.into());
config.add_node(camera);
let serialized = config.serialize();
println!("{}", serialized);
let deserialized = CopperConfig::deserialize(&serialized);
assert_eq!(deserialized.get_node(0).unwrap().get_param::<i32>("resolution-height").unwrap(), 1080);
assert_eq!(
deserialized
.get_node(0)
.unwrap()
.get_param::<i32>("resolution-height")
.unwrap(),
1080
);
}
}
20 changes: 12 additions & 8 deletions copper_derive_test/build.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
use std::env;
use std::io::Write;
use std::path::PathBuf;
use copper::config::CopperConfig;
use copper::config::ConfigNode;
use copper::config::Value;

use uom::si::time::second;
use uom::si::time::Time;

fn main() {
use copper::config::ConfigNode;
use copper::config::CopperConfig;
use copper::config::Value;

fn main() {
// Generate a config
let mut copperconfig = CopperConfig::new();
let mut camera = ConfigNode::new("copper-camera", "camerapkg::Camera").set_base_period(Time::new::<second>(60.into()));
let mut camera =
ConfigNode::new("camera", "camerapkg::Camera")
.set_base_period(Time::new::<second>(60.into()));
camera.set_param::<Value>("resolution-height", 1080.into());
// camera.set_param::<Value>("resolution-width", 1920.into());
let mut isp = ConfigNode::new("copper-isp", "isppkg::Isp").set_base_period(Time::new::<second>(1.into()));
let mut isp =
ConfigNode::new("copper-isp", "isppkg::Isp").set_base_period(Time::new::<second>(1.into()));
// isp.set_param::<Value>("tone", 1.3.into());
let algo = ConfigNode::new("copper-algo", "algopkg::Algo").set_base_period(Time::new::<second>(5.into()));
let algo = ConfigNode::new("copper-algo", "algopkg::Algo")
.set_base_period(Time::new::<second>(5.into()));
let n1 = copperconfig.add_node(isp);
let n2 = copperconfig.add_node(camera);
let n3 = copperconfig.add_node(algo);
Expand Down
2 changes: 1 addition & 1 deletion examples/pluginload/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ edition = "2021"
[dependencies]
uom = { version = "0.36.0", features = ["rational"] }
copper = { path = "../../copper" }
camreader = { path = "../v4lsrc" }
v4lsrc = { path = "../v4lsrc" }

[build-dependencies]
cargo_metadata = "0.18.1"
Expand Down
9 changes: 9 additions & 0 deletions examples/simplelogger/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "simplelogger"
version = "0.1.0"
edition = "2021"

[dependencies]
copper = { path = "../../copper" }
v4lsrc = { path = "../v4lsrc" }
serde = { version = "1.0.202", features = ["derive"] }
59 changes: 59 additions & 0 deletions examples/simplelogger/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use std::fs::File;
use std::io::Write;

use serde::{Deserialize, Serialize};

use copper::config::NodeConfig;
use copper::cutask::{CuResult, CuSinkTask};
use v4lsrc::ImageMsg;

struct SimpleLogger {
path: String,
log_file: Option<File>,
}

impl CuSinkTask for SimpleLogger {
type Input = ImageMsg;

fn new(config: NodeConfig) -> CuResult<Self>
where
Self: Sized,
{
let path = (*config.get("path").unwrap()).clone().into();
Ok(SimpleLogger {
path,
log_file: None,
})
}

fn start(&mut self) -> CuResult<()> {
let log_file = File::create(&self.path).unwrap();
self.log_file = Some(log_file);
Ok(())
}

fn stop(&mut self) -> CuResult<()> {
Ok(())
}

fn process(&mut self, input: &Self::Input) -> CuResult<()> {
let log_file = self.log_file.as_mut().unwrap();
for line in input.buffer.iter() {
log_file.write_all(line).unwrap();
}
Ok(())
}
}

#[cfg(test)]
mod tests {
use super::*;

// ignore this test because it requires a camera to be connected to the computer
// it is still runnable if specifically called with `cargo test emulate_runtime`
#[ignore]
#[test]
fn emulate_runtime() -> CuResult<()> {
Ok(())
}
}
2 changes: 1 addition & 1 deletion examples/v4lsrc/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
name = "camreader"
name = "v4lsrc"
version = "0.1.0"
edition = "2021"

Expand Down
7 changes: 4 additions & 3 deletions examples/v4lsrc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ use copper::cutask::{CuResult, CuSrcTask};
use copper::serde::arrays;

#[derive(Serialize, Deserialize)]
struct ImageMsg {
pub struct ImageMsg {
#[serde(with = "arrays")]
buffer: [[u8; 1920]; 1200],
pub buffer: [[u8; 1920]; 1200],
}

impl Default for ImageMsg {
Expand Down Expand Up @@ -51,7 +51,8 @@ impl CuSrcTask for Video4LinuxSource {
where
Self: Sized,
{
let device = Device::open("/dev/video0").unwrap();
let dev: String = (*config.get("dev").unwrap()).clone().into();
let device = Device::open(dev).unwrap();
Ok(Video4LinuxSource {
device,
stream: None,
Expand Down

0 comments on commit 2c75722

Please sign in to comment.