Visualization in Visual Studio watch window using a custom .natvis file:

magic

The structure shown above was generated by HFSM automatically for the following FSM:

using FSM = M::Root<StreetLight,
               M::Composite<On,
                   On::Red,
                   On::Yellow,
                   On::Green
               >,
               Off
            >;

FSM structure and activity history API is available for custom run-time visualization:

// hfsm.hpp:
struct StructureEntry {
    bool isActive;
    const wchar_t* prefix;
    const char* name;
};

using MachineStructure = detail::ArrayView<StructureEntry>;
const MachineStructure& hfsm::M<>::Root<>::structure() const;

using MachineActivity = detail::ArrayView<char>;
const MachineActivity& hfsm::M<>::Root<>::activity() const;

Example: using visualization API to print FSM structure using SFML:

class StructureVisualizer {
    using Lines = std::vector<sf::Text>;
    enum : unsigned { FONT_SIZE = 16u };

public:
    StructureVisualizer(const k9::MachineStructure& structure) {
        _lines.reserve(structure.count());

        for (unsigned i = 0; i < structure.count(); ++i) {
            auto& line = _lines.emplace_back("", font, FONT_SIZE);

            std::wstringstream stream;
            stream << structure[i].prefix << structure[i].name;

            line.setString(stream.str());
            line.setPosition(10.0f, 10.0f + FONT_SIZE * i);
        }
    }

    void draw(const k9::MachineActivity& activity) {
        for (unsigned i = 0; i < activity.count(); ++i) {
            auto& line = _lines[lineIndex];

            if (activity[lineIndex] > 0)
                line.setFillColor(sf::Color::Yellow);
            else
                line.setFillColor(sf::Color(127, 127, 127, 255));

            line.setPosition(10.0f, 10.0f + FONT_SIZE * i);
            window.draw(line);
        }
    }

private:
    Lines _lines;
};

int main() {
    Context context;
    FSM fsm(context);

    StructureVisualizer structureVisualizer(fsm.structure());
    fsm.enter();

    while (/* running */) {
        // ...
        structureVisualizer.draw(fsm.activity());
    }
}