Export ActorSimulation DSL to production-grade OMNeT++ C++ code.
# Define your simulation in Elixir
simulation =
ActorSimulation.new()
|> ActorSimulation.add_actor(:publisher,
send_pattern: {:periodic, 100, :event},
targets: [:subscriber1, :subscriber2, :subscriber3])
|> ActorSimulation.add_actor(:subscriber1)
|> ActorSimulation.add_actor(:subscriber2)
|> ActorSimulation.add_actor(:subscriber3)
# Generate complete OMNeT++ project
{:ok, files} = ActorSimulation.OMNeTPPGenerator.generate(simulation,
network_name: "PubSubNetwork",
sim_time_limit: 10)
ActorSimulation.OMNeTPPGenerator.write_to_directory(files, "omnetpp_output/")| File | Description |
|---|---|
NetworkName.ned |
Network topology in NED language |
ActorName.h |
C++ header files for each actor module |
ActorName.cc |
C++ implementation with message handling |
CMakeLists.txt |
CMake build configuration |
conanfile.txt |
Conan package manager configuration |
omnetpp.ini |
Simulation parameters and settings |
| ActorSimulation DSL | OMNeT++ Equivalent |
|---|---|
ActorSimulation.add_actor/2 |
cSimpleModule class |
send_pattern: {:periodic, ms, msg} |
scheduleAt(simTime() + interval) |
send_pattern: {:rate, per_sec, msg} |
scheduleAt(simTime() + 1/rate) |
send_pattern: {:burst, n, ms, msg} |
Loop sending n messages per interval |
targets: [...] |
Output gates + NED connections |
| VirtualClock time | simTime() |
| Message passing | send(msg, "out", gateIndex) |
Periodic Messages:
send_pattern: {:periodic, 100, :tick}
# Generates: scheduleAt(simTime() + 0.1, selfMsg)Rate-Based:
send_pattern: {:rate, 50, :data}
# Generates: scheduleAt(simTime() + 0.02, selfMsg) # 50/sec = 0.02s intervalBurst Pattern:
send_pattern: {:burst, 10, 1000, :batch}
# Generates: for loop sending 10 messages every 1 secondAfter generating the files, build and run with OMNeT++:
# Navigate to output directory
cd omnetpp_output/
# Create build directory
mkdir build && cd build
# Configure with CMake
cmake ..
# Build
make
# Run simulation (command-line interface)
./NetworkName -u Cmdenv
# Or run with GUI
./NetworkNameTo build and run generated code, you need:
- OMNeT++ 6.0+ - Install from omnetpp.org
- CMake 3.15+ - For build configuration
- C++17 compiler - GCC 7+, Clang 5+, or MSVC 2017+
- Conan (optional) - For dependency management
See OMNeT++ Installation Guide for platform-specific instructions.
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)
{:ok, files} = ActorSimulation.OMNeTPPGenerator.generate(simulation,
network_name: "PubSubNetwork",
sim_time_limit: 10)
ActorSimulation.OMNeTPPGenerator.write_to_directory(files, "omnetpp_pubsub/")Generated NED topology:
simple Publisher {
gates:
output out[3];
}
simple Sub1 {
gates:
input in;
}
network PubSubNetwork {
submodules:
publisher: Publisher;
sub1: Sub1;
sub2: Sub2;
sub3: Sub3;
connections:
publisher.out[0] --> sub1.in;
publisher.out[1] --> sub2.in;
publisher.out[2] --> sub3.in;
}Generated C++ (Publisher.cc excerpt):
void Publisher::initialize() {
sendCount = 0;
selfMsg = new cMessage("selfMsg");
scheduleAt(simTime() + 0.1, selfMsg); // 100ms interval
}
void Publisher::handleMessage(cMessage *msg) {
if (msg->isSelfMessage()) {
// Send to all subscribers
for (int i = 0; i < 3; i++) {
cMessage *outMsg = new cMessage("msg");
send(outMsg, "out", i);
sendCount++;
}
scheduleAt(simTime() + 0.1, msg); // Reschedule
}
}{:ok, files} = ActorSimulation.OMNeTPPGenerator.generate(simulation,
network_name: "MyNetwork", # Network name (required)
sim_time_limit: 60.0, # Simulation duration in seconds
output_dir: "custom/path/" # Custom output path (documentation only)
)Run the included demos to see complete examples:
# Generate multiple OMNeT++ projects
mix run examples/omnetpp_demo.exs
# Explore generated code
cd examples/omnetpp_pubsub
ls -la # See all generated files
# View the network topology in PubSubNetwork.ned
# View the C++ implementation in Publisher.ccDevelopment Workflow:
- 🚀 Prototype - Rapid iteration in Elixir with instant feedback
- 🧪 Test - Validate with virtual time and fast simulations
- 📊 Visualize - Generate Mermaid sequence diagrams
- ⚡ Scale - Export to OMNeT++ for large-scale C++ simulations
- 🎯 Deploy - Leverage OMNeT++ ecosystem and performance
Benefits:
- 10-100x faster prototyping in Elixir vs writing C++
- Type safety - Catch errors at compile time in generated C++
- Maintainability - Single source of truth (your DSL)
- Cross-validation - Compare Elixir vs C++ simulation results
- Industry tools - Access OMNeT++ GUI, analysis, and visualization
The generator currently supports:
- ✅ Simple module actors with send patterns
- ✅ Point-to-point message passing
- ✅ Periodic, rate, and burst patterns
- ✅ Basic statistics collection
Not yet supported:
- ❌ Complex state machines (on_receive/on_match functions)
- ❌ Dynamic topology changes
- ❌ Custom message types beyond cMessage
- ❌ Network delays and channel models
- ❌ Parameter sweeps and configurations
For these advanced features, use OMNeT++ directly or extend the generator.
The generator is extensible and contributions are welcome:
- Add support for custom message types
- Implement state machine translation
- Add network delay/loss models
- Support INET framework integration
See lib/actor_simulation/omnetpp_generator.ex and
test/omnetpp_generator_test.exs.