Nimbin[12]?SDL & Graphics / sdl_runtime_compiler / src/systems/cpp_highlight_system.hpp

sdl_runtime_compiler git · main

SDL3 game for running and compiling code at runtime

sdl3 c++ compiler dlopen cmake · first commit 2026-04-19 · last commit 2026-07-03 (3 months ago) · synced 3 days ago · upstream: git.ide3.de/hsnr/sdl-runtime-compiler

C++ 72.3% C 26.2%
git clone https://git.christianimmanuel.de/sdl-graphics/sdl_runtime_compiler.gitwget https://git.christianimmanuel.de/sdl-graphics/sdl_runtime_compiler/archive/sdl_runtime_compiler.tar.gz
src/systems/cpp_highlight_system.hpp 1.9 KB · 80 lines raw
#pragma once

#include <atomic>
#include <mutex>
#include <string>
#include <thread>

#include "text/text.hpp"
#include "utils/globals.hpp"

namespace
Nimbin
{

class CppHighlightSystem
{
public:
    ~CppHighlightSystem() { if (_worker.joinable()) _worker.join(); }

    void request(const std::string& source, uint64_t gen)
    {
        if (source == _last_requested) return;
        _last_requested = source;

        if (_running.load()) { _redo = true; return; }
        spawn(source, gen);
    }

    bool poll(DynArray<Text::HiSpan>& out, uint64_t& out_gen)
    {
        if (!_done.load()) return false;

        {
            std::lock_guard<std::mutex> lk(_mtx);
            out     = _pending;
            out_gen = _result_gen;
        }

        _done.store(false);
        if (_worker.joinable()) _worker.join();
        _running.store(false);

        if (_redo) {
            _redo = false;
            spawn(_last_requested, _last_gen_pending);
        }
        return true;
    }

private:
    DynArray<Text::HiSpan>  _pending;
    std::string       _last_requested;
    std::thread       _worker;
    std::mutex        _mtx;
    uint64_t          _result_gen { 0 };
    uint64_t          _last_gen_pending { 0 };
    std::atomic<bool> _running { false };
    std::atomic<bool> _done    { false };
    bool              _redo    { false };

    void spawn(const std::string& source, uint64_t gen)
    {
        if (_worker.joinable()) _worker.join();
        _running.store(true);
        _done.store(false);
        _last_gen_pending = gen;
        _worker = std::thread([this, source, gen]() {
            DynArray<Text::HiSpan> spans = Text::CppHighlight::classify(source);
            {
                std::lock_guard<std::mutex> lk(_mtx);
                _pending    = std::move(spans);
                _result_gen = gen;
            }
            _done.store(true);
        });
    }

};

} // namespace Nimbin