pub struct Context { /* private fields */ }
Expand description
A manager for the state of a discrete-event simulation
Provides core simulation services including
- Maintaining a notion of time
- Scheduling events to occur at some point in the future and executing them at that time
- Holding data that can be accessed by simulation modules
Simulations are constructed out of a series of interacting modules that
take turns manipulating the Context through a mutable reference. Modules
store data in the simulation using the DataPlugin
trait that allows them
to retrieve data by type.
The future event list of the simulation is a queue of Callback
objects -
called plans
- that will assume control of the Context at a future point
in time and execute the logic in the associated FnOnce(&mut Context)
closure. Modules can add plans to this queue through the Context
.
The simulation also has a separate callback mechanism. Callbacks fire before the next timed event (even if it is scheduled for the current time). This allows modules to schedule actions for immediate execution but outside of the current iteration of the event loop.
Modules can also emit ‘events’ that other modules can subscribe to handle by event type. This allows modules to broadcast that specific things have occurred and have other modules take turns reacting to these occurrences.
Implementations§
Source§impl Context
impl Context
Sourcepub fn schedule_debugger(
&mut self,
time: f64,
priority: Option<ExecutionPhase>,
callback: Box<dyn FnOnce(&mut Context)>,
)
pub fn schedule_debugger( &mut self, time: f64, priority: Option<ExecutionPhase>, callback: Box<dyn FnOnce(&mut Context)>, )
Schedule the simulation to pause at time t and start the debugger. This will give you a REPL which allows you to inspect the state of the simulation (type help to see a list of commands)
§Errors
Internal debugger errors e.g., reading or writing to stdin/stdout; errors in Ixa are printed to stdout
Sourcepub fn subscribe_to_event<E: IxaEvent + Copy + 'static>(
&mut self,
handler: impl Fn(&mut Context, E) + 'static,
)
pub fn subscribe_to_event<E: IxaEvent + Copy + 'static>( &mut self, handler: impl Fn(&mut Context, E) + 'static, )
Register to handle emission of events of type E
Handlers will be called upon event emission in order of subscription as
queued Callback
s with the appropriate event.
Sourcepub fn emit_event<E: IxaEvent + Copy + 'static>(&mut self, event: E)
pub fn emit_event<E: IxaEvent + Copy + 'static>(&mut self, event: E)
Emit and event of type E to be handled by registered receivers
Receivers will handle events in the order that they have subscribed and are queued as callbacks
Sourcepub fn add_plan(
&mut self,
time: f64,
callback: impl FnOnce(&mut Context) + 'static,
) -> PlanId
pub fn add_plan( &mut self, time: f64, callback: impl FnOnce(&mut Context) + 'static, ) -> PlanId
Add a plan to the future event list at the specified time in the normal phase
Returns a PlanId
for the newly-added plan that can be used to cancel it
if needed.
§Panics
Panics if time is in the past, infinite, or NaN.
Sourcepub fn add_plan_with_phase(
&mut self,
time: f64,
callback: impl FnOnce(&mut Context) + 'static,
phase: ExecutionPhase,
) -> PlanId
pub fn add_plan_with_phase( &mut self, time: f64, callback: impl FnOnce(&mut Context) + 'static, phase: ExecutionPhase, ) -> PlanId
Add a plan to the future event list at the specified time and with the specified phase (first, normal, or last among plans at the specified time)
Returns a PlanId
for the newly-added plan that can be used to cancel it
if needed.
§Panics
Panics if time is in the past, infinite, or NaN.
Sourcepub fn add_periodic_plan_with_phase(
&mut self,
period: f64,
callback: impl Fn(&mut Context) + 'static,
phase: ExecutionPhase,
)
pub fn add_periodic_plan_with_phase( &mut self, period: f64, callback: impl Fn(&mut Context) + 'static, phase: ExecutionPhase, )
Add a plan with specified priority to the future event list, and continuously repeat the plan at the specified period, stopping only once there are no other plans scheduled.
§Panics
Panics if plan period is negative, infinite, or NaN.
Sourcepub fn cancel_plan(&mut self, plan_id: &PlanId)
pub fn cancel_plan(&mut self, plan_id: &PlanId)
Cancel a plan that has been added to the queue
§Panics
This function panics if you cancel a plan which has already been cancelled or executed.
Sourcepub fn queue_callback(&mut self, callback: impl FnOnce(&mut Context) + 'static)
pub fn queue_callback(&mut self, callback: impl FnOnce(&mut Context) + 'static)
Add a Callback
to the queue to be executed before the next plan
Sourcepub fn get_data_container_mut<T: DataPlugin>(
&mut self,
_data_plugin: T,
) -> &mut T::DataContainer
pub fn get_data_container_mut<T: DataPlugin>( &mut self, _data_plugin: T, ) -> &mut T::DataContainer
Retrieve a mutable reference to the data container associated with a
DataPlugin
If the data container has not been already added to the Context
then
this function will use the DataPlugin::create_data_container
method
to construct a new data container and store it in the Context
.
Returns a mutable reference to the data container
Sourcepub fn get_data_container<T: DataPlugin>(
&self,
_data_plugin: T,
) -> Option<&T::DataContainer>
pub fn get_data_container<T: DataPlugin>( &self, _data_plugin: T, ) -> Option<&T::DataContainer>
Retrieve a reference to the data container associated with a
DataPlugin
Returns a reference to the data container if it exists or else None
Sourcepub fn shutdown(&mut self)
pub fn shutdown(&mut self)
Shutdown the simulation cleanly, abandoning all events after whatever is currently executing.
Sourcepub fn get_current_time(&self) -> f64
pub fn get_current_time(&self) -> f64
Get the current time in the simulation
Returns the current time
Sourcepub fn request_debugger(&mut self)
pub fn request_debugger(&mut self)
Request to enter a debugger session at next event loop
Sourcepub fn cancel_debugger_request(&mut self)
pub fn cancel_debugger_request(&mut self)
Request to enter a debugger session at next event loop
Sourcepub fn disable_breakpoints(&mut self)
pub fn disable_breakpoints(&mut self)
Disable breakpoints
Sourcepub fn enable_breakpoints(&mut self)
pub fn enable_breakpoints(&mut self)
Enable breakpoints
Sourcepub fn breakpoints_are_enabled(&self) -> bool
pub fn breakpoints_are_enabled(&self) -> bool
Returns true
if breakpoints are enabled.
Sourcepub fn delete_breakpoint(
&mut self,
breakpoint_id: u64,
) -> Option<Box<dyn FnOnce(&mut Context)>>
pub fn delete_breakpoint( &mut self, breakpoint_id: u64, ) -> Option<Box<dyn FnOnce(&mut Context)>>
Delete the breakpoint with the given ID
Sourcepub fn list_breakpoints(
&self,
at_most: usize,
) -> Vec<&PlanSchedule<ExecutionPhase>>
pub fn list_breakpoints( &self, at_most: usize, ) -> Vec<&PlanSchedule<ExecutionPhase>>
Returns a list of length at_most
, or unbounded if at_most=0
, of active scheduled
PlanSchedule
s ordered as they are in the queue itself.
Sourcepub fn clear_breakpoints(&mut self)
pub fn clear_breakpoints(&mut self)
Deletes all breakpoints.
Sourcepub fn execute_single_step(&mut self)
pub fn execute_single_step(&mut self)
Executes a single step of the simulation, prioritizing tasks as follows:
- Breakpoints
- Callbacks
- Plans
- Shutdown
Trait Implementations§
Source§impl ContextGlobalPropertiesExt for Context
impl ContextGlobalPropertiesExt for Context
Source§fn set_global_property_value<T: GlobalProperty + 'static>(
&mut self,
property: T,
value: T::Value,
) -> Result<(), IxaError>
fn set_global_property_value<T: GlobalProperty + 'static>( &mut self, property: T, value: T::Value, ) -> Result<(), IxaError>
Source§fn get_global_property_value<T: GlobalProperty + 'static>(
&self,
_property: T,
) -> Option<&T::Value>
fn get_global_property_value<T: GlobalProperty + 'static>( &self, _property: T, ) -> Option<&T::Value>
fn list_registered_global_properties(&self) -> Vec<String>
Source§fn get_serialized_value_by_string(
&self,
name: &str,
) -> Result<Option<String>, IxaError>
fn get_serialized_value_by_string( &self, name: &str, ) -> Result<Option<String>, IxaError>
Source§fn load_parameters_from_json<T: 'static + Debug + DeserializeOwned>(
&mut self,
file_name: &Path,
) -> Result<T, IxaError>
fn load_parameters_from_json<T: 'static + Debug + DeserializeOwned>( &mut self, file_name: &Path, ) -> Result<T, IxaError>
Source§impl ContextNetworkExt for Context
impl ContextNetworkExt for Context
Source§fn add_edge<T: EdgeType + 'static>(
&mut self,
person: PersonId,
neighbor: PersonId,
weight: f32,
inner: T::Value,
) -> Result<(), IxaError>
fn add_edge<T: EdgeType + 'static>( &mut self, person: PersonId, neighbor: PersonId, weight: f32, inner: T::Value, ) -> Result<(), IxaError>
T
between person
and neighbor
with a
given weight
. inner
is a value of whatever type is
associated with T
. Read moreSource§fn add_edge_bidi<T: EdgeType + 'static>(
&mut self,
person1: PersonId,
person2: PersonId,
weight: f32,
inner: T::Value,
) -> Result<(), IxaError>
fn add_edge_bidi<T: EdgeType + 'static>( &mut self, person1: PersonId, person2: PersonId, weight: f32, inner: T::Value, ) -> Result<(), IxaError>
T
between person1
and
neighbor2
with a given weight
, one edge in each
direction. inner
is a value of whatever type is associated
with T
. This is syntactic sugar for calling add_edge()
twice. Read moreSource§fn remove_edge<T: EdgeType + 'static>(
&mut self,
person: PersonId,
neighbor: PersonId,
) -> Result<(), IxaError>
fn remove_edge<T: EdgeType + 'static>( &mut self, person: PersonId, neighbor: PersonId, ) -> Result<(), IxaError>
Source§fn get_edge<T: EdgeType + 'static>(
&self,
person: PersonId,
neighbor: PersonId,
) -> Option<&Edge<T::Value>>
fn get_edge<T: EdgeType + 'static>( &self, person: PersonId, neighbor: PersonId, ) -> Option<&Edge<T::Value>>
T
between person
and neighbor
if one exists.Source§fn get_edges<T: EdgeType + 'static>(
&self,
person: PersonId,
) -> Vec<Edge<T::Value>>
fn get_edges<T: EdgeType + 'static>( &self, person: PersonId, ) -> Vec<Edge<T::Value>>
T
from person
.Source§fn get_matching_edges<T: EdgeType + 'static>(
&self,
person: PersonId,
filter: impl Fn(&Context, &Edge<T::Value>) -> bool + 'static,
) -> Vec<Edge<T::Value>>
fn get_matching_edges<T: EdgeType + 'static>( &self, person: PersonId, filter: impl Fn(&Context, &Edge<T::Value>) -> bool + 'static, ) -> Vec<Edge<T::Value>>
T
from person
that match the predicate
provided in filter
. Note that because filter
has access to
both the edge, which contains the neighbor and Context
, it is
possible to filter on properties of the neighbor. The function
context.matching_person()
might be helpful here.Source§impl ContextPeopleExt for Context
impl ContextPeopleExt for Context
Source§fn get_current_population(&self) -> usize
fn get_current_population(&self) -> usize
Source§fn add_person<T: InitializationList>(
&mut self,
props: T,
) -> Result<PersonId, IxaError>
fn add_person<T: InitializationList>( &mut self, props: T, ) -> Result<PersonId, IxaError>
InitializationList
it is best to take advantage of the provided
syntax that implements InitializationList
for tuples, such as:
let person = context.add_person((Age, 42)).unwrap();
Read moreSource§fn get_person_property<T: PersonProperty + 'static>(
&self,
person_id: PersonId,
property: T,
) -> T::Value
fn get_person_property<T: PersonProperty + 'static>( &self, person_id: PersonId, property: T, ) -> T::Value
PersonId
returns the value of a defined person property,
initializing it if it hasn’t been set yet. If no initializer is
provided, and the property is not set this will panic, as long
as the property has been set or subscribed to at least once before.
Otherwise, Ixa doesn’t know about the property.Source§fn set_person_property<T: PersonProperty + 'static>(
&mut self,
person_id: PersonId,
property: T,
value: T::Value,
)
fn set_person_property<T: PersonProperty + 'static>( &mut self, person_id: PersonId, property: T, value: T::Value, )
PersonId
, sets the value of a defined person property
Panics if the property is not initialized. Fires a change event.Source§fn index_property<T: PersonProperty + 'static>(&mut self, _property: T)
fn index_property<T: PersonProperty + 'static>(&mut self, _property: T)
T
. Read moreSource§fn query_people<T: Query>(&self, q: T) -> Vec<PersonId>
fn query_people<T: Query>(&self, q: T) -> Vec<PersonId>
Source§fn query_people_count<T: Query>(&self, q: T) -> usize
fn query_people_count<T: Query>(&self, q: T) -> usize
Source§fn match_person<T: Query>(&self, person_id: PersonId, q: T) -> bool
fn match_person<T: Query>(&self, person_id: PersonId, q: T) -> bool
fn tabulate_person_properties<T: Tabulator, F>( &self, tabulator: &T, print_fn: F, )
Source§impl ContextRandomExt for Context
impl ContextRandomExt for Context
Source§fn init_random(&mut self, base_seed: u64)
fn init_random(&mut self, base_seed: u64)
Initializes the RngPlugin
data container to store rngs as well as a base
seed. Note that rngs are created lazily when get_rng
is called.
Source§fn sample<R: RngId + 'static, T>(
&self,
_rng_id: R,
sampler: impl FnOnce(&mut R::RngType) -> T,
) -> T
fn sample<R: RngId + 'static, T>( &self, _rng_id: R, sampler: impl FnOnce(&mut R::RngType) -> T, ) -> T
RngId
by applying the specified sampler function. If the Rng has not been used
before, one will be created with the base seed you defined in set_base_random_seed
.
Note that this will panic if set_base_random_seed
was not called yet.Source§fn sample_distr<R: RngId + 'static, T>(
&self,
_rng_id: R,
distribution: impl Distribution<T>,
) -> T
fn sample_distr<R: RngId + 'static, T>( &self, _rng_id: R, distribution: impl Distribution<T>, ) -> T
RngId
. If the Rng has not been used before, one will be
created with the base seed you defined in set_base_random_seed
.
Note that this will panic if set_base_random_seed
was not called yet.Source§fn sample_range<R: RngId + 'static, S, T>(&self, rng_id: R, range: S) -> T
fn sample_range<R: RngId + 'static, S, T>(&self, rng_id: R, range: S) -> T
range
using the generator associated with the given RngId
.
Note that this will panic if set_base_random_seed
was not called yet.Source§fn sample_bool<R: RngId + 'static>(&self, rng_id: R, p: f64) -> bool
fn sample_bool<R: RngId + 'static>(&self, rng_id: R, p: f64) -> bool
p
using the generator associated with the given RngId
.
Note that this will panic if set_base_random_seed
was not called yet.Source§impl ContextReportExt for Context
impl ContextReportExt for Context
Source§fn send_report<T: Report>(&self, report: T)
fn send_report<T: Report>(&self, report: T)
Write a new row to the appropriate report file
Source§fn report_options(&mut self) -> &mut ConfigReportOptions
fn report_options(&mut self) -> &mut ConfigReportOptions
Returns a ConfigReportOptions
object which has setter methods for report configuration
Source§fn add_report_by_type_id(
&mut self,
type_id: TypeId,
short_name: &str,
) -> Result<(), IxaError>
fn add_report_by_type_id( &mut self, type_id: TypeId, short_name: &str, ) -> Result<(), IxaError>
TypeId
.
The short_name
is used for file naming to distinguish what data each
output file points to. Read moreSource§fn add_report<T: Report + 'static>(
&mut self,
short_name: &str,
) -> Result<(), IxaError>
fn add_report<T: Report + 'static>( &mut self, short_name: &str, ) -> Result<(), IxaError>
add_report
with each report type, passing the name of the report type.
The short_name
is used for file naming to distinguish what data each
output file points to. Read moreSource§fn add_periodic_report<T: Tabulator + Clone + 'static>(
&mut self,
short_name: &str,
period: f64,
tabulator: T,
) -> Result<(), IxaError>
fn add_periodic_report<T: Tabulator + Clone + 'static>( &mut self, short_name: &str, period: f64, tabulator: T, ) -> Result<(), IxaError>
period
which summarizes the
number of people in each combination of properties in tabulator
. Read morefn get_writer(&self, type_id: TypeId) -> RefMut<'_, Writer<File>>
Source§impl ContextWebApiExt for Context
impl ContextWebApiExt for Context
Source§fn add_web_api_handler(
&mut self,
name: &str,
handler: impl Fn(&mut Context, Value) -> Result<Value, IxaError> + 'static,
) -> Result<(), IxaError>
fn add_web_api_handler( &mut self, name: &str, handler: impl Fn(&mut Context, Value) -> Result<Value, IxaError> + 'static, ) -> Result<(), IxaError>
Add an API point.