Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 132 additions & 0 deletions integration-tests/ixa-runner-tests/tests/macros.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#[cfg(test)]
mod tests {
use std::cell::RefCell;
use std::hash::{Hash, Hasher};
use std::rc::Rc;

use ixa::prelude::*;
use ixa::HashSet;
Expand All @@ -11,6 +13,21 @@ mod tests {
// Test entity property / derived / multi-property macros
define_property!(struct TestPropU32(u32), Person);
define_property!(struct TestPropU32b(u32), Person);
define_property!(struct MacroAge(u8), Person, default_const = MacroAge(0));
define_property!(
struct MacroHighRisk(bool),
Person,
default_const = MacroHighRisk(false)
);
define_property!(
enum MacroInfectionStatus {
Susceptible,
Infected,
Recovered,
},
Person,
default_const = MacroInfectionStatus::Susceptible
);
define_property!(
struct TestPropDefault(u32),
Person,
Expand Down Expand Up @@ -138,6 +155,12 @@ mod tests {
// Test rng macro
define_rng!(TestRngId);

fn as_context(context: &mut Context) -> &mut Context {
context
}

fn macro_named_value_change_handler<C>(_context: &mut Context, _counter: &mut C) {}

#[test]
fn compile_and_run_macros() {
let mut ctx = Context::new();
Expand Down Expand Up @@ -238,4 +261,113 @@ mod tests {
let b = 1.0f64 + 1e-12;
ixa::assert_almost_eq!(a, b, 1e-10);
}

#[test]
fn track_periodic_value_change_counts_macro_forms() {
let mut ctx = Context::new();

let omitted_strata = Rc::new(RefCell::new(Vec::<usize>::new()));
let empty_strata = Rc::new(RefCell::new(Vec::<usize>::new()));
let singleton_strata = Rc::new(RefCell::new(Vec::<usize>::new()));
let multiple_strata = Rc::new(RefCell::new(Vec::<usize>::new()));

let omitted_strata_clone = omitted_strata.clone();
track_periodic_value_change_counts!(
as_context(&mut ctx),
Person,
MacroInfectionStatus,
0.5 + 0.5,
move |_context, counter| {
omitted_strata_clone
.borrow_mut()
.push(counter.get_count((), MacroInfectionStatus::Infected));
},
);

let empty_strata_clone = empty_strata.clone();
track_periodic_value_change_counts!(
ctx,
Person,
MacroInfectionStatus,
[],
1.0,
move |_context, counter| {
empty_strata_clone
.borrow_mut()
.push(counter.get_count((), MacroInfectionStatus::Infected));
},
);

let singleton_strata_clone = singleton_strata.clone();
track_periodic_value_change_counts!(
ctx,
Person,
MacroInfectionStatus,
[MacroAge],
1.0,
move |_context, counter| {
singleton_strata_clone
.borrow_mut()
.push(counter.get_count((MacroAge(10),), MacroInfectionStatus::Infected));
},
);

let multiple_strata_clone = multiple_strata.clone();
track_periodic_value_change_counts!(
ctx,
Person,
MacroInfectionStatus,
[MacroAge, MacroHighRisk],
1.0,
move |_context, counter| {
multiple_strata_clone.borrow_mut().push(counter.get_count(
(MacroAge(10), MacroHighRisk(true)),
MacroInfectionStatus::Infected,
));
},
);

track_periodic_value_change_counts!(
ctx,
Person,
MacroInfectionStatus,
[],
1.0,
|_context, counter| {
let _ = counter.get_count((), MacroInfectionStatus::Infected);
},
);

track_periodic_value_change_counts!(
ctx,
Person,
MacroInfectionStatus,
[MacroAge],
1.0,
macro_named_value_change_handler,
);

let person = ctx
.add_entity(with!(
Person,
TestPropU32(1),
TestPropU32b(2),
MacroAge(10),
MacroHighRisk(true),
MacroInfectionStatus::Susceptible,
))
.unwrap();

ctx.add_plan(0.5, move |context| {
context.set_property(person, MacroInfectionStatus::Infected);
});
ctx.add_plan(1.1, Context::shutdown);

ctx.execute();

assert_eq!(*omitted_strata.borrow(), vec![0, 1]);
assert_eq!(*empty_strata.borrow(), vec![0, 1]);
assert_eq!(*singleton_strata.borrow(), vec![0, 1]);
assert_eq!(*multiple_strata.borrow(), vec![0, 1]);
}
}
1 change: 1 addition & 0 deletions src/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ mod define_rng;
mod edge_impl;
mod entity_impl;
mod property_impl;
mod value_change_counts;
mod with;
47 changes: 47 additions & 0 deletions src/macros/value_change_counts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/// Tracks periodic value change counts with concise entity, property, and strata syntax.
///
/// The strata list is optional. Omitting it, or passing `[]`, uses the empty
/// property list `()`.
///
/// ```ignore
/// track_periodic_value_change_counts!(
/// context,
/// Person,
/// InfectionStatus,
/// 1.0,
/// handle_incidence_tracking
/// );
///
/// track_periodic_value_change_counts!(
/// context,
/// Person,
/// InfectionStatus,
/// [Age],
/// 1.0,
/// move |_context, counter| {
/// let _ = counter;
/// }
/// );
///
/// track_periodic_value_change_counts!(
/// context,
/// Person,
/// InfectionStatus,
/// [Age, HighRisk],
/// 1.0,
/// handle_incidence_tracking
/// );
/// ```
#[macro_export]
macro_rules! track_periodic_value_change_counts {
($context:expr, $entity:ty, $property:ty, [$($stratum:ty),* $(,)?], $period:expr, $handler:expr $(,)?) => {
($context).track_periodic_value_change_counts::<$entity, ($($stratum,)*), $property, _>(
$period,
$handler,
)
};

($context:expr, $entity:ty, $property:ty, $period:expr, $handler:expr $(,)?) => {
track_periodic_value_change_counts!($context, $entity, $property, [], $period, $handler)
};
}
3 changes: 2 additions & 1 deletion src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ pub use crate::report::ContextReportExt;
pub use crate::{
define_data_plugin, define_derived_property, define_edge_type, define_entity,
define_global_property, define_multi_property, define_property, define_report, define_rng,
impl_edge_type, impl_entity, impl_property, with, PluginContext,
impl_edge_type, impl_entity, impl_property, track_periodic_value_change_counts, with,
PluginContext,
};