Module store

Source
Expand description

A data store.

The Store is a component that can hold a number of items defined by its capacity.

§Ports

This component has the following ports:

  • The rx port [InPort] which is used to put data into the store.
  • The tx port [OutPort] which is used to get data out of the store.

A given Store is capable of holding any type as long as it implements the [SimObject] trait. This trait has been implemented for a few builtin types like i32 and usize so that they can be used for simple testing.


§Build a store

Here is an example creating a Store:

use std::rc::Rc;

use gwr_components::store::Store;
use gwr_engine::engine::Engine;
use gwr_engine::executor::Spawner;
use gwr_track::entity::Entity;

fn build_store(engine: &Engine, parent: &Rc<Entity>, spawner: Spawner) -> Rc<Store<i32>> {
    // Create a store. It is passed:
    //   - a parent entity which provides its location within the simulation.
    //   - a name which should be unique within the parent.
    //   - a [spawner](gwr_engine::executor::Spawner) that is used to spawn
    //     internal concurrent tasks.
    //   - a capacity.
    let store: Rc<Store<i32>> = Store::new_and_register(engine, parent, "store", spawner, 5)
        .expect("should be able to create and register `Store`");
    store
}

By default, the store enters a waiting state if the capacity is overflown, but this behaviour can be changed to return an error, by using the set_error_on_overflow() method.

use std::rc::Rc;

use gwr_components::store::Store;
use gwr_engine::engine::Engine;
use gwr_engine::executor::Spawner;
use gwr_track::entity::Entity;

fn build_store_with_panic(
    engine: &Engine,
    parent: &Rc<Entity>,
    spawner: Spawner,
) -> Rc<Store<i32>> {
    // Create a store that panics on overflow. Use `new_and_register()` as before,
    // then call `set_error_on_overflow()` on the resulting struct.
    let store = Store::new_and_register(engine, parent, "store_error", spawner, 5)
        .expect("should be able to create and register `Store`");
    store.set_error_on_overflow();
    store
}

§Connect a store

Here is an example of a more complete simulation using a Store as well as a Source to put data into the store and an Sink to take the data out of the store.

use std::rc::Rc;
use gwr_components::sink::Sink;
use gwr_components::source::Source;
use gwr_components::store::Store;
use gwr_components::{connect_port, option_box_repeat};
use gwr_engine::engine::Engine;
use gwr_engine::run_simulation;

// Every simulation is based around an `Engine`
let mut engine = Engine::default();

// A spawner allows components to spawn activity
let spawner = engine.spawner();

// Take a reference to the engine top to use as the parent
let top = engine.top();

// Create the basic componets:
// The simplest use of the source is to inject the same value repeatedly.
let source = Source::new_and_register(&engine, top, "source", option_box_repeat!(1 ; 10))
    .expect("should be able to create and register `Source`");
// Create the store - its type will be derived from the connections to its ports.
let store = Store::new_and_register(&engine, top, "store", spawner, 5)
    .expect("should be able to create and register `Store`");
// Create the sink which will pull all of the data items out of the store
let sink = Sink::new_and_register(&engine, top, "sink")
    .expect("should be able to create and register `Sink`");

// Connect the ports together:
// The source will drive data into the store:
connect_port!(source, tx => store, rx)
    .expect("should be able to connect `Source` to `Store`");

// The sink will pull data out of the store
connect_port!(store, tx => sink, rx)
    .expect("should be able to connect `Store` to `Sink`");

// The `run_simulation!` macro then spawns all active components
// and runs the simulation to completion.
run_simulation!(engine);

Structs§

Store
A component that can support a configurable number of objects.