use std::rc::Rc;
use std::result;
use std::cell::RefCell;
use dvcompute::simulation;
use dvcompute::simulation::Run;
use dvcompute::simulation::simulation::*;
use dvcompute::simulation::simulation::ops::*;
use dvcompute::simulation::parameter::*;
use dvcompute::simulation::parameter::ops::*;
use dvcompute::simulation::event::*;
use dvcompute::simulation::event::ops::*;
use dvcompute::simulation::observable::*;
use dvcompute::simulation::observable::source::*;
use dvcompute::simulation::ref_comp::*;
use dvcompute::simulation::queue;
use dvcompute::simulation::strategy::*;
use dvcompute_gpss::simulation::queue::*;
use dvcompute_gpss::simulation::facility::*;
use dvcompute_gpss::simulation::storage::*;
use dvcompute_utils::simulation::stats::*;
use dvcompute_utils::collections::im::OrdMap;
use dvcompute_utils::grc::Grc;
use self::locale::*;
pub mod locale;
pub mod io;
pub type ResultError = String;
pub type Result<T> = result::Result<T, ResultError>;
pub trait ResultProvider {
fn get_source(self, name: ResultName, descr: ResultDescription) -> ResultSource
where Self: Sized
{
let name_path = vec![name.clone()];
let title = result_name_into_title(name.clone());
let id = ResultId::UserDefined(UserDefinedResult { name: name.clone(), descr, title });
let id_path = vec![id.clone()];
self.get_source_by_id(name, name_path, id, id_path)
}
fn get_source3(self, name: ResultName, descr: ResultDescription, title: ResultDescription) -> ResultSource
where Self: Sized
{
let name_path = vec![name.clone()];
let id = ResultId::UserDefined(UserDefinedResult { name: name.clone(), descr, title });
let id_path = vec![id.clone()];
self.get_source_by_id(name, name_path, id, id_path)
}
fn get_source_by_id(self, name: ResultName, name_path: Vec<ResultName>, id: ResultId, id_path: Vec<ResultId>) -> ResultSource;
}
pub type ResultSourceMap = OrdMap<ResultName, ResultSource>;
#[derive(Clone)]
pub enum ResultSource {
Item(Rc<dyn ResultItem>),
Object(Rc<ResultObject>),
Vec(Rc<ResultVec>),
Separator(Rc<ResultSeparator>)
}
impl ResultSource {
pub fn summary(&self) -> ResultSource {
match &self {
&ResultSource::Item(ref x) => x.summary(),
&ResultSource::Object(ref x) => (x.summary)(),
&ResultSource::Vec(ref x) => (x.summary)(),
&ResultSource::Separator(x) => ResultSource::Separator(x.clone())
}
}
pub fn observable(&self) -> ResultObservable {
match &self {
&ResultSource::Item(ref x) => x.observable(),
&ResultSource::Object(ref x) => (x.observable)(),
&ResultSource::Vec(ref x) => (x.observable)(),
&ResultSource::Separator(_) => ResultObservable::empty()
}
}
pub fn flatten(&self) -> Vec<Rc<dyn ResultItem>> {
match self {
&ResultSource::Item(ref x) => {
vec![x.clone()]
},
&ResultSource::Object(ref x) => {
let mut ys = Vec::new();
for p in x.props.iter() {
let mut zs = p.source.flatten();
ys.append(&mut zs);
}
ys
},
&ResultSource::Vec(ref x) => {
let mut ys = Vec::new();
for i in x.items.iter() {
let mut zs = i.flatten();
ys.append(&mut zs);
}
ys
},
&ResultSource::Separator(_) => {
vec![]
}
}
}
pub fn get_name(&self) -> ResultName {
match self {
&ResultSource::Item(ref x) => x.get_name().clone(),
&ResultSource::Object(ref x) => x.name.clone(),
&ResultSource::Vec(ref x) => x.name.clone(),
&ResultSource::Separator(_) => String::new()
}
}
pub fn expand(&self) -> ResultSource {
match self {
&ResultSource::Item(ref x) => x.expand(),
&ResultSource::Object(ref x) => {
let mut ys = Vec::with_capacity(x.props.len());
for p in x.props.iter() {
let p2 = ResultProperty {
label: p.label.clone(),
id: p.id.clone(),
source: p.source.expand()
};
ys.push(p2);
}
let z = ResultObject {
name: x.name.clone(),
id: x.id.clone(),
type_id: x.type_id.clone(),
props: ys,
observable: x.observable.clone(),
summary: x.summary.clone()
};
ResultSource::Object(Rc::new(z))
},
&ResultSource::Vec(ref x) => {
let mut ys = Vec::with_capacity(x.items.len());
for i in x.items.iter() {
ys.push(i.expand());
}
let z = ResultVec {
name: x.name.clone(),
id: x.id.clone(),
items: ys,
subscript: x.subscript.clone(),
observable: x.observable.clone(),
summary: x.summary.clone()
};
ResultSource::Vec(Rc::new(z))
},
&ResultSource::Separator(ref x) => {
let z = ResultSeparator { text: x.text.clone() };
ResultSource::Separator(Rc::new(z))
}
}
}
pub fn get_int_vals(&self) -> Result<Vec<ResultValue<isize>>> {
let xs = self.flatten();
let mut ys = Vec::with_capacity(xs.len());
for x in xs {
ys.push(x.get_int_val()?);
}
result::Result::Ok(ys)
}
pub fn get_int_vec_vals(&self) -> Result<Vec<ResultValue<Vec<isize>>>> {
let xs = self.flatten();
let mut ys = Vec::with_capacity(xs.len());
for x in xs {
ys.push(x.get_int_vec_val()?);
}
result::Result::Ok(ys)
}
pub fn get_int_stats_vals(&self) -> Result<Vec<ResultValue<SamplingStats<isize>>>> {
let xs = self.flatten();
let mut ys = Vec::with_capacity(xs.len());
for x in xs {
ys.push(x.get_int_stats_val()?);
}
result::Result::Ok(ys)
}
pub fn get_int_timing_stats_vals(&self) -> Result<Vec<ResultValue<TimingStats<isize>>>> {
let xs = self.flatten();
let mut ys = Vec::with_capacity(xs.len());
for x in xs {
ys.push(x.get_int_timing_stats_val()?);
}
result::Result::Ok(ys)
}
pub fn get_floating_vals(&self) -> Result<Vec<ResultValue<f64>>> {
let xs = self.flatten();
let mut ys = Vec::with_capacity(xs.len());
for x in xs {
ys.push(x.get_floating_val()?);
}
result::Result::Ok(ys)
}
pub fn get_floating_vec_vals(&self) -> Result<Vec<ResultValue<Vec<f64>>>> {
let xs = self.flatten();
let mut ys = Vec::with_capacity(xs.len());
for x in xs {
ys.push(x.get_floating_vec_val()?);
}
result::Result::Ok(ys)
}
pub fn get_floating_stats_vals(&self) -> Result<Vec<ResultValue<SamplingStats<f64>>>> {
let xs = self.flatten();
let mut ys = Vec::with_capacity(xs.len());
for x in xs {
ys.push(x.get_floating_stats_val()?);
}
result::Result::Ok(ys)
}
pub fn get_floating_timing_stats_vals(&self) -> Result<Vec<ResultValue<TimingStats<f64>>>> {
let xs = self.flatten();
let mut ys = Vec::with_capacity(xs.len());
for x in xs {
ys.push(x.get_floating_timing_stats_val()?);
}
result::Result::Ok(ys)
}
pub fn get_string_vals(&self) -> Result<Vec<ResultValue<String>>> {
let xs = self.flatten();
let mut ys = Vec::with_capacity(xs.len());
for x in xs {
ys.push(x.get_string_val()?);
}
result::Result::Ok(ys)
}
pub fn from_stats<E>(cont: ResultValue<SamplingStats<E>>) -> ResultSource
where ResultValue<E>: ResultItem,
ResultValue<SamplingStats<E>>: ResultItem,
E: StatData + Copy + Clone + 'static
{
let props = vec![
cont.clone().map_prop("count", ResultId::SamplingStatsCount, move |x| { x.count as isize }),
cont.clone().map_prop("mean", ResultId::SamplingStatsMean, move |x| { x.mean }),
cont.clone().map_prop("mean2", ResultId::SamplingStatsMean2, move |x| { x.mean2 }),
cont.clone().map_prop("std", ResultId::SamplingStatsDeviation, move |x| { x.deviation() }),
cont.clone().map_prop("var", ResultId::SamplingStatsVariance, move |x| { x.variance() }),
cont.clone().map_prop("min", ResultId::SamplingStatsMin, move |x| { x.min }),
cont.clone().map_prop("max", ResultId::SamplingStatsMax, move |x| { x.max })
];
let source = ResultObject {
name: cont.name.clone(),
id: cont.id.clone(),
type_id: ResultId::SamplingStats,
observable: cont.observable.clone(),
summary: Rc::new(move || { ResultSource::summary_from_stats(cont.clone()) }),
props: props
};
let source = Rc::new(source);
ResultSource::Object(source)
}
pub fn summary_from_stats<E>(cont: ResultValue<SamplingStats<E>>) -> ResultSource
where ResultValue<E>: ResultItem,
ResultValue<SamplingStats<E>>: ResultItem,
E: Clone + 'static
{
ResultSource::Item(Rc::new(cont.get_string_val().unwrap()))
}
pub fn from_timing_stats<E>(cont: ResultValue<TimingStats<E>>) -> ResultSource
where ResultValue<E>: ResultItem,
ResultValue<TimingStats<E>>: ResultItem,
E: StatData + Copy + Clone + 'static
{
let props = vec![
cont.clone().map_prop("count", ResultId::TimingStatsCount, move |x| { x.count as isize }),
cont.clone().map_prop("mean", ResultId::TimingStatsMean, move |x| { x.mean() }),
cont.clone().map_prop("std", ResultId::TimingStatsDeviation, move |x| { x.deviation() }),
cont.clone().map_prop("var", ResultId::TimingStatsVariance, move |x| { x.variance() }),
cont.clone().map_prop("min", ResultId::TimingStatsMin, move |x| { x.min }),
cont.clone().map_prop("max", ResultId::TimingStatsMax, move |x| { x.max }),
cont.clone().map_prop("min_time", ResultId::TimingStatsMinTime, move |x| { x.min_time }),
cont.clone().map_prop("max_time", ResultId::TimingStatsMaxTime, move |x| { x.max_time }),
cont.clone().map_prop("start_time", ResultId::TimingStatsStartTime, move |x| { x.start_time }),
cont.clone().map_prop("last_time", ResultId::TimingStatsLastTime, move |x| { x.last_time }),
cont.clone().map_prop("sum", ResultId::TimingStatsSum, move |x| { x.sum }),
cont.clone().map_prop("sum2", ResultId::TimingStatsSum2, move |x| { x.sum2 })
];
let source = ResultObject {
name: cont.name.clone(),
id: cont.id.clone(),
type_id: ResultId::TimingStats,
observable: cont.observable.clone(),
summary: Rc::new(move || { ResultSource::summary_from_timing_stats(cont.clone()) }),
props: props
};
let source = Rc::new(source);
ResultSource::Object(source)
}
pub fn summary_from_timing_stats<E>(cont: ResultValue<TimingStats<E>>) -> ResultSource
where ResultValue<E>: ResultItem,
ResultValue<TimingStats<E>>: ResultItem,
E: Clone + 'static
{
ResultSource::Item(Rc::new(cont.get_string_val().unwrap()))
}
pub fn from_queue(cont: ResultContainer<Queue>) -> ResultSource {
let props = vec![
cont.clone().prop("queue_empty",
ResultId::QueueEmpty,
move |x| { Queue::is_empty(x) },
move |x| { Queue::content_changed_(&x) }),
cont.clone().prop("queue_content",
ResultId::QueueContent,
move |x| { Queue::content(x) },
move |x| { Queue::content_changed_(&x) }),
cont.clone().prop("queue_content_stats",
ResultId::QueueContentStats,
move |x| { Queue::content_stats(x) },
move |x| { Queue::content_changed_(&x) }),
cont.clone().prop("enqueue_count",
ResultId::EnqueueCount,
move |x| { Queue::enqueue_count(x) },
move |x| { Queue::enqueue_count_changed_(&x) }),
cont.clone().prop("enqueue_zero_enty_count",
ResultId::EnqueueZeroEntryCount,
move |x| { Queue::enqueue_zero_entry_count(x) },
move |x| { Queue::enqueue_zero_entry_count_changed_(&x) }),
cont.clone().prop("queue_wait_time",
ResultId::QueueWaitTime,
move |x| { Queue::wait_time(x) },
move |x| { Queue::wait_time_changed_(&x) }),
cont.clone().prop("queue_non_zero_entry_wait_time",
ResultId::QueueNotZeroEntryWaitTime,
move |x| { Queue::non_zero_entry_wait_time(x) },
move |x| { Queue::non_zero_entry_wait_time_changed_(&x) }),
cont.clone().prop("queue_rate",
ResultId::QueueRate,
move |x| { Queue::rate(x) },
move |x| { Queue::rate_changed_(&x) })
];
let source = ResultObject {
name: cont.name.clone(),
id: cont.id.clone(),
type_id: ResultId::Queue,
observable: cont.observable.clone(),
summary: Rc::new(move || { ResultSource::summary_from_queue(cont.clone()) }),
props: props
};
let source = Rc::new(source);
ResultSource::Object(source)
}
pub fn summary_from_queue(cont: ResultContainer<Queue>) -> ResultSource {
let props = vec![
cont.clone().prop("queue_content_stats",
ResultId::QueueContentStats,
move |x| { Queue::content_stats(x) },
move |x| { Queue::content_changed_(&x) }),
cont.clone().prop("enqueue_count",
ResultId::EnqueueCount,
move |x| { Queue::enqueue_count(x) },
move |x| { Queue::enqueue_count_changed_(&x) }),
cont.clone().prop("enqueue_zero_enty_count",
ResultId::EnqueueZeroEntryCount,
move |x| { Queue::enqueue_zero_entry_count(x) },
move |x| { Queue::enqueue_zero_entry_count_changed_(&x) }),
cont.clone().prop("queue_wait_time",
ResultId::QueueWaitTime,
move |x| { Queue::wait_time(x) },
move |x| { Queue::wait_time_changed_(&x) }),
cont.clone().prop("queue_non_zero_entry_wait_time",
ResultId::QueueNotZeroEntryWaitTime,
move |x| { Queue::non_zero_entry_wait_time(x) },
move |x| { Queue::non_zero_entry_wait_time_changed_(&x) }),
cont.clone().prop("queue_rate",
ResultId::QueueRate,
move |x| { Queue::rate(x) },
move |x| { Queue::rate_changed_(&x) })
];
let source = ResultObject {
name: cont.name.clone(),
id: cont.id.clone(),
type_id: ResultId::Queue,
observable: cont.observable.clone(),
summary: Rc::new(move || { ResultSource::summary_from_queue(cont.clone()) }),
props: props
};
let source = Rc::new(source);
ResultSource::Object(source)
}
pub fn from_facility<T: 'static>(cont: ResultContainer<Facility<T>>) -> ResultSource {
let props = vec![
cont.clone().prop("queue_count",
ResultId::FacilityQueueCount,
move |x| { Facility::queue_count(x) },
move |x| { Facility::queue_count_changed_(&x) }),
cont.clone().prop("queue_count_stats",
ResultId::FacilityQueueCountStats,
move |x| { Facility::queue_count_stats(x) },
move |x| { Facility::queue_count_changed_(&x) }),
cont.clone().prop("total_wait_time",
ResultId::FacilityTotalWaitTime,
move |x| { Facility::total_wait_time(x) },
move |x| { Facility::wait_time_changed_(&x) }),
cont.clone().prop("wait_time",
ResultId::FacilityWaitTime,
move |x| { Facility::wait_time(x) },
move |x| { Facility::wait_time_changed_(&x) }),
cont.clone().prop("total_holding_time",
ResultId::FacilityTotalHoldingTime,
move |x| { Facility::total_holding_time(x) },
move |x| { Facility::holding_time_changed_(&x) }),
cont.clone().prop("holding_time",
ResultId::FacilityHoldingTime,
move |x| { Facility::holding_time(x) },
move |x| { Facility::holding_time_changed_(&x) }),
cont.clone().integ_prop("interrupted",
ResultId::FacilityInterrupted,
move |x| { Facility::is_interrupted(x) }),
cont.clone().prop("count",
ResultId::FacilityCount,
move |x| { Facility::count(x) },
move |x| { Facility::count_changed_(&x) }),
cont.clone().prop("count_stats",
ResultId::FacilityCountStats,
move |x| { Facility::count_stats(x) },
move |x| { Facility::count_changed_(&x) }),
cont.clone().prop("capture_count",
ResultId::FacilityCaptureCount,
move |x| { Facility::capture_count(x) },
move |x| { Facility::capture_count_changed_(&x) }),
cont.clone().prop("util_count",
ResultId::FacilityUtilCount,
move |x| { Facility::util_count(x) },
move |x| { Facility::util_count_changed_(&x) }),
cont.clone().prop("util_count_stats",
ResultId::FacilityUtilCountStats,
move |x| { Facility::util_count_stats(x) },
move |x| { Facility::util_count_changed_(&x) })
];
let source = ResultObject {
name: cont.name.clone(),
id: cont.id.clone(),
type_id: ResultId::Facility,
observable: cont.observable.clone(),
summary: Rc::new(move || { ResultSource::summary_from_facility(cont.clone()) }),
props: props
};
let source = Rc::new(source);
ResultSource::Object(source)
}
pub fn summary_from_facility<T: 'static>(cont: ResultContainer<Facility<T>>) -> ResultSource {
let props = vec![
cont.clone().prop("queue_count_stats",
ResultId::FacilityQueueCountStats,
move |x| { Facility::queue_count_stats(x) },
move |x| { Facility::queue_count_changed_(&x) }),
cont.clone().prop("wait_time",
ResultId::FacilityWaitTime,
move |x| { Facility::wait_time(x) },
move |x| { Facility::wait_time_changed_(&x) }),
cont.clone().prop("holding_time",
ResultId::FacilityHoldingTime,
move |x| { Facility::holding_time(x) },
move |x| { Facility::holding_time_changed_(&x) }),
cont.clone().prop("count_stats",
ResultId::FacilityCountStats,
move |x| { Facility::count_stats(x) },
move |x| { Facility::count_changed_(&x) }),
cont.clone().prop("capture_count",
ResultId::FacilityCaptureCount,
move |x| { Facility::capture_count(x) },
move |x| { Facility::capture_count_changed_(&x) }),
cont.clone().prop("util_count_stats",
ResultId::FacilityUtilCountStats,
move |x| { Facility::util_count_stats(x) },
move |x| { Facility::util_count_changed_(&x) })
];
let source = ResultObject {
name: cont.name.clone(),
id: cont.id.clone(),
type_id: ResultId::Facility,
observable: cont.observable.clone(),
summary: Rc::new(move || { ResultSource::summary_from_facility(cont.clone()) }),
props: props
};
let source = Rc::new(source);
ResultSource::Object(source)
}
pub fn from_storage<T: 'static>(cont: ResultContainer<Storage<T>>) -> ResultSource {
let props = vec![
cont.clone().const_prop("capacity",
ResultId::StorageCapacity,
move |x| { x.capacity() }),
cont.clone().integ_prop("empty",
ResultId::StorageEmpty,
move |x| { Storage::is_empty(x) }),
cont.clone().integ_prop("full",
ResultId::StorageFull,
move |x| { Storage::is_full(x) }),
cont.clone().prop("queue_count",
ResultId::StorageQueueCount,
move |x| { Storage::queue_count(x) },
move |x| { Storage::queue_count_changed_(&x) }),
cont.clone().prop("queue_count_stats",
ResultId::StorageQueueCountStats,
move |x| { Storage::queue_count_stats(x) },
move |x| { Storage::queue_count_changed_(&x) }),
cont.clone().prop("total_wait_time",
ResultId::StorageTotalWaitTime,
move |x| { Storage::total_wait_time(x) },
move |x| { Storage::wait_time_changed_(&x) }),
cont.clone().prop("wait_time",
ResultId::StorageWaitTime,
move |x| { Storage::wait_time(x) },
move |x| { Storage::wait_time_changed_(&x) }),
cont.clone().integ_prop("average_holding_time",
ResultId::StorageAverageHoldingTime,
move |x| { Storage::average_holding_time(x) }),
cont.clone().prop("content",
ResultId::StorageContent,
move |x| { Storage::content(x) },
move |x| { Storage::content_changed_(&x) }),
cont.clone().prop("content_stats",
ResultId::StorageContentStats,
move |x| { Storage::content_stats(x) },
move |x| { Storage::content_changed_(&x) }),
cont.clone().prop("use_count",
ResultId::StorageUseCount,
move |x| { Storage::use_count(x) },
move |x| { Storage::use_count_changed_(&x) }),
cont.clone().prop("used_content",
ResultId::StorageUsedContent,
move |x| { Storage::used_content(x) },
move |x| { Storage::used_content_changed_(&x) }),
cont.clone().prop("util_count",
ResultId::StorageUtilCount,
move |x| { Storage::util_count(x) },
move |x| { Storage::util_count_changed_(&x) }),
cont.clone().prop("util_count_stats",
ResultId::StorageUtilCountStats,
move |x| { Storage::util_count_stats(x) },
move |x| { Storage::util_count_changed_(&x) })
];
let source = ResultObject {
name: cont.name.clone(),
id: cont.id.clone(),
type_id: ResultId::Storage,
observable: cont.observable.clone(),
summary: Rc::new(move || { ResultSource::summary_from_storage(cont.clone()) }),
props: props
};
let source = Rc::new(source);
ResultSource::Object(source)
}
pub fn summary_from_storage<T: 'static>(cont: ResultContainer<Storage<T>>) -> ResultSource {
let props = vec![
cont.clone().const_prop("capacity",
ResultId::StorageCapacity,
move |x| { x.capacity() }),
cont.clone().prop("queue_count_stats",
ResultId::StorageQueueCountStats,
move |x| { Storage::queue_count_stats(x) },
move |x| { Storage::queue_count_changed_(&x) }),
cont.clone().prop("wait_time",
ResultId::StorageWaitTime,
move |x| { Storage::wait_time(x) },
move |x| { Storage::wait_time_changed_(&x) }),
cont.clone().integ_prop("average_holding_time",
ResultId::StorageAverageHoldingTime,
move |x| { Storage::average_holding_time(x) }),
cont.clone().prop("content_stats",
ResultId::StorageContentStats,
move |x| { Storage::content_stats(x) },
move |x| { Storage::content_changed_(&x) }),
cont.clone().prop("use_count",
ResultId::StorageUseCount,
move |x| { Storage::use_count(x) },
move |x| { Storage::use_count_changed_(&x) }),
cont.clone().prop("used_content",
ResultId::StorageUsedContent,
move |x| { Storage::used_content(x) },
move |x| { Storage::used_content_changed_(&x) }),
cont.clone().prop("util_count_stats",
ResultId::StorageUtilCountStats,
move |x| { Storage::util_count_stats(x) },
move |x| { Storage::util_count_changed_(&x) })
];
let source = ResultObject {
name: cont.name.clone(),
id: cont.id.clone(),
type_id: ResultId::Storage,
observable: cont.observable.clone(),
summary: Rc::new(move || { ResultSource::summary_from_storage(cont.clone()) }),
props: props
};
let source = Rc::new(source);
ResultSource::Object(source)
}
pub fn from_bounded_queue<SI, SM, SO, T>(cont: ResultContainer<queue::stats::Queue<SI, SM, SO, T>>) -> ResultSource
where SI: QueueStrategy + 'static,
SM: QueueStrategy + 'static,
SO: QueueStrategy + 'static,
T: Clone + 'static
{
let props = vec![
cont.clone().prop("queue_empty",
ResultId::QueueEmpty,
move |x| { queue::stats::Queue::<SI, SM, SO, T>::is_empty(x) },
move |x| { queue::stats::Queue::<SI, SM, SO, T>::is_empty_changed_(&x) }),
cont.clone().prop("queue_full",
ResultId::QueueFull,
move |x| { queue::stats::Queue::<SI, SM, SO, T>::is_full(x) },
move |x| { queue::stats::Queue::<SI, SM, SO, T>::is_full_changed_(&x) }),
cont.clone().const_prop("capacity",
ResultId::QueueMaxCount,
move |x| { x.max_count() }),
cont.clone().prop("queue_count",
ResultId::QueueCount,
move |x| { queue::stats::Queue::<SI, SM, SO, T>::count(x) },
move |x| { queue::stats::Queue::<SI, SM, SO, T>::count_changed_(&x) }),
cont.clone().prop("queue_count_stats",
ResultId::QueueCountStats,
move |x| { queue::stats::Queue::<SI, SM, SO, T>::count_stats(x) },
move |x| { queue::stats::Queue::<SI, SM, SO, T>::count_changed_(&x) }),
cont.clone().prop("enqueue_count",
ResultId::EnqueueCount,
move |x| { queue::stats::Queue::<SI, SM, SO, T>::enqueue_count(x) },
move |x| { queue::stats::Queue::<SI, SM, SO, T>::enqueue_count_changed_(&x) }),
cont.clone().prop("enqueue_lost_count",
ResultId::EnqueueLostCount,
move |x| { queue::stats::Queue::<SI, SM, SO, T>::enqueue_lost_count(x) },
move |x| { queue::stats::Queue::<SI, SM, SO, T>::enqueue_lost_count_changed_(&x) }),
cont.clone().prop("enqueue_store_count",
ResultId::EnqueueStoreCount,
move |x| { queue::stats::Queue::<SI, SM, SO, T>::enqueue_store_count(x) },
move |x| { queue::stats::Queue::<SI, SM, SO, T>::enqueue_store_count_changed_(&x) }),
cont.clone().prop("dequeue_count",
ResultId::DequeueCount,
move |x| { queue::stats::Queue::<SI, SM, SO, T>::dequeue_count(x) },
move |x| { queue::stats::Queue::<SI, SM, SO, T>::dequeue_count_changed_(&x) }),
cont.clone().prop("dequeue_extract_count",
ResultId::DequeueExtractCount,
move |x| { queue::stats::Queue::<SI, SM, SO, T>::dequeue_extract_count(x) },
move |x| { queue::stats::Queue::<SI, SM, SO, T>::dequeue_extract_count_changed_(&x) }),
cont.clone().prop("queue_load_factor",
ResultId::QueueLoadFactor,
move |x| { queue::stats::Queue::<SI, SM, SO, T>::load_factor(x) },
move |x| { queue::stats::Queue::<SI, SM, SO, T>::load_factor_changed_(&x) }),
cont.clone().integ_prop("enqueue_rate",
ResultId::EnqueueRate,
move |x| { queue::stats::Queue::<SI, SM, SO, T>::enqueue_rate(x) }),
cont.clone().integ_prop("enqueue_store_rate",
ResultId::EnqueueStoreRate,
move |x| { queue::stats::Queue::<SI, SM, SO, T>::store_rate(x) }),
cont.clone().integ_prop("dequeue_rate",
ResultId::DequeueRate,
move |x| { queue::stats::Queue::<SI, SM, SO, T>::dequeue_rate(x) }),
cont.clone().integ_prop("dequeue_extract_rate",
ResultId::DequeueExtractRate,
move |x| { queue::stats::Queue::<SI, SM, SO, T>::dequeue_extract_rate(x) }),
cont.clone().prop("queue_wait_time",
ResultId::QueueWaitTime,
move |x| { queue::stats::Queue::<SI, SM, SO, T>::wait_time(x) },
move |x| { queue::stats::Queue::<SI, SM, SO, T>::wait_time_changed_(&x) }),
cont.clone().prop("queue_total_wait_time",
ResultId::QueueTotalWaitTime,
move |x| { queue::stats::Queue::<SI, SM, SO, T>::total_wait_time(x) },
move |x| { queue::stats::Queue::<SI, SM, SO, T>::total_wait_time_changed_(&x) }),
cont.clone().prop("enqueue_wait_time",
ResultId::EnqueueWaitTime,
move |x| { queue::stats::Queue::<SI, SM, SO, T>::enqueue_wait_time(x) },
move |x| { queue::stats::Queue::<SI, SM, SO, T>::enqueue_wait_time_changed_(&x) }),
cont.clone().prop("dequeue_wait_time",
ResultId::DequeueWaitTime,
move |x| { queue::stats::Queue::<SI, SM, SO, T>::dequeue_wait_time(x) },
move |x| { queue::stats::Queue::<SI, SM, SO, T>::dequeue_wait_time_changed_(&x) }),
cont.clone().prop("queue_rate",
ResultId::QueueRate,
move |x| { queue::stats::Queue::<SI, SM, SO, T>::rate(x) },
move |x| { queue::stats::Queue::<SI, SM, SO, T>::rate_changed_(&x) })
];
let source = ResultObject {
name: cont.name.clone(),
id: cont.id.clone(),
type_id: ResultId::Queue,
observable: cont.observable.clone(),
summary: Rc::new(move || { ResultSource::summary_from_bounded_queue(cont.clone()) }),
props: props
};
let source = Rc::new(source);
ResultSource::Object(source)
}
pub fn summary_from_bounded_queue<SI, SM, SO, T>(cont: ResultContainer<queue::stats::Queue<SI, SM, SO, T>>) -> ResultSource
where SI: QueueStrategy + 'static,
SM: QueueStrategy + 'static,
SO: QueueStrategy + 'static,
T: Clone + 'static
{
let props = vec![
cont.clone().const_prop("capacity",
ResultId::QueueMaxCount,
move |x| { x.max_count() }),
cont.clone().prop("queue_count_stats",
ResultId::QueueCountStats,
move |x| { queue::stats::Queue::<SI, SM, SO, T>::count_stats(x) },
move |x| { queue::stats::Queue::<SI, SM, SO, T>::count_changed_(&x) }),
cont.clone().prop("enqueue_count",
ResultId::EnqueueCount,
move |x| { queue::stats::Queue::<SI, SM, SO, T>::enqueue_count(x) },
move |x| { queue::stats::Queue::<SI, SM, SO, T>::enqueue_count_changed_(&x) }),
cont.clone().prop("enqueue_lost_count",
ResultId::EnqueueLostCount,
move |x| { queue::stats::Queue::<SI, SM, SO, T>::enqueue_lost_count(x) },
move |x| { queue::stats::Queue::<SI, SM, SO, T>::enqueue_lost_count_changed_(&x) }),
cont.clone().prop("enqueue_store_count",
ResultId::EnqueueStoreCount,
move |x| { queue::stats::Queue::<SI, SM, SO, T>::enqueue_store_count(x) },
move |x| { queue::stats::Queue::<SI, SM, SO, T>::enqueue_store_count_changed_(&x) }),
cont.clone().prop("dequeue_count",
ResultId::DequeueCount,
move |x| { queue::stats::Queue::<SI, SM, SO, T>::dequeue_count(x) },
move |x| { queue::stats::Queue::<SI, SM, SO, T>::dequeue_count_changed_(&x) }),
cont.clone().prop("dequeue_extract_count",
ResultId::DequeueExtractCount,
move |x| { queue::stats::Queue::<SI, SM, SO, T>::dequeue_extract_count(x) },
move |x| { queue::stats::Queue::<SI, SM, SO, T>::dequeue_extract_count_changed_(&x) }),
cont.clone().prop("queue_load_factor",
ResultId::QueueLoadFactor,
move |x| { queue::stats::Queue::<SI, SM, SO, T>::load_factor(x) },
move |x| { queue::stats::Queue::<SI, SM, SO, T>::load_factor_changed_(&x) }),
cont.clone().prop("queue_wait_time",
ResultId::QueueWaitTime,
move |x| { queue::stats::Queue::<SI, SM, SO, T>::wait_time(x) },
move |x| { queue::stats::Queue::<SI, SM, SO, T>::wait_time_changed_(&x) }),
cont.clone().prop("queue_rate",
ResultId::QueueRate,
move |x| { queue::stats::Queue::<SI, SM, SO, T>::rate(x) },
move |x| { queue::stats::Queue::<SI, SM, SO, T>::rate_changed_(&x) })
];
let source = ResultObject {
name: cont.name.clone(),
id: cont.id.clone(),
type_id: ResultId::Queue,
observable: cont.observable.clone(),
summary: Rc::new(move || { ResultSource::summary_from_bounded_queue(cont.clone()) }),
props: props
};
let source = Rc::new(source);
ResultSource::Object(source)
}
pub fn from_unbounded_queue<SM, SO, T>(cont: ResultContainer<queue::unbounded::stats::Queue<SM, SO, T>>) -> ResultSource
where SM: QueueStrategy + 'static,
SO: QueueStrategy + 'static,
T: Clone + 'static
{
let props = vec![
cont.clone().prop("queue_empty",
ResultId::QueueEmpty,
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::is_empty(x) },
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::is_empty_changed_(&x) }),
cont.clone().prop("queue_count",
ResultId::QueueCount,
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::count(x) },
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::count_changed_(&x) }),
cont.clone().prop("queue_count_stats",
ResultId::QueueCountStats,
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::count_stats(x) },
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::count_changed_(&x) }),
cont.clone().prop("enqueue_store_count",
ResultId::EnqueueStoreCount,
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::enqueue_store_count(x) },
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::enqueue_store_count_changed_(&x) }),
cont.clone().prop("dequeue_count",
ResultId::DequeueCount,
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::dequeue_count(x) },
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::dequeue_count_changed_(&x) }),
cont.clone().prop("dequeue_extract_count",
ResultId::DequeueExtractCount,
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::dequeue_extract_count(x) },
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::dequeue_extract_count_changed_(&x) }),
cont.clone().integ_prop("enqueue_store_rate",
ResultId::EnqueueStoreRate,
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::store_rate(x) }),
cont.clone().integ_prop("dequeue_rate",
ResultId::DequeueRate,
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::dequeue_rate(x) }),
cont.clone().integ_prop("dequeue_extract_rate",
ResultId::DequeueExtractRate,
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::dequeue_extract_rate(x) }),
cont.clone().prop("queue_wait_time",
ResultId::QueueWaitTime,
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::wait_time(x) },
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::wait_time_changed_(&x) }),
cont.clone().prop("dequeue_wait_time",
ResultId::DequeueWaitTime,
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::dequeue_wait_time(x) },
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::dequeue_wait_time_changed_(&x) }),
cont.clone().prop("queue_rate",
ResultId::QueueRate,
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::rate(x) },
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::rate_changed_(&x) })
];
let source = ResultObject {
name: cont.name.clone(),
id: cont.id.clone(),
type_id: ResultId::Queue,
observable: cont.observable.clone(),
summary: Rc::new(move || { ResultSource::summary_from_unbounded_queue(cont.clone()) }),
props: props
};
let source = Rc::new(source);
ResultSource::Object(source)
}
pub fn summary_from_unbounded_queue<SM, SO, T>(cont: ResultContainer<queue::unbounded::stats::Queue<SM, SO, T>>) -> ResultSource
where SM: QueueStrategy + 'static,
SO: QueueStrategy + 'static,
T: Clone + 'static
{
let props = vec![
cont.clone().prop("queue_count_stats",
ResultId::QueueCountStats,
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::count_stats(x) },
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::count_changed_(&x) }),
cont.clone().prop("enqueue_store_count",
ResultId::EnqueueStoreCount,
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::enqueue_store_count(x) },
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::enqueue_store_count_changed_(&x) }),
cont.clone().prop("dequeue_count",
ResultId::DequeueCount,
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::dequeue_count(x) },
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::dequeue_count_changed_(&x) }),
cont.clone().prop("dequeue_extract_count",
ResultId::DequeueExtractCount,
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::dequeue_extract_count(x) },
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::dequeue_extract_count_changed_(&x) }),
cont.clone().prop("queue_wait_time",
ResultId::QueueWaitTime,
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::wait_time(x) },
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::wait_time_changed_(&x) }),
cont.clone().prop("queue_rate",
ResultId::QueueRate,
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::rate(x) },
move |x| { queue::unbounded::stats::Queue::<SM, SO, T>::rate_changed_(&x) })
];
let source = ResultObject {
name: cont.name.clone(),
id: cont.id.clone(),
type_id: ResultId::Queue,
observable: cont.observable.clone(),
summary: Rc::new(move || { ResultSource::summary_from_unbounded_queue(cont.clone()) }),
props: props
};
let source = Rc::new(source);
ResultSource::Object(source)
}
pub fn from_text(text: String) -> ResultSource {
let source = ResultSeparator { text: text };
let source = Rc::new(source);
ResultSource::Separator(source)
}
pub fn time() -> ResultSource {
let source = EventFn::new(move || { time_event() });
let name = String::from("t");
let name_path = vec![name.clone()];
let id = ResultId::Time;
let id_path = vec![id.clone()];
source.get_source_by_id(name, name_path, id, id_path)
}
}
pub trait ResultItem {
fn get_name(&self) -> ResultName;
fn get_name_path(&self) -> Vec<ResultName>;
fn get_id(&self) -> ResultId;
fn get_id_path(&self) -> Vec<ResultId>;
fn observable(&self) -> ResultObservable;
fn expand(&self) -> ResultSource;
fn summary(&self) -> ResultSource;
fn as_int_val(&self) -> Option<ResultValue<isize>>;
fn as_int_vec_val(&self) -> Option<ResultValue<Vec<isize>>>;
fn as_int_stats_val(&self) -> Option<ResultValue<SamplingStats<isize>>>;
fn as_int_timing_stats_val(&self) -> Option<ResultValue<TimingStats<isize>>>;
fn as_floating_val(&self) -> Option<ResultValue<f64>>;
fn as_floating_vec_val(&self) -> Option<ResultValue<Vec<f64>>>;
fn as_floating_stats_val(&self) -> Option<ResultValue<SamplingStats<f64>>>;
fn as_floating_timing_stats_val(&self) -> Option<ResultValue<TimingStats<f64>>>;
fn as_string_val(&self) -> Option<ResultValue<String>>;
fn get_int_val(&self) -> Result<ResultValue<isize>> {
match self.as_int_val() {
Some(x) => result::Result::Ok(x),
None => {
let err = format!("Cannot represent {} as a source of integer numbers", self.get_name());
result::Result::Err(err)
}
}
}
fn get_int_vec_val(&self) -> Result<ResultValue<Vec<isize>>> {
match self.as_int_vec_val() {
Some(x) => result::Result::Ok(x),
None => {
let err = format!("Cannot represent {} as a source of vectors of integer numbers", self.get_name());
result::Result::Err(err)
}
}
}
fn get_int_stats_val(&self) -> Result<ResultValue<SamplingStats<isize>>> {
match self.as_int_stats_val() {
Some(x) => result::Result::Ok(x),
None => {
let err = format!("Cannot represent {} as a source of statistics based on integer numbers", self.get_name());
result::Result::Err(err)
}
}
}
fn get_int_timing_stats_val(&self) -> Result<ResultValue<TimingStats<isize>>> {
match self.as_int_timing_stats_val() {
Some(x) => result::Result::Ok(x),
None => {
let err = format!("Cannot represent {} as a source of the time-persistent statistics based on integer numbers", self.get_name());
result::Result::Err(err)
}
}
}
fn get_floating_val(&self) -> Result<ResultValue<f64>> {
match self.as_floating_val() {
Some(x) => result::Result::Ok(x),
None => {
let err = format!("Cannot represent {} as a source of double floating point numbers", self.get_name());
result::Result::Err(err)
}
}
}
fn get_floating_vec_val(&self) -> Result<ResultValue<Vec<f64>>> {
match self.as_floating_vec_val() {
Some(x) => result::Result::Ok(x),
None => {
let err = format!("Cannot represent {} as a source of vectors of double floating point numbers", self.get_name());
result::Result::Err(err)
}
}
}
fn get_floating_stats_val(&self) -> Result<ResultValue<SamplingStats<f64>>> {
match self.as_floating_stats_val() {
Some(x) => result::Result::Ok(x),
None => {
let err = format!("Cannot represent {} as a source of statistics based on double floating point numbers", self.get_name());
result::Result::Err(err)
}
}
}
fn get_floating_timing_stats_val(&self) -> Result<ResultValue<TimingStats<f64>>> {
match self.as_floating_timing_stats_val() {
Some(x) => result::Result::Ok(x),
None => {
let err = format!("Cannot represent {} as a source of the time-persistent statistics based on double floating point numbers", self.get_name());
result::Result::Err(err)
}
}
}
fn get_string_val(&self) -> Result<ResultValue<String>> {
match self.as_string_val() {
Some(x) => result::Result::Ok(x),
None => {
let err = format!("Cannot represent {} as a source of String values", self.get_name());
result::Result::Err(err)
}
}
}
}
pub struct ResultObject {
pub name: ResultName,
pub id: ResultId,
pub type_id: ResultId,
pub props: Vec<ResultProperty>,
pub observable: Rc<dyn Fn() -> ResultObservable>,
pub summary: Rc<dyn Fn() -> ResultSource>
}
pub struct ResultProperty {
pub label: ResultName,
pub id: ResultId,
pub source: ResultSource
}
pub struct ResultVec {
pub name: ResultName,
pub id: ResultId,
pub items: Vec<ResultSource>,
pub subscript: Vec<ResultName>,
pub observable: Rc<dyn Fn() -> ResultObservable>,
pub summary: Rc<dyn Fn() -> ResultSource>
}
impl ResultVec {
pub fn observable(items: &[ResultSource]) -> ResultObservable {
items
.iter()
.fold(ResultObservable::empty(), move |acc, item| {
acc.merge(item.observable())
})
}
pub fn summary(vec: Rc<ResultVec>) -> ResultSource {
let items = {
vec.items
.iter()
.map(|x| { x.summary() })
.collect::<Vec<ResultSource>>()
};
ResultVec::with_items(vec, items)
}
fn with_items(vec: Rc<ResultVec>, items: Vec<ResultSource>) -> ResultSource {
let name = vec.name.clone();
let id = vec.id.clone();
let subscript = vec.subscript.clone();
let observable = {
let items = items.clone();
Rc::new(move || { ResultVec::observable(&items) })
};
let summary = {
let items = items.clone();
Rc::new(move || {
ResultVec::with_items(vec.clone(), items.clone())
})
};
let vec = ResultVec { name, id, items, subscript, observable, summary };
let vec = Rc::new(vec);
ResultSource::Vec(vec)
}
}
#[derive(Clone)]
pub struct ResultSeparator {
pub text: String
}
#[derive(Clone)]
pub struct ResultValue<E> {
pub name: ResultName,
pub name_path: Vec<ResultName>,
pub id: ResultId,
pub id_path: Vec<ResultId>,
pub data: Rc<dyn Fn() -> ResultData<E>>,
pub observable: Rc<dyn Fn() -> ResultObservable>
}
impl<E> ResultValue<E> {
pub fn map<F, B>(self, f: F) -> ResultValue<B>
where F: FnOnce(E) -> B + Clone + 'static,
B: 'static,
E: 'static
{
let ResultValue { name, name_path, id, id_path, data, observable } = self;
let data = {
Rc::new(move || {
data().map(f.clone()).into_boxed()
})
};
ResultValue {
name: name,
name_path: name_path,
id: id,
id_path: id_path,
data: data,
observable: observable
}
}
pub fn and_then<F, B>(self, f: F) -> ResultValue<B>
where F: FnOnce(ResultData<E>) -> ResultData<B> + Clone + 'static,
B: 'static,
E: 'static
{
let ResultValue { name, name_path, id, id_path, data, observable } = self;
let data = {
Rc::new(move || {
(f.clone())(data())
})
};
ResultValue {
name: name,
name_path: name_path,
id: id,
id_path: id_path,
data: data,
observable: observable
}
}
pub fn into_container(self) -> ResultContainer<ResultData<E>> {
let ResultValue { name, name_path, id, id_path, data, observable } = self;
let data = Grc::new(data());
ResultContainer { name, name_path, id, id_path, data, observable }
}
pub fn raw_prop_source<F, B>(self, prop_name: &str, prop_id: ResultId, prop_data: F) -> ResultSource
where F: FnOnce(ResultData<E>) -> ResultData<B> + Clone + 'static,
ResultValue<B>: ResultItem,
B: 'static,
E: 'static
{
let ResultValue { name, name_path, id: _, id_path, data, observable } = self;
let item = ResultValue {
name: name + "." + prop_name,
name_path: {
let mut name_path = name_path;
name_path.push(prop_name.to_string());
name_path
},
id: prop_id.clone(),
id_path: {
let mut id_path = id_path;
id_path.push(prop_id);
id_path
},
data: {
let data = data.clone();
Rc::new(move || { (prop_data.clone())(data()) })
},
observable: observable
};
ResultSource::Item(Rc::new(item))
}
pub fn raw_prop<F, B>(self, prop_name: &str, prop_id: ResultId, prop_data: F) -> ResultProperty
where F: FnOnce(ResultData<E>) -> ResultData<B> + Clone + 'static,
ResultValue<B>: ResultItem,
B: 'static,
E: 'static
{
let label = prop_name.to_string();
let id = prop_id.clone();
let source = self.raw_prop_source(prop_name, prop_id, prop_data);
ResultProperty {
label: label,
id: id,
source: source
}
}
pub fn map_prop<F, B>(self, prop_name: &str, prop_id: ResultId, prop_data: F) -> ResultProperty
where F: FnOnce(E) -> B + Clone + 'static,
ResultValue<B>: ResultItem,
B: 'static,
E: 'static
{
self.raw_prop(prop_name, prop_id,
move |comp| { comp.map(prop_data).into_boxed() })
}
}
pub struct ResultContainer<E> where E: 'static {
pub name: ResultName,
pub name_path: Vec<ResultName>,
pub id: ResultId,
pub id_path: Vec<ResultId>,
pub data: Grc<E>,
pub observable: Rc<dyn Fn() -> ResultObservable>
}
impl<E> ResultContainer<E> {
pub fn map<F, B>(val: Rc<Self>, f: F) -> ResultContainer<B>
where F: FnOnce(&E) -> B
{
let data = Grc::new(f(&val.data));
ResultContainer {
name: val.name.clone(),
name_path: val.name_path.clone(),
id: val.id.clone(),
id_path: val.id_path.clone(),
data: data,
observable: val.observable.clone()
}
}
pub fn raw_prop_source<F1, F2, B>(self, prop_name: &str, prop_id: ResultId, prop_data: F1, prop_observable: F2) -> ResultSource
where F1: FnOnce(Grc<E>) -> ResultData<B> + Clone + 'static,
F2: FnOnce(Grc<E>) -> ResultObservable + Clone + 'static,
ResultValue<B>: ResultItem,
B: 'static,
E: 'static
{
let ResultContainer { name, name_path, id: _, id_path, data, observable: _ } = self;
let item = ResultValue {
name: name + "." + prop_name,
name_path: {
let mut name_path = name_path;
name_path.push(prop_name.to_string());
name_path
},
id: prop_id.clone(),
id_path: {
let mut id_path = id_path;
id_path.push(prop_id);
id_path
},
data: {
let data = data.clone();
Rc::new(move || { (prop_data.clone())(data.clone()) })
},
observable: {
Rc::new(move || { (prop_observable.clone())(data.clone()) })
}
};
ResultSource::Item(Rc::new(item))
}
pub fn raw_prop<F1, F2, B>(self, prop_name: &str, prop_id: ResultId, prop_data: F1, prop_observable: F2) -> ResultProperty
where F1: FnOnce(Grc<E>) -> ResultData<B> + Clone + 'static,
F2: FnOnce(Grc<E>) -> ResultObservable + Clone + 'static,
ResultValue<B>: ResultItem,
B: 'static,
E: 'static
{
let label = prop_name.to_string();
let id = prop_id.clone();
let source = self.raw_prop_source(prop_name, prop_id, prop_data, prop_observable);
ResultProperty {
label: label,
id: id,
source: source
}
}
pub fn const_prop<F, B>(self, prop_name: &str, prop_id: ResultId, prop_data: F) -> ResultProperty
where F: FnOnce(Grc<E>) -> B + Clone + 'static,
ResultValue<B>: ResultItem,
B: 'static,
E: 'static
{
self.raw_prop(prop_name, prop_id,
move |e| { return_event(prop_data(e)).into_boxed() },
move |_| { ResultObservable::Empty })
}
pub fn integ_prop<F, M, B>(self, prop_name: &str, prop_id: ResultId, prop_data: F) -> ResultProperty
where F: FnOnce(Grc<E>) -> M + Clone + 'static,
M: Event<Item = B> + 'static,
ResultValue<B>: ResultItem,
B: 'static,
E: 'static
{
self.raw_prop(prop_name, prop_id,
move |e| { prop_data(e).into_boxed() },
move |_| { ResultObservable::Unknown })
}
pub fn prop<F1, F2, M, O, B>(self, prop_name: &str, prop_id: ResultId, prop_data: F1, prop_observable: F2) -> ResultProperty
where F1: FnOnce(Grc<E>) -> M + Clone + 'static,
F2: FnOnce(Grc<E>) -> O + Clone + 'static,
M: Event<Item = B> + 'static,
O: Observable<Message = ()> + 'static,
ResultValue<B>: ResultItem,
B: 'static,
E: 'static
{
self.raw_prop(prop_name, prop_id,
move |e| { prop_data(e).into_boxed() },
move |e| { ResultObservable::Observable(prop_observable(e).into_boxed()) })
}
}
impl<E> Clone for ResultContainer<E> {
fn clone(&self) -> Self {
ResultContainer {
name: self.name.clone(),
name_path: self.name_path.clone(),
id: self.id.clone(),
id_path: self.id_path.clone(),
data: self.data.clone(),
observable: self.observable.clone()
}
}
}
pub type ResultData<E> = EventBox<E>;
fn norm_timing_stats_data<A>(data: ResultData<TimingStats<A>>) -> ResultData<SamplingStats<A>>
where A: StatData + Copy + PartialOrd + 'static
{
data.and_then(move |x| {
cons_event(move |p| {
let n = p.iteration;
let y = x.norm(n);
result::Result::Ok(y)
})
}).into_boxed()
}
pub enum ResultObservable {
Empty,
Unknown,
Observable(ObservableBox<()>),
ObservableMix(ObservableBox<()>)
}
impl ResultObservable {
pub fn from_option(observable: Option<ObservableBox<()>>) -> Self {
match observable {
Some(x) => ResultObservable::Observable(x),
None => ResultObservable::Empty
}
}
pub fn empty() -> Self {
ResultObservable::Empty
}
pub fn merge(self, other: Self) -> Self {
match (self, other) {
(ResultObservable::Empty, z) => z,
(ResultObservable::Unknown, ResultObservable::Empty) => ResultObservable::Unknown,
(ResultObservable::Unknown, ResultObservable::Unknown) => ResultObservable::Unknown,
(ResultObservable::Unknown, ResultObservable::Observable(x)) => ResultObservable::ObservableMix(x),
(ResultObservable::Unknown, z@ResultObservable::ObservableMix(_)) => z,
(z@ResultObservable::Observable(_), ResultObservable::Empty) => z,
(ResultObservable::Observable(x), ResultObservable::Unknown) => ResultObservable::ObservableMix(x),
(ResultObservable::Observable(x), ResultObservable::Observable(y)) => ResultObservable::Observable(x.merge(y).into_boxed()),
(ResultObservable::Observable(x), ResultObservable::ObservableMix(y)) => ResultObservable::ObservableMix(x.merge(y).into_boxed()),
(z@ResultObservable::ObservableMix(_), ResultObservable::Empty) => z,
(z@ResultObservable::ObservableMix(_), ResultObservable::Unknown) => z,
(ResultObservable::ObservableMix(x), ResultObservable::Observable(y)) => ResultObservable::ObservableMix(x.merge(y).into_boxed()),
(ResultObservable::ObservableMix(x), ResultObservable::ObservableMix(y)) => ResultObservable::ObservableMix(x.merge(y).into_boxed()),
}
}
pub fn pure(self, predefined: &ResultPredefinedObservableSet) -> ObservableBox<()> {
match self {
ResultObservable::Empty => {
predefined.in_start_time().map(|_| ())
.into_boxed()
},
ResultObservable::Unknown => {
predefined.in_integ_times().map(|_| ())
.into_boxed()
},
ResultObservable::Observable(x) => {
predefined.in_start_time().map(|_| ())
.merge(predefined.in_stop_time().map(|_| ()))
.merge(x)
.into_boxed()
},
ResultObservable::ObservableMix(x) => {
predefined.in_integ_times().map(|_| ())
.merge(x)
.into_boxed()
}
}
}
}
impl ResultItem for ResultValue<isize> {
fn get_name(&self) -> ResultName {
self.name.clone()
}
fn get_name_path(&self) -> Vec<ResultName> {
self.name_path.clone()
}
fn get_id(&self) -> ResultId {
self.id.clone()
}
fn get_id_path(&self) -> Vec<ResultId> {
self.id_path.clone()
}
fn observable(&self) -> ResultObservable {
(self.observable)()
}
fn expand(&self) -> ResultSource {
ResultSource::Item(Rc::new(self.clone()))
}
fn summary(&self) -> ResultSource {
ResultSource::Item(Rc::new(self.clone()))
}
fn as_int_val(&self) -> Option<ResultValue<isize>> {
Some(self.clone())
}
fn as_int_vec_val(&self) -> Option<ResultValue<Vec<isize>>> {
Some(self.clone().map(move |x| { vec![x] }))
}
fn as_int_stats_val(&self) -> Option<ResultValue<SamplingStats<isize>>> {
Some(self.clone().map(move |x| { SamplingStats::from_sample(x) }))
}
fn as_int_timing_stats_val(&self) -> Option<ResultValue<TimingStats<isize>>> {
None
}
fn as_floating_val(&self) -> Option<ResultValue<f64>> {
Some(self.clone().map(move |x| { x as f64 }))
}
fn as_floating_vec_val(&self) -> Option<ResultValue<Vec<f64>>> {
Some(self.clone().map(move |x| { vec![x as f64] }))
}
fn as_floating_stats_val(&self) -> Option<ResultValue<SamplingStats<f64>>> {
Some(self.clone().map(move |x| { SamplingStats::from_sample(x as f64) }))
}
fn as_floating_timing_stats_val(&self) -> Option<ResultValue<TimingStats<f64>>> {
None
}
fn as_string_val(&self) -> Option<ResultValue<String>> {
Some(self.clone().map(move |x| { format!("{}", x) }))
}
}
impl ResultItem for ResultValue<f64> {
fn get_name(&self) -> ResultName {
self.name.clone()
}
fn get_name_path(&self) -> Vec<ResultName> {
self.name_path.clone()
}
fn get_id(&self) -> ResultId {
self.id.clone()
}
fn get_id_path(&self) -> Vec<ResultId> {
self.id_path.clone()
}
fn observable(&self) -> ResultObservable {
(self.observable)()
}
fn expand(&self) -> ResultSource {
ResultSource::Item(Rc::new(self.clone()))
}
fn summary(&self) -> ResultSource {
ResultSource::Item(Rc::new(self.clone()))
}
fn as_int_val(&self) -> Option<ResultValue<isize>> {
None
}
fn as_int_vec_val(&self) -> Option<ResultValue<Vec<isize>>> {
None
}
fn as_int_stats_val(&self) -> Option<ResultValue<SamplingStats<isize>>> {
None
}
fn as_int_timing_stats_val(&self) -> Option<ResultValue<TimingStats<isize>>> {
None
}
fn as_floating_val(&self) -> Option<ResultValue<f64>> {
Some(self.clone())
}
fn as_floating_vec_val(&self) -> Option<ResultValue<Vec<f64>>> {
Some(self.clone().map(move |x| { vec![x] }))
}
fn as_floating_stats_val(&self) -> Option<ResultValue<SamplingStats<f64>>> {
Some(self.clone().map(move |x| { SamplingStats::from_sample(x) }))
}
fn as_floating_timing_stats_val(&self) -> Option<ResultValue<TimingStats<f64>>> {
None
}
fn as_string_val(&self) -> Option<ResultValue<String>> {
Some(self.clone().map(move |x| { format!("{}", x) }))
}
}
impl ResultItem for ResultValue<Vec<isize>> {
fn get_name(&self) -> ResultName {
self.name.clone()
}
fn get_name_path(&self) -> Vec<ResultName> {
self.name_path.clone()
}
fn get_id(&self) -> ResultId {
self.id.clone()
}
fn get_id_path(&self) -> Vec<ResultId> {
self.id_path.clone()
}
fn observable(&self) -> ResultObservable {
(self.observable)()
}
fn expand(&self) -> ResultSource {
ResultSource::Item(Rc::new(self.clone()))
}
fn summary(&self) -> ResultSource {
ResultSource::Item(Rc::new(self.clone()))
}
fn as_int_val(&self) -> Option<ResultValue<isize>> {
None
}
fn as_int_vec_val(&self) -> Option<ResultValue<Vec<isize>>> {
Some(self.clone())
}
fn as_int_stats_val(&self) -> Option<ResultValue<SamplingStats<isize>>> {
Some(self.clone().map(move |x| { SamplingStats::from_samples(x.iter()) }))
}
fn as_int_timing_stats_val(&self) -> Option<ResultValue<TimingStats<isize>>> {
None
}
fn as_floating_val(&self) -> Option<ResultValue<f64>> {
None
}
fn as_floating_vec_val(&self) -> Option<ResultValue<Vec<f64>>> {
Some(self.clone().map(move |x| { x.iter().map(|y| { *y as f64 }).collect() }))
}
fn as_floating_stats_val(&self) -> Option<ResultValue<SamplingStats<f64>>> {
Some(self.clone().map(move |x| { SamplingStats::from_samples(x.iter().map(|y| { *y as f64 })) }))
}
fn as_floating_timing_stats_val(&self) -> Option<ResultValue<TimingStats<f64>>> {
None
}
fn as_string_val(&self) -> Option<ResultValue<String>> {
Some(self.clone().map(move |x| { format!("{:?}", x) }))
}
}
impl ResultItem for ResultValue<Vec<f64>> {
fn get_name(&self) -> ResultName {
self.name.clone()
}
fn get_name_path(&self) -> Vec<ResultName> {
self.name_path.clone()
}
fn get_id(&self) -> ResultId {
self.id.clone()
}
fn get_id_path(&self) -> Vec<ResultId> {
self.id_path.clone()
}
fn observable(&self) -> ResultObservable {
(self.observable)()
}
fn expand(&self) -> ResultSource {
ResultSource::Item(Rc::new(self.clone()))
}
fn summary(&self) -> ResultSource {
ResultSource::Item(Rc::new(self.clone()))
}
fn as_int_val(&self) -> Option<ResultValue<isize>> {
None
}
fn as_int_vec_val(&self) -> Option<ResultValue<Vec<isize>>> {
None
}
fn as_int_stats_val(&self) -> Option<ResultValue<SamplingStats<isize>>> {
None
}
fn as_int_timing_stats_val(&self) -> Option<ResultValue<TimingStats<isize>>> {
None
}
fn as_floating_val(&self) -> Option<ResultValue<f64>> {
None
}
fn as_floating_vec_val(&self) -> Option<ResultValue<Vec<f64>>> {
Some(self.clone())
}
fn as_floating_stats_val(&self) -> Option<ResultValue<SamplingStats<f64>>> {
Some(self.clone().map(move |x| { SamplingStats::from_samples(x.iter()) }))
}
fn as_floating_timing_stats_val(&self) -> Option<ResultValue<TimingStats<f64>>> {
None
}
fn as_string_val(&self) -> Option<ResultValue<String>> {
Some(self.clone().map(move |x| { format!("{:?}", x) }))
}
}
impl ResultItem for ResultValue<SamplingStats<isize>> {
fn get_name(&self) -> ResultName {
self.name.clone()
}
fn get_name_path(&self) -> Vec<ResultName> {
self.name_path.clone()
}
fn get_id(&self) -> ResultId {
self.id.clone()
}
fn get_id_path(&self) -> Vec<ResultId> {
self.id_path.clone()
}
fn observable(&self) -> ResultObservable {
(self.observable)()
}
fn expand(&self) -> ResultSource {
ResultSource::from_stats(self.clone())
}
fn summary(&self) -> ResultSource {
ResultSource::summary_from_stats(self.clone())
}
fn as_int_val(&self) -> Option<ResultValue<isize>> {
None
}
fn as_int_vec_val(&self) -> Option<ResultValue<Vec<isize>>> {
None
}
fn as_int_stats_val(&self) -> Option<ResultValue<SamplingStats<isize>>> {
Some(self.clone())
}
fn as_int_timing_stats_val(&self) -> Option<ResultValue<TimingStats<isize>>> {
None
}
fn as_floating_val(&self) -> Option<ResultValue<f64>> {
None
}
fn as_floating_vec_val(&self) -> Option<ResultValue<Vec<f64>>> {
None
}
fn as_floating_stats_val(&self) -> Option<ResultValue<SamplingStats<f64>>> {
Some(self.clone().map(move |x| { x.into() }))
}
fn as_floating_timing_stats_val(&self) -> Option<ResultValue<TimingStats<f64>>> {
None
}
fn as_string_val(&self) -> Option<ResultValue<String>> {
Some(self.clone().map(move |x| { format!("{}", x) }))
}
}
impl ResultItem for ResultValue<SamplingStats<f64>> {
fn get_name(&self) -> ResultName {
self.name.clone()
}
fn get_name_path(&self) -> Vec<ResultName> {
self.name_path.clone()
}
fn get_id(&self) -> ResultId {
self.id.clone()
}
fn get_id_path(&self) -> Vec<ResultId> {
self.id_path.clone()
}
fn observable(&self) -> ResultObservable {
(self.observable)()
}
fn expand(&self) -> ResultSource {
ResultSource::from_stats(self.clone())
}
fn summary(&self) -> ResultSource {
ResultSource::summary_from_stats(self.clone())
}
fn as_int_val(&self) -> Option<ResultValue<isize>> {
None
}
fn as_int_vec_val(&self) -> Option<ResultValue<Vec<isize>>> {
None
}
fn as_int_stats_val(&self) -> Option<ResultValue<SamplingStats<isize>>> {
None
}
fn as_int_timing_stats_val(&self) -> Option<ResultValue<TimingStats<isize>>> {
None
}
fn as_floating_val(&self) -> Option<ResultValue<f64>> {
None
}
fn as_floating_vec_val(&self) -> Option<ResultValue<Vec<f64>>> {
None
}
fn as_floating_stats_val(&self) -> Option<ResultValue<SamplingStats<f64>>> {
Some(self.clone())
}
fn as_floating_timing_stats_val(&self) -> Option<ResultValue<TimingStats<f64>>> {
None
}
fn as_string_val(&self) -> Option<ResultValue<String>> {
Some(self.clone().map(move |x| { format!("{}", x) }))
}
}
impl ResultItem for ResultValue<TimingStats<isize>> {
fn get_name(&self) -> ResultName {
self.name.clone()
}
fn get_name_path(&self) -> Vec<ResultName> {
self.name_path.clone()
}
fn get_id(&self) -> ResultId {
self.id.clone()
}
fn get_id_path(&self) -> Vec<ResultId> {
self.id_path.clone()
}
fn observable(&self) -> ResultObservable {
(self.observable)()
}
fn expand(&self) -> ResultSource {
ResultSource::from_timing_stats(self.clone())
}
fn summary(&self) -> ResultSource {
ResultSource::summary_from_timing_stats(self.clone())
}
fn as_int_val(&self) -> Option<ResultValue<isize>> {
None
}
fn as_int_vec_val(&self) -> Option<ResultValue<Vec<isize>>> {
None
}
fn as_int_stats_val(&self) -> Option<ResultValue<SamplingStats<isize>>> {
Some(self.clone().and_then(norm_timing_stats_data))
}
fn as_int_timing_stats_val(&self) -> Option<ResultValue<TimingStats<isize>>> {
Some(self.clone())
}
fn as_floating_val(&self) -> Option<ResultValue<f64>> {
None
}
fn as_floating_vec_val(&self) -> Option<ResultValue<Vec<f64>>> {
None
}
fn as_floating_stats_val(&self) -> Option<ResultValue<SamplingStats<f64>>> {
Some(self.clone().map(move |x| { x.into() }).and_then(norm_timing_stats_data))
}
fn as_floating_timing_stats_val(&self) -> Option<ResultValue<TimingStats<f64>>> {
Some(self.clone().map(move |x| { x.into() }))
}
fn as_string_val(&self) -> Option<ResultValue<String>> {
Some(self.clone().map(move |x| { format!("{}", x) }))
}
}
impl ResultItem for ResultValue<TimingStats<f64>> {
fn get_name(&self) -> ResultName {
self.name.clone()
}
fn get_name_path(&self) -> Vec<ResultName> {
self.name_path.clone()
}
fn get_id(&self) -> ResultId {
self.id.clone()
}
fn get_id_path(&self) -> Vec<ResultId> {
self.id_path.clone()
}
fn observable(&self) -> ResultObservable {
(self.observable)()
}
fn expand(&self) -> ResultSource {
ResultSource::from_timing_stats(self.clone())
}
fn summary(&self) -> ResultSource {
ResultSource::summary_from_timing_stats(self.clone())
}
fn as_int_val(&self) -> Option<ResultValue<isize>> {
None
}
fn as_int_vec_val(&self) -> Option<ResultValue<Vec<isize>>> {
None
}
fn as_int_stats_val(&self) -> Option<ResultValue<SamplingStats<isize>>> {
None
}
fn as_int_timing_stats_val(&self) -> Option<ResultValue<TimingStats<isize>>> {
None
}
fn as_floating_val(&self) -> Option<ResultValue<f64>> {
None
}
fn as_floating_vec_val(&self) -> Option<ResultValue<Vec<f64>>> {
None
}
fn as_floating_stats_val(&self) -> Option<ResultValue<SamplingStats<f64>>> {
Some(self.clone().and_then(norm_timing_stats_data))
}
fn as_floating_timing_stats_val(&self) -> Option<ResultValue<TimingStats<f64>>> {
Some(self.clone())
}
fn as_string_val(&self) -> Option<ResultValue<String>> {
Some(self.clone().map(move |x| { format!("{}", x) }))
}
}
impl ResultItem for ResultValue<bool> {
fn get_name(&self) -> ResultName {
self.name.clone()
}
fn get_name_path(&self) -> Vec<ResultName> {
self.name_path.clone()
}
fn get_id(&self) -> ResultId {
self.id.clone()
}
fn get_id_path(&self) -> Vec<ResultId> {
self.id_path.clone()
}
fn observable(&self) -> ResultObservable {
(self.observable)()
}
fn expand(&self) -> ResultSource {
ResultSource::Item(Rc::new(self.clone()))
}
fn summary(&self) -> ResultSource {
ResultSource::Item(Rc::new(self.clone()))
}
fn as_int_val(&self) -> Option<ResultValue<isize>> {
None
}
fn as_int_vec_val(&self) -> Option<ResultValue<Vec<isize>>> {
None
}
fn as_int_stats_val(&self) -> Option<ResultValue<SamplingStats<isize>>> {
None
}
fn as_int_timing_stats_val(&self) -> Option<ResultValue<TimingStats<isize>>> {
None
}
fn as_floating_val(&self) -> Option<ResultValue<f64>> {
None
}
fn as_floating_vec_val(&self) -> Option<ResultValue<Vec<f64>>> {
None
}
fn as_floating_stats_val(&self) -> Option<ResultValue<SamplingStats<f64>>> {
None
}
fn as_floating_timing_stats_val(&self) -> Option<ResultValue<TimingStats<f64>>> {
None
}
fn as_string_val(&self) -> Option<ResultValue<String>> {
Some(self.clone().map(move |x| { format!("{}", x) }))
}
}
impl ResultItem for ResultValue<String> {
fn get_name(&self) -> ResultName {
self.name.clone()
}
fn get_name_path(&self) -> Vec<ResultName> {
self.name_path.clone()
}
fn get_id(&self) -> ResultId {
self.id.clone()
}
fn get_id_path(&self) -> Vec<ResultId> {
self.id_path.clone()
}
fn observable(&self) -> ResultObservable {
(self.observable)()
}
fn expand(&self) -> ResultSource {
ResultSource::Item(Rc::new(self.clone()))
}
fn summary(&self) -> ResultSource {
ResultSource::Item(Rc::new(self.clone()))
}
fn as_int_val(&self) -> Option<ResultValue<isize>> {
None
}
fn as_int_vec_val(&self) -> Option<ResultValue<Vec<isize>>> {
None
}
fn as_int_stats_val(&self) -> Option<ResultValue<SamplingStats<isize>>> {
None
}
fn as_int_timing_stats_val(&self) -> Option<ResultValue<TimingStats<isize>>> {
None
}
fn as_floating_val(&self) -> Option<ResultValue<f64>> {
None
}
fn as_floating_vec_val(&self) -> Option<ResultValue<Vec<f64>>> {
None
}
fn as_floating_stats_val(&self) -> Option<ResultValue<SamplingStats<f64>>> {
None
}
fn as_floating_timing_stats_val(&self) -> Option<ResultValue<TimingStats<f64>>> {
None
}
fn as_string_val(&self) -> Option<ResultValue<String>> {
Some(self.clone())
}
}
#[derive(Clone)]
pub struct ResultPredefinedObservableSet {
source_in_integ_times: Grc<ObservableSource<f64>>,
source_in_start_time: Grc<ObservableSource<f64>>,
source_in_stop_time: Grc<ObservableSource<f64>>
}
impl ResultPredefinedObservableSet {
pub fn new() -> NewResultPredefinedObservableSet {
NewResultPredefinedObservableSet {}
}
pub fn in_integ_times(&self) -> ObservableBox<f64> {
self.source_in_integ_times.publish().into_boxed()
}
pub fn in_start_time(&self) -> ObservableBox<f64> {
self.source_in_start_time.publish().into_boxed()
}
pub fn in_stop_time(&self) -> ObservableBox<f64> {
self.source_in_stop_time.publish().into_boxed()
}
}
#[must_use = "computations are lazy and do nothing unless to be run"]
#[derive(Clone)]
pub struct NewResultPredefinedObservableSet {}
impl Simulation for NewResultPredefinedObservableSet {
type Item = ResultPredefinedObservableSet;
#[doc(hidden)]
fn call_simulation(self, r: &Run) -> simulation::Result<Self::Item> {
cons_event(move |p| {
let source_in_integ_times = new_observable_source_in_integ_times().call_event(p)?;
let source_in_start_time = new_observable_source_in_start_time().call_event(p)?;
let source_in_stop_time = new_observable_source_in_stop_time().call_event(p)?;
result::Result::Ok(ResultPredefinedObservableSet {
source_in_integ_times: source_in_integ_times,
source_in_start_time: source_in_start_time,
source_in_stop_time: source_in_stop_time
})
}).run_in_start_time_by(false)
.call_simulation(r)
}
}
pub struct ResultSet {
map: ResultSourceMap,
vec: Vec<ResultSource>
}
impl Into<ResultSet> for Vec<ResultSource> {
fn into(self) -> ResultSet {
let mut map = OrdMap::empty();
for source in self.iter() {
map = map.insert(source.get_name(), source.clone());
}
ResultSet {
map: map,
vec: self
}
}
}
impl Clone for ResultSet {
fn clone(&self) -> Self {
let sources: Vec<ResultSource> = self.vec.iter().map(|x| x.clone()).collect();
sources.into()
}
}
impl ResultSet {
pub fn empty() -> Self {
let sources: Vec<ResultSource> = vec![];
sources.into()
}
pub fn merge(&self, other: &Self) -> Self {
let mut sources = self.vec.clone();
let mut sources2 = other.vec.clone();
sources.append(&mut sources2);
sources.into()
}
pub fn summary(&self) -> Self {
let sources: Vec<ResultSource> = self.vec.iter().map(|x| x.summary()).collect();
sources.into()
}
pub fn expand(&self) -> Self {
let sources: Vec<ResultSource> = self.vec.iter().map(|x| x.expand()).collect();
sources.into()
}
pub fn observable(&self) -> ResultObservable {
self.vec
.iter()
.map(|x| x.observable())
.fold(ResultObservable::Empty, |x, y| x.merge(y))
}
pub fn get_sources(&self) -> impl Iterator<Item = &ResultSource> {
self.vec.iter()
}
pub fn get_int_vals(&self) -> Result<Vec<ResultValue<isize>>> {
let mut ys = Vec::new();
for x in self.vec.iter() {
let mut zs = x.get_int_vals()?;
ys.append(&mut zs);
}
result::Result::Ok(ys)
}
pub fn get_int_vec_vals(&self) -> Result<Vec<ResultValue<Vec<isize>>>> {
let mut ys = Vec::new();
for x in self.vec.iter() {
let mut zs = x.get_int_vec_vals()?;
ys.append(&mut zs);
}
result::Result::Ok(ys)
}
pub fn get_int_stats_vals(&self) -> Result<Vec<ResultValue<SamplingStats<isize>>>> {
let mut ys = Vec::new();
for x in self.vec.iter() {
let mut zs = x.get_int_stats_vals()?;
ys.append(&mut zs);
}
result::Result::Ok(ys)
}
pub fn get_int_timing_stats_vals(&self) -> Result<Vec<ResultValue<TimingStats<isize>>>> {
let mut ys = Vec::new();
for x in self.vec.iter() {
let mut zs = x.get_int_timing_stats_vals()?;
ys.append(&mut zs);
}
result::Result::Ok(ys)
}
pub fn get_floating_vals(&self) -> Result<Vec<ResultValue<f64>>> {
let mut ys = Vec::new();
for x in self.vec.iter() {
let mut zs = x.get_floating_vals()?;
ys.append(&mut zs);
}
result::Result::Ok(ys)
}
pub fn get_floating_vec_vals(&self) -> Result<Vec<ResultValue<Vec<f64>>>> {
let mut ys = Vec::new();
for x in self.vec.iter() {
let mut zs = x.get_floating_vec_vals()?;
ys.append(&mut zs);
}
result::Result::Ok(ys)
}
pub fn get_floating_stats_vals(&self) -> Result<Vec<ResultValue<SamplingStats<f64>>>> {
let mut ys = Vec::new();
for x in self.vec.iter() {
let mut zs = x.get_floating_stats_vals()?;
ys.append(&mut zs);
}
result::Result::Ok(ys)
}
pub fn get_floating_timing_stats_vals(&self) -> Result<Vec<ResultValue<TimingStats<f64>>>> {
let mut ys = Vec::new();
for x in self.vec.iter() {
let mut zs = x.get_floating_timing_stats_vals()?;
ys.append(&mut zs);
}
result::Result::Ok(ys)
}
pub fn get_string_vals(&self) -> Result<Vec<ResultValue<String>>> {
let mut ys = Vec::new();
for x in self.vec.iter() {
let mut zs = x.get_string_vals()?;
ys.append(&mut zs);
}
result::Result::Ok(ys)
}
}
pub struct ResultTransform {
f: Rc<dyn Fn(&ResultSet) -> Result<ResultSet>>
}
impl Clone for ResultTransform {
fn clone(&self) -> Self {
ResultTransform {
f: self.f.clone()
}
}
}
impl ResultTransform {
pub fn new<F>(f: F) -> ResultTransform
where F: Fn(&ResultSet) -> Result<ResultSet> + 'static
{
ResultTransform {
f: Rc::new(f)
}
}
pub fn call(&self, results: &ResultSet) -> Result<ResultSet> {
(self.f)(results)
}
pub fn empty() -> Self {
ResultTransform::new(|x| result::Result::Ok(x.clone()))
}
pub fn merge(&self, other: &Self) -> Self {
let f = self.f.clone();
let f2 = other.f.clone();
ResultTransform::new(move |x| {
let ys1 = f(x)?;
let ys2 = f2(x)?;
result::Result::Ok(ys1.merge(&ys2))
})
}
pub fn and_then(&self, other: &Self) -> Self {
let f = self.f.clone();
let f2 = other.f.clone();
ResultTransform::new(move |x| {
let ys1 = f(x)?;
f2(&ys1)
})
}
pub fn summary() -> Self {
ResultTransform::new(|x| result::Result::Ok(x.summary()))
}
pub fn expand() -> Self {
ResultTransform::new(|x| result::Result::Ok(x.expand()))
}
pub fn by_name(name: String) -> Self {
ResultTransform::new(move |x| {
match x.map.get(&name) {
Some(ref source) => {
let source: &ResultSource = source;
let sources: Vec<ResultSource> = vec![source.clone()];
result::Result::Ok(sources.into())
},
None => {
let err = format!("Not found result source with name {}", name);
result::Result::Err(err)
}
}
})
}
pub fn by_id(id: ResultId) -> Self {
ResultTransform::new(move |x| {
fn process_source(result: &mut Vec<ResultSource>, source: &ResultSource, id: &ResultId) -> Result<()> {
match &source {
ResultSource::Item(ref s) if s.get_id() == *id => {
result.push(source.clone())
},
ResultSource::Item(_) => {
let err = format!("Expected to find item with id = {:?}", *id);
return result::Result::Err(err);
},
ResultSource::Object(ref s) if s.id == *id => {
result.push(source.clone())
},
ResultSource::Object(ref s) => {
let ps = s.props.iter().find(|p| { p.id == *id });
match ps {
Some(ref p) => result.push(p.source.clone()),
None => {
let err = format!("Not found property with id = {:?}", *id);
return result::Result::Err(err);
}
}
},
ResultSource::Vec(ref s) if s.id == *id => {
result.push(source.clone())
},
ResultSource::Vec(ref s) => {
for item in s.items.iter() {
process_source(result, item, id)?;
}
},
ResultSource::Separator(_) => {
let err = format!("Expected to find either item, or object, or vector with id = {:?}", id);
return result::Result::Err(err);
}
}
result::Result::Ok(())
}
let mut ys: Vec<ResultSource> = Vec::new();
for source in x.vec.iter() {
process_source(&mut ys, source, &id)?;
}
result::Result::Ok(ys.into())
})
}
}
impl<T> ResultProvider for ParameterFn<T>
where T: 'static,
ResultValue<T>: ResultItem
{
fn get_source_by_id(self, name: ResultName, name_path: Vec<ResultName>, id: ResultId, id_path: Vec<ResultId>) -> ResultSource {
let item = ResultValue {
name: name,
name_path: name_path,
id: id,
id_path: id_path,
data: {
Rc::new(move || {
self.next().into_event().into_boxed()
})
},
observable: {
Rc::new(move || ResultObservable::Unknown)
}
};
ResultSource::Item(Rc::new(item))
}
}
impl<T> ResultProvider for SimulationFn<T>
where T: 'static,
ResultValue<T>: ResultItem
{
fn get_source_by_id(self, name: ResultName, name_path: Vec<ResultName>, id: ResultId, id_path: Vec<ResultId>) -> ResultSource {
let item = ResultValue {
name: name,
name_path: name_path,
id: id,
id_path: id_path,
data: {
Rc::new(move || {
self.next().into_event().into_boxed()
})
},
observable: {
Rc::new(move || ResultObservable::Unknown)
}
};
ResultSource::Item(Rc::new(item))
}
}
impl<T> ResultProvider for EventFn<T>
where T: 'static,
ResultValue<T>: ResultItem
{
fn get_source_by_id(self, name: ResultName, name_path: Vec<ResultName>, id: ResultId, id_path: Vec<ResultId>) -> ResultSource {
let item = ResultValue {
name: name,
name_path: name_path,
id: id,
id_path: id_path,
data: {
Rc::new(move || {
self.next().into_boxed()
})
},
observable: {
Rc::new(move || ResultObservable::Unknown)
}
};
ResultSource::Item(Rc::new(item))
}
}
impl<T> ResultProvider for Grc<RefComp<T>>
where T: Clone + 'static,
ResultValue<T>: ResultItem
{
fn get_source_by_id(self, name: ResultName, name_path: Vec<ResultName>, id: ResultId, id_path: Vec<ResultId>) -> ResultSource {
let item = ResultValue {
name: name,
name_path: name_path,
id: id,
id_path: id_path,
data: {
Rc::new(move || {
RefComp::read(self.clone()).into_boxed()
})
},
observable: {
Rc::new(move || ResultObservable::Unknown)
}
};
ResultSource::Item(Rc::new(item))
}
}
impl<T> ResultProvider for Vec<T>
where T: ResultProvider
{
fn get_source_by_id(self, name: ResultName, name_path: Vec<ResultName>, id: ResultId, id_path: Vec<ResultId>) -> ResultSource {
let len = self.len();
let items: Vec<ResultSource> = {
let name = name.clone();
self.into_iter()
.enumerate()
.map(move |(i, x)| {
let idx = format!("[{}]", i);
let name = name.clone() + &idx;
let name_path = {
let mut name_path = name_path.clone();
name_path.push(idx);
name_path
};
let id = ResultId::VectorItem(i);
let id_path = {
let mut id_path = id_path.clone();
id_path.push(id.clone());
id_path
};
x.get_source_by_id(name, name_path, id, id_path)
})
.collect()
};
let subscript: Vec<ResultName> = {
(0 .. len)
.map(|i| format!("[{}]", i))
.collect()
};
let memo: Rc<RefCell<Option<Rc<ResultVec>>>> = Rc::new(RefCell::new(None));
let item = ResultVec {
name: name,
id: id,
items: items.clone(),
subscript: subscript,
observable: {
Rc::new(move || {
ResultVec::observable(&items)
})
},
summary: {
let memo = memo.clone();
Rc::new(move || {
let vec = {
let cell = memo.borrow();
match *cell {
Some(ref x) => x.clone(),
None => panic!("Invalid memo cell")
}
};
ResultVec::summary(vec)
})
}
};
let item = Rc::new(item);
{
let mut cell = memo.borrow_mut();
*cell = Some(item.clone());
}
ResultSource::Vec(item)
}
}
impl ResultProvider for Grc<Queue> {
fn get_source_by_id(self, name: ResultName, name_path: Vec<ResultName>, id: ResultId, id_path: Vec<ResultId>) -> ResultSource {
let cont = ResultContainer {
name: name,
name_path: name_path,
id: id,
id_path: id_path,
data: self.clone(),
observable: {
Rc::new(move || ResultObservable::Observable(self.changed_().into_boxed()))
}
};
ResultSource::from_queue(cont)
}
}
impl<T> ResultProvider for Grc<Facility<T>>
where T: 'static
{
fn get_source_by_id(self, name: ResultName, name_path: Vec<ResultName>, id: ResultId, id_path: Vec<ResultId>) -> ResultSource {
let cont = ResultContainer {
name: name,
name_path: name_path,
id: id,
id_path: id_path,
data: self.clone(),
observable: {
Rc::new(move || ResultObservable::Observable(self.changed_().into_boxed()))
}
};
ResultSource::from_facility(cont)
}
}
impl<T> ResultProvider for Grc<Storage<T>>
where T: 'static
{
fn get_source_by_id(self, name: ResultName, name_path: Vec<ResultName>, id: ResultId, id_path: Vec<ResultId>) -> ResultSource {
let cont = ResultContainer {
name: name,
name_path: name_path,
id: id,
id_path: id_path,
data: self.clone(),
observable: {
Rc::new(move || ResultObservable::Observable(self.changed_().into_boxed()))
}
};
ResultSource::from_storage(cont)
}
}
impl<SI, SM, SO, T> ResultProvider for Grc<queue::stats::Queue<SI, SM, SO, T>>
where SI: QueueStrategy + 'static,
SM: QueueStrategy + 'static,
SO: QueueStrategy + 'static,
T: Clone + 'static
{
fn get_source_by_id(self, name: ResultName, name_path: Vec<ResultName>, id: ResultId, id_path: Vec<ResultId>) -> ResultSource {
let cont = ResultContainer {
name: name,
name_path: name_path,
id: id,
id_path: id_path,
data: self.clone(),
observable: {
Rc::new(move || ResultObservable::Observable(self.changed_().into_boxed()))
}
};
ResultSource::from_bounded_queue(cont)
}
}
impl<SM, SO, T> ResultProvider for Grc<queue::unbounded::stats::Queue<SM, SO, T>>
where SM: QueueStrategy + 'static,
SO: QueueStrategy + 'static,
T: Clone + 'static
{
fn get_source_by_id(self, name: ResultName, name_path: Vec<ResultName>, id: ResultId, id_path: Vec<ResultId>) -> ResultSource {
let cont = ResultContainer {
name: name,
name_path: name_path,
id: id,
id_path: id_path,
data: self.clone(),
observable: {
Rc::new(move || ResultObservable::Observable(self.changed_().into_boxed()))
}
};
ResultSource::from_unbounded_queue(cont)
}
}