// Author: Paul Oliver // Project: Salis // Lightweight UI for the Salis simulator with minimal output. // Can be interrupted through OS signals. // Ideal for running Salis in the background. volatile bool g_running; uint64_t g_step_block; void info_impl(const char *restrict fmt, ...) { assert(fmt); printf("\033[1;34mINFO:\033[0m "); va_list args; va_start(args, fmt); vprintf(fmt, args); va_end(args); printf("\n"); } void warn_impl(const char *restrict fmt, ...) { assert(fmt); printf("\033[1;31mWARN:\033[0m "); va_list args; va_start(args, fmt); vprintf(fmt, args); va_end(args); printf("\n"); } void sig_handler(int signo) { (void)signo; if (g_running) { g_warn("Signal received, will stop simulator soon..."); g_running = false; } } void step_block() { clock_t beg = clock(); salis_step(g_step_block - (g_steps % g_step_block)); clock_t end = clock(); if ((end - beg) < (CLOCKS_PER_SEC * 4)) { g_step_block <<= 1; } if ((end - beg) >= (CLOCKS_PER_SEC * 2) && g_step_block != 1) { g_step_block >>= 1; } g_info("Simulator running on step '%#lx'", g_steps); } int main() { g_info = info_impl; g_warn = warn_impl; {% if args.command == "new" %} salis_init(); {% elif args.command == "load" %} salis_load(); {% endif %} g_running = true; g_step_block = 1; signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); while (g_running) { step_block(); } g_info("Saving simulation..."); salis_save("{{ sim_path }}"); salis_free(); g_info("Exiting salis..."); return 0; }