Export ActorSimulation DSL to production-grade C++ Actor Framework (CAF) code with callback interfaces for customization.
# 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 CAF project with callback interfaces
{:ok, files} = ActorSimulation.CAFGenerator.generate(simulation,
project_name: "PubSubActors",
enable_callbacks: true)
ActorSimulation.CAFGenerator.write_to_directory(files, "caf_output/")*_actor.hpp/cpp- CAF actor implementations (DO NOT EDIT)*_callbacks.hpp- Callback interfaces (DO NOT EDIT)*_callbacks_impl.cpp- Your custom code goes here!test_actors.cpp- Catch2 testsCMakeLists.txt- CMake with test targetconanfile.txt- CAF + Catch2 dependencies.github/workflows/ci.yml- CI pipeline
// publisher_callbacks_impl.cpp (EDIT THIS!)
void publisher_callbacks::on_event() {
// Add your business logic here!
std::cout << "Custom behavior!" << std::endl;
log_to_database();
send_metrics();
}- Production-ready actor systems in C++
- Type-safe message passing
- Distributed actors across networks
- Callback interfaces for clean customization
- Built-in Catch2 tests with CI validation
mix run examples/caf_demo.exs
cd examples/caf_pubsub
# See generated C++ code with tests!cd caf_output/
# Install dependencies with Conan
mkdir build && cd build
conan install .. --build=missing
# Configure with CMake
cmake .. -DCMAKE_BUILD_TYPE=Release
# Build
cmake --build .
# Run tests
./test_actors- CMake 3.15+
- C++17 compiler (GCC 7+, Clang 5+, MSVC 2017+)
- Conan 1.x or 2.x - For CAF and Catch2 dependencies
Install Conan:
pip install conan- Define actors in Elixir DSL
- Generate CAF code with callbacks
- Implement custom logic in
*_callbacks_impl.cpp - Test with generated Catch2 tests
- CI validates on every push
simulation =
ActorSimulation.new()
|> ActorSimulation.add_actor(:source,
send_pattern: {:rate, 100, :data},
targets: [:processor])
|> ActorSimulation.add_actor(:processor,
targets: [:sink])
|> ActorSimulation.add_actor(:sink)
{:ok, files} = ActorSimulation.CAFGenerator.generate(simulation,
project_name: "PipelineActors",
enable_callbacks: true)Generated structure:
caf_output/
├── source_actor.hpp/cpp # CAF actor (generated)
├── source_callbacks.hpp # Interface (generated)
├── source_callbacks_impl.cpp # YOUR CODE HERE
├── processor_actor.hpp/cpp # CAF actor (generated)
├── processor_callbacks.hpp # Interface (generated)
├── processor_callbacks_impl.cpp # YOUR CODE HERE
├── sink_actor.hpp/cpp # CAF actor (generated)
├── sink_callbacks.hpp # Interface (generated)
├── sink_callbacks_impl.cpp # YOUR CODE HERE
├── test_actors.cpp # Catch2 tests
├── CMakeLists.txt
├── conanfile.txt
└── .github/workflows/ci.yml
Generated Interface (DO NOT EDIT):
// processor_callbacks.hpp
class processor_callbacks {
public:
virtual void on_data_received() = 0;
virtual void on_timer_tick() = 0;
virtual ~processor_callbacks() = default;
};Your Implementation (EDIT THIS):
// processor_callbacks_impl.cpp
void processor_callbacks::on_data_received() {
// Transform data
auto result = process(input);
// Log metrics
metrics.increment("processed");
// Forward to next stage
forward_to_sink(result);
}
void processor_callbacks::on_timer_tick() {
flush_buffers();
}The generator creates Catch2 tests:
TEST_CASE("Source actor sends messages", "[source]") {
auto sys = caf::actor_system{cfg};
auto source = sys.spawn<source_actor>();
// Test message generation
self->send(source, start_atom::value);
self->receive(
[&](data_msg msg) {
REQUIRE(msg.id > 0);
}
);
}Run tests:
./test_actorsGenerated .github/workflows/ci.yml validates:
- ✅ Code compiles on Linux, macOS, Windows
- ✅ All tests pass
- ✅ Multiple compiler versions (GCC, Clang, MSVC)
Currently supports:
- ✅ Basic send patterns (periodic, rate, burst)
- ✅ Point-to-point messaging
- ✅ Callback interfaces
- ✅ Catch2 test generation
- ✅ CI pipeline
Not yet supported:
- ❌ Complex state machines
- ❌ Dynamic topology
- ❌ Custom message types
- ❌ Distributed deployment configs
Extend the generator:
- Add custom message type generation
- Implement state machine translation
- Support distributed configurations
- Add more test patterns
See lib/actor_simulation/caf_generator.ex and tests.