sdl_runtime_compiler git · main
SDL3 game for running and compiling code at runtime
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.gzsrc/systems/compiler_system.cpp raw
#include <SDL3/SDL.h>
#include "systems/compiler_system.hpp"
#include "text/text.hpp"
namespace
Nimbin
{
CompilerSystem::~CompilerSystem()
{
if (_worker.joinable()) _worker.join();
}
void
CompilerSystem::compile(Text::Handler& out, const std::string& src)
{
if (_running.load()) return;
if (_worker.joinable()) _worker.join();
last_compile_ok = false;
out.clear();
_count = 0;
{
std::lock_guard<std::mutex> lock(_mtx);
_pending.clear();
}
_running.store(true);
_worker = std::thread(&CompilerSystem::run_Compile, this, src);
}
void
CompilerSystem::run_Compile(CompilerSystem* self, std::string src)
{
FILE* f = fopen("/tmp/game_prog.cpp", "w");
if (!f) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"CompilerSystem: could not write temp file");
self->_running.store(false);
return;
}
fputs(src.c_str(), f);
fclose(f);
FILE* pipe = popen("LC_ALL=C c++ /tmp/game_prog.cpp -o /tmp/game_prog 2>&1", "r");
if (!pipe) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "CompilerSystem: popen failed");
self->_running.store(false);
return;
}
int n = 0;
char buf[512];
while (fgets(buf, sizeof(buf), pipe)) {
std::string line(buf);
if (!line.empty() && line.back() == '\n') line.pop_back();
if (line.empty()) continue;
std::lock_guard<std::mutex> lock(self->_mtx);
self->_pending.push_back(line);
++n;
}
pclose(pipe);
if (n == 0) { // no diagnostics → success
std::lock_guard<std::mutex> lock(self->_mtx);
self->_pending.push_back("OK");
}
self->_running.store(false);
}
void
CompilerSystem::update(Text::Handler& out)
{
constexpr size_t LINES_PER_FRAME = 2;
DynArray<std::string> batch;
{
std::lock_guard<std::mutex> lock(_mtx);
if (_pending.empty()) return;
const size_t n = SDL_min(LINES_PER_FRAME, _pending.size());
for (size_t i = 0; i < n; i++) batch.push_back(std::move(_pending[i]));
_pending.erase(_pending.begin(),
_pending.begin() + static_cast<std::ptrdiff_t>(n));
}
for (const std::string& line : batch)
push_Line(out, line);
}
void
CompilerSystem::push_Line(Text::Handler& out, const std::string& line)
{
if (line == "OK") last_compile_ok = true;
out.append_Line(Text::ascii_Sanitize(line));
_count++;
}
} // namespace Nimbin