ixa::context

Struct Context

Source
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

Source

pub fn new() -> Context

Create a new empty Context

Source

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

Source

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 Callbacks with the appropriate event.

Source

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

Source

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.

Source

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.

Source

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.

Source

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.

Source

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

Source

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

Source

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

Source

pub fn shutdown(&mut self)

Shutdown the simulation cleanly, abandoning all events after whatever is currently executing.

Source

pub fn get_current_time(&self) -> f64

Get the current time in the simulation

Returns the current time

Source

pub fn request_debugger(&mut self)

Request to enter a debugger session at next event loop

Source

pub fn cancel_debugger_request(&mut self)

Request to enter a debugger session at next event loop

Source

pub fn disable_breakpoints(&mut self)

Disable breakpoints

Source

pub fn enable_breakpoints(&mut self)

Enable breakpoints

Source

pub fn breakpoints_are_enabled(&self) -> bool

Returns true if breakpoints are enabled.

Source

pub fn delete_breakpoint( &mut self, breakpoint_id: u64, ) -> Option<Box<dyn FnOnce(&mut Context)>>

Delete the breakpoint with the given ID

Source

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 PlanSchedules ordered as they are in the queue itself.

Source

pub fn clear_breakpoints(&mut self)

Deletes all breakpoints.

Source

pub fn execute(&mut self)

Execute the simulation until the plan and callback queues are empty

Source

pub fn execute_single_step(&mut self)

Executes a single step of the simulation, prioritizing tasks as follows:

  1. Breakpoints
  2. Callbacks
  3. Plans
  4. Shutdown

Trait Implementations§

Source§

impl ContextGlobalPropertiesExt for Context

Source§

fn set_global_property_value<T: GlobalProperty + 'static>( &mut self, property: T, value: T::Value, ) -> Result<(), IxaError>

Set the value of a global property of type T Read more
Source§

fn get_global_property_value<T: GlobalProperty + 'static>( &self, _property: T, ) -> Option<&T::Value>

Return value of global property T
Source§

fn list_registered_global_properties(&self) -> Vec<String>

Source§

fn get_serialized_value_by_string( &self, name: &str, ) -> Result<Option<String>, IxaError>

Return the serialized value of a global property by fully qualified name Read more
Source§

fn load_parameters_from_json<T: 'static + Debug + DeserializeOwned>( &mut self, file_name: &Path, ) -> Result<T, IxaError>

Given a file path for a valid json file, deserialize parameter values for a given struct T Read more
Source§

fn load_global_properties(&mut self, file_name: &Path) -> Result<(), IxaError>

Load global properties from a JSON file. Read more
Source§

impl ContextNetworkExt for Context

Source§

fn add_edge<T: EdgeType + 'static>( &mut self, person: PersonId, neighbor: PersonId, weight: f32, inner: T::Value, ) -> Result<(), IxaError>

Add an edge of type T between person and neighbor with a given weight. inner is a value of whatever type is associated with T. Read more
Source§

fn add_edge_bidi<T: EdgeType + 'static>( &mut self, person1: PersonId, person2: PersonId, weight: f32, inner: T::Value, ) -> Result<(), IxaError>

Add a pair of edges of type 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 more
Source§

fn remove_edge<T: EdgeType + 'static>( &mut self, person: PersonId, neighbor: PersonId, ) -> Result<(), IxaError>

Remove an edge of type T between person and neighbor if one exists. Read more
Source§

fn get_edge<T: EdgeType + 'static>( &self, person: PersonId, neighbor: PersonId, ) -> Option<&Edge<T::Value>>

Get an edge of type T between person and neighbor if one exists.
Source§

fn get_edges<T: EdgeType + 'static>( &self, person: PersonId, ) -> Vec<Edge<T::Value>>

Get all edges of type 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>>

Get all edges of type 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§

fn find_people_by_degree<T: EdgeType + 'static>( &self, degree: usize, ) -> Vec<PersonId>

Find all people who have an edge of type T and degree degree.
Source§

fn select_random_edge<T: EdgeType + 'static, R: RngId + 'static>( &self, rng_id: R, person_id: PersonId, ) -> Result<Edge<T::Value>, IxaError>
where R::RngType: Rng,

Select a random edge out of the list of outgoing edges of type T from person_id, weighted by the edge weights. Read more
Source§

impl ContextPeopleExt for Context

Source§

fn get_current_population(&self) -> usize

Returns the current population size
Source§

fn add_person<T: InitializationList>( &mut self, props: T, ) -> Result<PersonId, IxaError>

Creates a new person. The caller must supply initial values for all non-derived properties that don’t have a default or an initializer. Note that although this technically takes any type that implements 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 more
Source§

fn get_person_property<T: PersonProperty + 'static>( &self, person_id: PersonId, property: T, ) -> T::Value

Given a 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, )

Given a 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)

Create an index for property T. Read more
Source§

fn query_people<T: Query>(&self, q: T) -> Vec<PersonId>

Query for all people matching a given set of criteria. Read more
Source§

fn query_people_count<T: Query>(&self, q: T) -> usize

Get the count of all people matching a given set of criteria. Read more
Source§

fn match_person<T: Query>(&self, person_id: PersonId, q: T) -> bool

Determine whether a person matches a given expression. Read more
Source§

fn tabulate_person_properties<T: Tabulator, F>( &self, tabulator: &T, print_fn: F, )
where F: Fn(&Context, &[String], usize),

Source§

fn sample_person<R: RngId + 'static, T: Query>( &self, rng_id: R, query: T, ) -> Option<PersonId>
where R::RngType: Rng,

Randomly sample a person from the population of people who match the query. Returns None if no people match the query. Read more
Source§

impl ContextRandomExt for Context

Source§

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

Gets a random sample from the random number generator associated with the given 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
where R::RngType: Rng,

Gets a random sample from the specified distribution using a random number generator associated with the given 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
where R::RngType: Rng, S: SampleRange<T>, T: SampleUniform,

Gets a random sample within the range provided by 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
where R::RngType: Rng,

Gets a random boolean value which is true with probability p 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_weighted<R: RngId + 'static, T>( &self, _rng_id: R, weights: &[T], ) -> usize

Draws a random entry out of the list provided in weights with the given weights 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

Source§

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

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>

Add a report file keyed by a TypeId. The short_name is used for file naming to distinguish what data each output file points to. Read more
Source§

fn add_report<T: Report + 'static>( &mut self, short_name: &str, ) -> Result<(), IxaError>

Call 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 more
Source§

fn add_periodic_report<T: Tabulator + Clone + 'static>( &mut self, short_name: &str, period: f64, tabulator: T, ) -> Result<(), IxaError>

Adds a periodic report at the end of period period which summarizes the number of people in each combination of properties in tabulator. Read more
Source§

fn get_writer(&self, type_id: TypeId) -> RefMut<'_, Writer<File>>

Source§

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>

Add an API point.

Source§

fn setup_web_api(&mut self, port: u16) -> Result<String, IxaError>

Set up the Web API and start the Web server. Read more
Source§

fn schedule_web_api(&mut self, t: f64)

Schedule the simulation to pause at time t and listen for requests from the Web API.
Source§

impl Default for Context

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl Freeze for Context

§

impl !RefUnwindSafe for Context

§

impl !Send for Context

§

impl !Sync for Context

§

impl Unpin for Context

§

impl !UnwindSafe for Context

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more