DEV Community

Cover image for Building Better State Machines in Modern C++: CXXStateTree
ZigRazor
ZigRazor

Posted on

Building Better State Machines in Modern C++: CXXStateTree

Building Better State Machines in Modern C++: CXXStateTree

State machines are the backbone of countless software systems - from game AI and UI flows to embedded devices and network protocols. Yet, implementing them in C++ often feels like we're stuck in the past: endless switch statements, tangled conditionals, and boilerplate that makes your eyes glaze over.

What if there was a better way?

๐Ÿš€ Meet CXXStateTree

CXXStateTree is a modern, header-only C++20 library that brings elegance and performance to state machine development. It's designed for developers who want clean, maintainable code without sacrificing the performance C++ is known for.

๐Ÿ’ก Why Another State Machine Library?

Fair question! Here's what makes CXXStateTree different:

โšก Zero Heap Allocation

Every allocation counts in performance-critical applications. CXXStateTree is designed with a zero-allocation philosophy - everything stays on the stack where possible.

๐Ÿ”ง Fluent Builder API

No more fighting with complex constructors or configuration objects. Build your state machine the way you'd draw it on a whiteboard:

#include <iostream>
#include "CXXStateTree/StateTree.hpp"

using namespace CXXStateTree;

int main() {
    auto machine = StateTree::Builder()
        .initial("Idle")
        .state("Idle", [](State& s) {
            s.on("Start", "Running", nullptr, []() {
                std::cout << "๐Ÿš€ Starting engine..." << std::endl;
            });
        })
        .state("Running", [](State& s) {
            s.on("Stop", "Idle", nullptr, []() {
                std::cout << "๐Ÿ›‘ Stopping engine..." << std::endl;
            });
        })
        .build();

    machine.send("Start");  // Output: ๐Ÿš€ Starting engine...
    machine.send("Stop");   // Output: ๐Ÿ›‘ Stopping engine...
}
Enter fullscreen mode Exit fullscreen mode

Clean. Readable. Self-documenting.

๐Ÿ›ก๏ธ Guards and Actions

Real-world state machines need conditional logic. CXXStateTree lets you attach guards (conditions) and actions to transitions:

auto doorMachine = StateTree::Builder()
    .initial("Closed")
    .state("Closed", [](State& s) {
        s.on("Open", "Open", 
            []() { 
                // Guard: only open if unlocked
                return !isDoorLocked(); 
            },
            []() { 
                // Action: perform the opening
                std::cout << "๐Ÿšช Opening door..." << std::endl;
            }
        );
    })
    .state("Open", [](State& s) {
        s.on("Close", "Closed", nullptr, []() {
            std::cout << "๐Ÿšช Closing door..." << std::endl;
        });
    })
    .build();
Enter fullscreen mode Exit fullscreen mode

๐ŸŒณ Hierarchical States (Available!)

One of the most powerful features - nested states for modeling complex behaviors:

Game Character
โ”œโ”€โ”€ Alive
โ”‚   โ”œโ”€โ”€ Idle
โ”‚   โ”œโ”€โ”€ Walking
โ”‚   โ””โ”€โ”€ Running
โ””โ”€โ”€ Dead
Enter fullscreen mode Exit fullscreen mode

This allows you to handle events at different levels of specificity, reducing code duplication and improving maintainability.

๐ŸŽฏ Real-World Use Cases

CXXStateTree shines in:

  • ๐ŸŽฎ Game Development: Character AI, game flow, animation controllers
  • ๐Ÿ“ฑ UI Development: Form wizards, navigation flows, modal states
  • ๐Ÿค– Embedded Systems: Protocol handlers, device state management
  • ๐ŸŒ Network Programming: Connection state machines, protocol implementations
  • ๐Ÿฆพ Robotics: Behavior trees, task scheduling

๐Ÿ“ฆ Getting Started

Requirements

  • C++20 compiler (GCC โ‰ฅ 10, Clang โ‰ฅ 11, MSVC โ‰ฅ 2019)
  • CMake (for building)

Installation

Option 1: Single Header (Recommended)

git clone https://github.com/ZigRazor/CXXStateTree.git
cd CXXStateTree
cmake -S . -B build -DENABLE_SINGLE_HEADER=ON
cmake --build build
Enter fullscreen mode Exit fullscreen mode

The single header file will be in single_include/CXXStateTree.hpp - just drop it into your project!

Option 2: Shared Library

cmake -S . -B build
cmake --build build
Enter fullscreen mode Exit fullscreen mode

Quick Example: Traffic Light

Let's build a simple traffic light system:

#include <iostream>
#include <thread>
#include <chrono>
#include "CXXStateTree/StateTree.hpp"

using namespace CXXStateTree;
using namespace std::chrono_literals;

int main() {
    auto trafficLight = StateTree::Builder()
        .initial("Red")
        .state("Red", [](State& s) {
            s.on("Timer", "Green", nullptr, []() {
                std::cout << "๐Ÿ”ด -> ๐ŸŸข RED to GREEN" << std::endl;
            });
        })
        .state("Green", [](State& s) {
            s.on("Timer", "Yellow", nullptr, []() {
                std::cout << "๐ŸŸข -> ๐ŸŸก GREEN to YELLOW" << std::endl;
            });
        })
        .state("Yellow", [](State& s) {
            s.on("Timer", "Red", nullptr, []() {
                std::cout << "๐ŸŸก -> ๐Ÿ”ด YELLOW to RED" << std::endl;
            });
        })
        .build();

    // Simulate traffic light cycle
    for (int i = 0; i < 6; i++) {
        std::this_thread::sleep_for(2s);
        trafficLight.send("Timer");
    }

    return 0;
}
Enter fullscreen mode Exit fullscreen mode

๐Ÿ—๏ธ Project Quality

CXXStateTree isn't just elegant code - it's built with professional software engineering practices:

  • โœ… Google Test Integration - Comprehensive unit test suite
  • โœ… Codecov Integration - Track test coverage
  • โœ… GitHub Actions CI/CD - Every commit is validated
  • โœ… Modern CMake - Easy integration into existing projects

๐Ÿ—บ๏ธ Roadmap

The project has an exciting future ahead:

Status Version Features
โœ… v0.1.0 Basic state machine with transitions
โœ… v0.2.0 Guards and actions
โœ… v0.3.0 Nested hierarchical states
โœ… v0.4.0 Graphviz export
๐Ÿšง v0.5.0 Coroutine/async support
๐Ÿ“‹ v1.0.0 Full test coverage, benchmarks, docs

๐Ÿค Contributing

CXXStateTree is open source under the MPL 2.0 license and welcomes contributions!

Ways to contribute:

  • ๐Ÿ› Report bugs and issues
  • ๐Ÿ’ก Suggest new features
  • ๐Ÿ”ง Submit pull requests
  • ๐Ÿ“š Improve documentation
  • โšก Share performance benchmarks

๐ŸŽ“ Learning Resources

Want to dive deeper? Check out:

๐Ÿ’ญ Final Thoughts

State machines don't have to be a pain in C++. With CXXStateTree, you get:

  1. Developer Productivity - Write less, express more
  2. Maintainability - Clear structure that scales
  3. Performance - Zero-overhead abstractions
  4. Modern C++ - Built for C++20 and beyond
  5. Active Development - Regular updates and improvements

Whether you're building a game, an embedded system, or a complex business application, CXXStateTree provides a solid foundation for managing state transitions cleanly and efficiently.

๐Ÿš€ Try It Today

git clone https://github.com/ZigRazor/CXXStateTree.git
Enter fullscreen mode Exit fullscreen mode

Give it a star โญ if you find it useful, and share your experience in the comments below!


What kind of state machines are you building? Drop a comment and let's discuss! ๐Ÿ’ฌ


Who Am I?

Top comments (0)