use std::io;
use std::io::Write;
use std::result::Result;
use std::cell::RefCell;
use std::ops::Deref;
use dvcompute::simulation;
use dvcompute::simulation::error::*;
use dvcompute::simulation::Point;
use dvcompute::simulation::Specs;
use dvcompute::simulation::event::*;
#[cfg(feature="cons_mode")]
use dvcompute::simulation::comm::context::LogicalProcessContext;
use crate::simulation::results::*;
fn into_string_result(w: Vec<u8>) -> simulation::Result<String> {
match String::from_utf8(w) {
Result::Ok(x) => Result::Ok(x),
Result::Err(e) => {
let msg = format!("{}", e);
let err = Error::panic(msg);
Result::Err(err)
}
}
}
#[inline]
pub fn show_result<M>(comp: M, locale: ResultLocale) -> impl Event<Item = String>
where M: ResultWrite
{
delay_event(move || {
let w = Grc::new(RefCell::new(Vec::new()));
write_result(comp, w.clone(), locale)
.and_then(move |()| {
cons_event(move |_p| {
let w = w.replace(Vec::new());
into_string_result(w)
})
})
})
}
#[inline]
pub fn show_results_in_integ_times<F, M>(f: F, locale: ResultLocale) -> impl Simulation<Item = String>
where F: Fn() -> M + 'static,
M: ResultWrite + 'static
{
delay_simulation(move || {
let w = Grc::new(RefCell::new(Vec::new()));
write_results_in_integ_times(f, w.clone(), locale)
.and_then(move |()| {
cons_simulation(move |_r| {
let w = w.replace(Vec::new());
into_string_result(w)
})
})
})
}
#[inline]
pub fn show_result_in_stop_time<M>(comp: M, locale: ResultLocale) -> impl Simulation<Item = String>
where M: ResultWrite + 'static
{
delay_simulation(move || {
let w = Grc::new(RefCell::new(Vec::new()));
write_result_in_stop_time(comp, w.clone(), locale)
.and_then(move |()| {
cons_simulation(move |_r| {
let w = w.replace(Vec::new());
into_string_result(w)
})
})
})
}
#[inline]
pub fn print_result<M>(comp: M, locale: ResultLocale) -> impl Event<Item = ()>
where M: ResultWrite
{
let w = Grc::new(RefCell::new(io::stdout()));
write_result(comp, w, locale)
}
#[inline]
pub fn print_results_in_integ_times<F, M>(f: F, locale: ResultLocale) -> impl Simulation<Item = ()>
where F: Fn() -> M + 'static,
M: ResultWrite + 'static
{
let w = Grc::new(RefCell::new(io::stdout()));
write_results_in_integ_times(f, w, locale)
}
#[inline]
pub fn print_result_in_stop_time<M>(comp: M, locale: ResultLocale) -> impl Simulation<Item = ()>
where M: ResultWrite + 'static
{
let w = Grc::new(RefCell::new(io::stdout()));
write_result_in_stop_time(comp, w, locale)
}
#[inline]
pub fn write_result<M, W>(comp: M, w: Grc<RefCell<W>>, locale: ResultLocale) -> impl Event<Item = ()>
where M: ResultWrite,
W: Write
{
cons_event(move |p| {
let mut w = w.borrow_mut();
let w = &mut *w;
comp.write(w, &locale, p)
})
}
pub fn write_results_in_integ_times<F, M, W>(f: F, w: Grc<RefCell<W>>, locale: ResultLocale) -> impl Simulation<Item = ()>
where F: Fn() -> M + 'static,
M: ResultWrite + 'static,
W: Write + 'static
{
enqueue_io_events_with_integ_times(move || {
let comp = f();
let w = w.clone();
let locale = locale.clone();
cons_event(move |p| {
let mut w = w.borrow_mut();
let w = &mut *w;
comp.write(w, &locale, p)
})
.into_boxed()
})
.run_in_start_time()
.and_then(move |()| {
return_event(())
.run_in_stop_time()
})
}
pub fn write_result_in_stop_time<M, W>(comp: M, w: Grc<RefCell<W>>, locale: ResultLocale) -> impl Simulation<Item = ()>
where M: ResultWrite + 'static,
W: Write + 'static
{
cons_event(move |p| {
Result::Ok(p.run.specs.stop_time)
})
.and_then(move |t2| {
enqueue_io_event(t2, {
cons_event(move |p| {
let mut w = w.borrow_mut();
let w = &mut *w;
comp.write(w, &locale, p)
})
.into_boxed()
})
})
.run_in_start_time()
.and_then(move |()| {
return_event(())
.run_in_stop_time()
})
}
#[cfg(any(feature="seq_mode", feature="wasm_mode"))]
pub fn show_simulation_results_in_integ_times<S, M>(sim: S, specs: Specs, locale: ResultLocale) -> simulation::Result<String>
where S: Simulation<Item = M>,
M: ResultWrite + 'static
{
let w = Grc::new(RefCell::new(Vec::new()));
write_simulation_results_in_integ_times(sim, specs, w.clone(), locale)?;
let w = w.replace(Vec::new());
into_string_result(w)
}
#[cfg(feature="cons_mode")]
pub fn show_simulation_results_in_integ_times<S, M>(sim: S, specs: Specs, ctx: &LogicalProcessContext, locale: ResultLocale) -> simulation::Result<String>
where S: Simulation<Item = M>,
M: ResultWrite + 'static
{
let w = Grc::new(RefCell::new(Vec::new()));
write_simulation_results_in_integ_times(sim, specs, ctx, w.clone(), locale)?;
let w = w.replace(Vec::new());
into_string_result(w)
}
#[cfg(any(feature="seq_mode", feature="wasm_mode"))]
pub fn show_simulation_result_in_stop_time<S, M>(sim: S, specs: Specs, locale: ResultLocale) -> simulation::Result<String>
where S: Simulation<Item = M>,
M: ResultWrite + 'static
{
let w = Grc::new(RefCell::new(Vec::new()));
write_simulation_result_in_stop_time(sim, specs, w.clone(), locale)?;
let w = w.replace(Vec::new());
into_string_result(w)
}
#[cfg(feature="cons_mode")]
pub fn show_simulation_result_in_stop_time<S, M>(sim: S, specs: Specs, ctx: &LogicalProcessContext, locale: ResultLocale) -> simulation::Result<String>
where S: Simulation<Item = M>,
M: ResultWrite + 'static
{
let w = Grc::new(RefCell::new(Vec::new()));
write_simulation_result_in_stop_time(sim, specs, ctx, w.clone(), locale)?;
let w = w.replace(Vec::new());
into_string_result(w)
}
#[cfg(any(feature="seq_mode", feature="wasm_mode"))]
pub fn print_simulation_results_in_integ_times<S, M>(sim: S, specs: Specs, locale: ResultLocale) -> simulation::Result<()>
where S: Simulation<Item = M>,
M: ResultWrite + 'static
{
let w = Grc::new(RefCell::new(io::stdout()));
write_simulation_results_in_integ_times(sim, specs, w, locale)
}
#[cfg(feature="cons_mode")]
pub fn print_simulation_results_in_integ_times<S, M>(sim: S, specs: Specs, ctx: &LogicalProcessContext, locale: ResultLocale) -> simulation::Result<()>
where S: Simulation<Item = M>,
M: ResultWrite + 'static
{
let w = Grc::new(RefCell::new(io::stdout()));
write_simulation_results_in_integ_times(sim, specs, ctx, w, locale)
}
#[cfg(any(feature="seq_mode", feature="wasm_mode"))]
pub fn print_simulation_result_in_stop_time<S, M>(sim: S, specs: Specs, locale: ResultLocale) -> simulation::Result<()>
where S: Simulation<Item = M>,
M: ResultWrite + 'static
{
let w = Grc::new(RefCell::new(io::stdout()));
write_simulation_result_in_stop_time(sim, specs, w, locale)
}
#[cfg(feature="cons_mode")]
pub fn print_simulation_result_in_stop_time<S, M>(sim: S, specs: Specs, ctx: &LogicalProcessContext, locale: ResultLocale) -> simulation::Result<()>
where S: Simulation<Item = M>,
M: ResultWrite + 'static
{
let w = Grc::new(RefCell::new(io::stdout()));
write_simulation_result_in_stop_time(sim, specs, ctx, w, locale)
}
#[cfg(any(feature="seq_mode", feature="wasm_mode"))]
pub fn write_simulation_results_in_integ_times<S, M, W>(sim: S, specs: Specs, w: Grc<RefCell<W>>, locale: ResultLocale) -> simulation::Result<()>
where S: Simulation<Item = M>,
M: ResultWrite + 'static,
W: Write + 'static
{
sim.and_then(move |comp| {
let comp = Grc::new(comp);
write_results_in_integ_times(move || { comp.clone() }, w, locale)
})
.run(specs)
}
#[cfg(feature="cons_mode")]
pub fn write_simulation_results_in_integ_times<S, M, W>(sim: S, specs: Specs, ctx: &LogicalProcessContext, w: Grc<RefCell<W>>, locale: ResultLocale) -> simulation::Result<()>
where S: Simulation<Item = M>,
M: ResultWrite + 'static,
W: Write + 'static
{
sim.and_then(move |comp| {
let comp = Grc::new(comp);
write_results_in_integ_times(move || { comp.clone() }, w, locale)
})
.run(specs, ctx)
}
#[cfg(any(feature="seq_mode", feature="wasm_mode"))]
pub fn write_simulation_result_in_stop_time<S, M, W>(sim: S, specs: Specs, w: Grc<RefCell<W>>, locale: ResultLocale) -> simulation::Result<()>
where S: Simulation<Item = M>,
M: ResultWrite + 'static,
W: Write + 'static
{
sim.and_then(move |comp| {
write_result_in_stop_time(comp, w, locale)
})
.run(specs)
}
#[cfg(feature="cons_mode")]
pub fn write_simulation_result_in_stop_time<S, M, W>(sim: S, specs: Specs, ctx: &LogicalProcessContext, w: Grc<RefCell<W>>, locale: ResultLocale) -> simulation::Result<()>
where S: Simulation<Item = M>,
M: ResultWrite + 'static,
W: Write + 'static
{
sim.and_then(move |comp| {
write_result_in_stop_time(comp, w, locale)
})
.run(specs, ctx)
}
pub trait ResultWrite {
fn write<W>(&self, write: &mut W, locale: &ResultLocale, p: &Point) -> simulation::Result<()>
where W: Write;
}
impl ResultWrite for ResultSet {
fn write<W>(&self, write: &mut W, locale: &ResultLocale, p: &Point) -> simulation::Result<()>
where W: Write
{
let x1 = ResultSource::from_text(String::from("----------"));
let x2 = ResultSource::time();
x1.write(write, locale, p)?;
x2.write(write, locale, p)?;
for source in self.get_sources() {
source.write(write, locale, p)?;
}
Result::Ok(())
}
}
impl ResultWrite for ResultSource {
fn write<W>(&self, write: &mut W, locale: &ResultLocale, p: &Point) -> simulation::Result<()>
where W: Write
{
write_source(self, write, 0, locale, p)
}
}
impl<T: ResultWrite> ResultWrite for Grc<T> {
fn write<W>(&self, write: &mut W, locale: &ResultLocale, p: &Point) -> simulation::Result<()>
where W: Write
{
self.deref().write(write, locale, p)
}
}
fn write_source<W: Write>(source: &ResultSource, w: &mut W, indent: usize, locale: &ResultLocale, p: &Point) -> simulation::Result<()> {
match source {
&ResultSource::Item(ref x) => {
write_source_ex(source, w, indent, x.get_name(), locale, p)
},
&ResultSource::Vec(ref x) => {
write_source_ex(source, w, indent, x.name.clone(), locale, p)
},
&ResultSource::Object(ref x) => {
write_source_ex(source, w, indent, x.name.clone(), locale, p)
},
&ResultSource::Separator(ref x) => {
write_source_ex(source, w, indent, x.text.clone(), locale, p)
}
}
}
fn write_source_ex<W: Write>(source: &ResultSource, w: &mut W, indent: usize, label: ResultName, locale: &ResultLocale, p: &Point) -> simulation::Result<()> {
match source {
&ResultSource::Item(ref x) => {
let a = match x.get_string_val() {
Result::Ok(a) => Result::Ok(a),
Result::Err(msg) => Result::Err(Error::panic(msg))
};
let a = a?;
let a = (a.data)();
let a = a.call_event(p)?;
match write_item(x.deref(), a, w, indent, label, locale, p) {
Result::Ok(z) => Result::Ok(z),
Result::Err(err) => Result::Err(Error::io(err))
}
},
&ResultSource::Vec(ref x) => {
let _ = match write_descr(&x.id, w, indent, label.clone(), locale, p) {
Result::Ok(z) => Result::Ok(z),
Result::Err(err) => Result::Err(Error::io(err))
}?;
for i in 0..(x.items.len()) {
let source = &x.items[i];
let indent = indent + 2;
let label = label.clone() + &x.subscript[i];
write_source_ex(source, w, indent, label, locale, p)?;
}
Result::Ok(())
},
&ResultSource::Object(ref x) => {
let _ = match write_descr(&x.id, w, indent, label.clone(), locale, p) {
Result::Ok(z) => Result::Ok(z),
Result::Err(err) => Result::Err(Error::io(err))
}?;
for i in 0..(x.props.len()) {
let source = &x.props[i].source;
let indent = indent + 2;
let label = x.props[i].label.clone();
write_source_ex(source, w, indent, label, locale, p)?;
}
Result::Ok(())
},
&ResultSource::Separator(_) => {
let _ = match write_separator(w, indent, label.clone(), p) {
Result::Ok(z) => Result::Ok(z),
Result::Err(err) => Result::Err(Error::io(err))
}?;
Result::Ok(())
}
}
}
fn write_item<W: Write>(item: &dyn ResultItem, rep: String, w: &mut W, indent: usize, label: ResultName, locale: &ResultLocale, _p: &Point) -> io::Result<()> {
let tab = " ".repeat(indent);
write!(w, "{}", tab)?;
write!(w, "// ")?;
writeln!(w, "{}", item.get_id().get_descr(locale))?;
write!(w, "{}", tab)?;
write!(w, "{}", label)?;
write!(w, " = ")?;
writeln!(w, "{}", rep)?;
writeln!(w, "")?;
Result::Ok(())
}
fn write_descr<W: Write>(id: &ResultId, w: &mut W, indent: usize, label: ResultName, locale: &ResultLocale, _p: &Point) -> io::Result<()> {
let tab = " ".repeat(indent);
write!(w, "{}", tab)?;
write!(w, "// ")?;
writeln!(w, "{}", id.get_descr(locale))?;
write!(w, "{}", tab)?;
write!(w, "{}", label)?;
writeln!(w, ":")?;
writeln!(w, "")?;
Result::Ok(())
}
fn write_separator<W: Write>(w: &mut W, indent: usize, label: ResultName, _p: &Point) -> io::Result<()> {
let tab = " ".repeat(indent);
write!(w, "{}", tab)?;
write!(w, "{}", label)?;
writeln!(w, "")?;
writeln!(w, "")?;
Result::Ok(())
}