Turn an actor_simulation model into a runnable project in another language:
C++ (CAF or OMNeT++), Go (Phony), Pony, Rust (Ractor) or Java (VLINGO XOOM).
Each generated project comes with build files, a CI workflow, a test suite and,
for every target but OMNeT++, callback interfaces, so behaviour can be
customised without editing generated code.
Prototype in Elixir where a simulated hour takes a millisecond, then take the same model to production.
The family
| Package | What it is for | Add it when |
|---|---|---|
gen_server_virtual_time | virtual clock, GenServer/gen_statem wrappers | you test code with timers |
gen_server_virtual_time_migrate | mix virtual_time.migrate rewrites GenServer code | you already have servers and want to keep them |
actor_simulation | actor-system DSL, statistics, sequence diagrams | you model parts of a system talking to each other |
actor_simulation_codegen (this one) | generate runnable projects in six runtimes | you want the same model in another language |
This package depends on actor_simulation, which brings
gen_server_virtual_time with it.
Install
def deps do
[{:actor_simulation_codegen, "~> 1.0.1"}]
endTargets
| Generator | Language | Framework | Output |
|---|---|---|---|
| CAF | C++ | C++ Actor Framework | Typed actors, CMake build, Conan deps, tests |
| Phony | Go | Phony | Zero-alloc actors, Go modules, tests |
| Pony | Pony | Pony Language | Type-safe actors, Corral deps, PonyTest |
| Ractor | Rust | Ractor | Gen_server-inspired, Cargo, async/await |
| VLINGO | Java | VLINGO XOOM | Protocol actors, Maven, JUnit 5 |
| OMNeT++ | C++ | OMNeT++ | Discrete-event simulation, NED files, CMake |
Each is generated from the same simulation:
simulation = ActorSimulation.new()
|> ActorSimulation.add_actor(:publisher,
send_pattern: {:periodic, 100, :event},
targets: [:sub1, :sub2, :sub3])
|> ActorSimulation.add_actor(:sub1)
|> ActorSimulation.add_actor(:sub2)
|> ActorSimulation.add_actor(:sub3)
# C++ with the C++ Actor Framework
{:ok, files} = ActorSimulation.CAFGenerator.generate(simulation,
project_name: "PubSubActors",
enable_callbacks: true)
ActorSimulation.CAFGenerator.write_to_directory(files, "caf_output/")
# Go with Phony
{:ok, files} = ActorSimulation.PhonyGenerator.generate(simulation,
project_name: "pubsub",
enable_callbacks: true)
ActorSimulation.PhonyGenerator.write_to_directory(files, "phony_output/")
# Rust with Ractor
{:ok, files} = ActorSimulation.RactorGenerator.generate(simulation,
project_name: "pubsub",
enable_callbacks: true)
ActorSimulation.RactorGenerator.write_to_directory(files, "ractor_output/")Then build the output with its own toolchain — each generated project ships a
README.md with the exact commands:
| Target | Build |
|---|---|
| CAF | cmake + conan |
| OMNeT++ | cmake (NED files and a runnable config) |
| Pony | make (Corral for dependencies) |
| Phony | go test ./... |
| Ractor | cargo test |
| VLINGO | mvn compile exec:exec (forked JVM) |
Callback interfaces let you change behaviour without touching generated files:
// CAF: publisher_callbacks_impl.cpp
void publisher_callbacks::on_event() {
log_to_database();
send_metrics();
}// Ractor: publisher.rs
impl PublisherCallbacks for MyPublisherCallbacks {
fn on_event(&self) {
println!("Publishing event with custom handler");
}
}Guides
- Code generators overview — what every target emits and how the shared pieces fit
- OMNeT++ · CAF · Pony · Phony · Ractor · VLINGO XOOM
- API reference
- Changelog
License
MIT License - See the LICENSE file for details.