7 ms·
Show HN: CXXStateTree – A modern C++ library for hierarchical state machines
Hi HN!
I've built [CXXStateTree](https://github.com/ZigRazor/CXXStateTree https://github.com/ZigRazor/CXXStateTree), a modern C++ header-only library to create hierarchical state machines with clean, intuitive APIs.
It supports:
- Deeply nested states
- Entry/exit handlers
- State transitions with guards and actions
- Asynchronous transitions with `co_await` (C++20 coroutines)
- Optional runtime type identification for flexibility
It's ideal for complex control logic, embedded systems, games, robotics, and anywhere you'd use a finite state machine.
I’d love feedback, use cases, or contributions from the community!
Repo: https://github.com/ZigRazor/CXXStateTree https://github.com/ZigRazor/CXXStateTree
- jeffreygoesto 1y agoNice and compact. I only wound have two nitpicks: The Readme sais "zero heap allocations" but the code uses list and unordered map and moves, did you mean "zero allocations after state tree building"? Also for embedded it would be useful to separate all in/out, dot export etc. to a second library that you can omit on small targets.
- zigrazor 1y agoyes, it means "zero allocations after state tree building". Thank you for the suggestions, I think we could separate target with compilation switch. If you want you can open an issue on the repo. Thank you so much
- rpaddock 1y agoIn some Embedded areas where safety is of high concern following the Motor Industry Software Reliability Association (MISRA) guidelines is a requirement. There may be no heap at all and memory must be pre-allocated at system initialization. Otherwise CXXStateTree sounds like it could be very useful in my Embedded devices, which rarely have enough Flash or RAM space, which is the nature of the work. https://misra.org.uk https://misra.org.uk
- happyweasel 1y agovcpkg it
- zigrazor 1y agoYou can open an Issue on that on the repo (https://github.com/ZigRazor/CXXStateTree/issues https://github.com/ZigRazor/CXXStateTree/issues) so we can track these changes. Another idea is to create a Python binding with a release of a package
- dgan 1y agoi am by no means a C++ expert, but isn't "pragma once" frowned upon?
- zigrazor 1y agoplease someone open an Issue on the repo(https://github.com/ZigRazor/CXXStateTree/issues https://github.com/ZigRazor/CXXStateTree/issues), to substitute the #pragma once with the more classic include guards with the motivation explained in the comment. Thank you
- kookamamie 1y agoNo, it is the way. Edit: no one has time for inventing unique names for include guards.
- hdhdjd 1y agoDoes anyone write those by hand anyway in any kind of project the size where it would matter? #pragma once is broken by design
- bogwog 1y agoI don't understand what you're saying here. #pragma once does the job that include guards used to do, but with less work, and in a less error prone way. How is it broken, and how is the size of a project relevant?
- motorest 1y ago> I don't understand what you're saying here. #pragma once does the job that include guards used to do, (...) They don't. They are not C++ and at most they are compiler-specific. It's fine if you opt to not write C++ and instead target specific compilers instead. Just don't pretend it's not frowned upon or kosher.
- bogwog 1y ago
- baymotion 1y agoRelated idea for those using python: https://github.com/baymotion/smax https://github.com/baymotion/smax.
- zigrazor 1y agoI want to create a python binding with PyBind11 and create a simple interface with a very good performance for Embedded systems
- wangii 1y agohow is it better than https://github.com/boost-ext/sml https://github.com/boost-ext/sml ? there are about 1 million c++ state machines, and sml happens to be the best, or one of them. how does yours differentiate?
- canyp 1y agoI was about to complain about the use of strings in both libraries, both for the lack of type safety as well as the possible runtime allocation, but then I looked at the assembly for the sml example and there are no strings in the binary other than the obvious "send" one. What exactly happened there? It looks like make_transition_table() is doing some serious magic. Or are the state transitions evaluated at compile-time given that there is no input in the example, and then the transition table gets compiled out? Anyway, I think it would help OP's library to have some assembly output in the readme as well.
- aw1621107 1y agoLooks like SML is using user-defined literals [0, 1] to effectively pre-process the string literal into state/event objects. Looks like the string itself is turned into a template parameter in the process and I believe those shouldn't show up in the compiled code (maybe unless there's some mangling-related thing going on?) [0]: https://en.cppreference.com/w/cpp/language/user_literal.html https://en.cppreference.com/w/cpp/language/user_literal.html [1]: https://github.com/boost-ext/sml/blob/f232328b49adf708737bef5173d5620855d88446/include/boost/sml.hpp#L2860 https://github.com/boost-ext/sml/blob/f232328b49adf708737bef...
- canyp 1y agoThanks, I didn't know that was a thing.