-
Dorian Weber authored0d54fc75
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
README.md 4.09 KiB
ODEM-rs: Object-Based Discrete-Event Modeling in Rust
ODEM-rs is a modular object-based discrete-event modeling framework for Rust. It provides an extensible,
deterministic simulation environment with structured concurrency using async
/await
.

Features

- Process-Based Simulation: Model simulation entities as concurrent agents with isolated state and internal concurrency.
- Event-Driven Execution: Skips directly between events rather than using a fixed time step.
- Deterministic & Reproducible: Uses pseudo-random number generators (PRNGs) and cooperative concurrency for portably reproducable results.
- Extensible & Modular: Provides traits and modular components across multiple crates.
-
no_std
Compatible: Supports bare-metal execution with minimal reductions in provided utilities.

Crate Organization

The ODEM-rs workspace consists of several crates, each serving a specific purpose:
Crate | Description |
---|---|
odem-rs |
Main library providing the entry point to the simulation framework. |
odem-rs-core |
Foundational structures, traits, and event-scheduling logic. |
odem-rs-meta |
Procedural macros for auto-generating configuration traits. |
odem-rs-sync |
Synchronization primitives and communication structures for agents and jobs. |
odem-rs-util |
Utility tools such as object pools, PRNG streams, and statistics modules. |

Getting Started

Installation
Add ODEM-rs to your Cargo.toml
:
[dependencies]
odem-rs = "0.1"
Or include specific sub-crates if you only need certain components.
Example: Barbershop Simulation
use odem_rs::{prelude::*, sync::facility::Facility};
#[derive(Config, Default)]
struct Barbershop {
barber: Facility,
rng_stream: RngStream,
}
struct Customer;
impl Behavior<Barbershop> for Customer {
type Output = ();
async fn actions(&self, sim: &Sim<Barbershop>) {
let mut duration = sim.global().rng_stream.rng();
let chair = sim.global().barber.seize().await;
sim.advance(duration.random_range(12.0..18.0)).await;
chair.release();
}
}
async fn sim_main(sim: &Sim<Barbershop>) {
sim.fork(async {
let mut delay = sim.global().rng_stream.rng();
let pool = Pool::dynamic();
loop {
sim.advance(delay.random_range(12.0..24.0)).await;
sim.activate(pool.alloc(Agent::new(Customer)));
}
}).or(sim.advance(12.0 * 60.0)).await;
}
fn main() {
simulation(sim_main).ok();
}
More examples can be found in the examples
directory.

Contributors & Acknowledgments

ODEM-rs is part of my doctoral research and has received invaluable contributions from:
- Lukas Markeffsky – Type system discussions and problem-solving.
- Paula Wiesner – Initial agent-based prototyping.
- Jens-Peter Redlich – Academic advisory support.
- Joachim Fischer – Mentorship and insights into simulation modeling.
I welcome contributions and feedback! Open an issue or submit a PR.

License

ODEM-rs is licensed under MIT. See LICENSE for details.