#include "Application.h" #include "raylib.h" #include #include #include #include "log/log.h" const char* Application::WINDOW_TITLE = "Raylib + AngelScript"; const char* Application::SCRIPT_FILE = "scripts/test.as"; Application::Application() : hotReload(nullptr), scriptCompilationError(false), logFile(nullptr) { } Application::~Application() { Shutdown(); } bool Application::Initialize() { logFile = fopen("log.txt", "w"); log_add_fp(logFile, LOG_TRACE); SetTraceLogCallback(raylib_log); // Initialize Raylib InitWindow(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE); SetTargetFPS(TARGET_FPS); // Initialize AngelScript if (!scriptEngine.Initialize()) { log_error("Failed to initialize script engine"); return false; } // Initialize hot reload to watch the scripts directory so any script change // (not just the main file) triggers a reload. { std::filesystem::path p(SCRIPT_FILE); std::string watchPath = p.parent_path().string(); if (watchPath.empty()) watchPath = "."; hotReload = new HotReload(watchPath); } // Compile initial script scriptCompilationError = !scriptEngine.CompileScript(SCRIPT_FILE); return true; } void Application::Run() { while (!WindowShouldClose()) { float deltaTime = GetFrameTime(); Update(deltaTime); Draw(); // Small sleep to prevent excessive CPU usage std::this_thread::sleep_for(std::chrono::milliseconds(10)); } } void Application::Update(float deltaTime) { // Check for hot reload if (hotReload && hotReload->CheckForChanges()) { bool success = scriptEngine.CompileScript(SCRIPT_FILE); scriptCompilationError = !success; if (!success) { log_warn("Script compilation failed - keeping previous version"); } } // Call script Update function scriptEngine.CallScriptFunction(scriptEngine.GetUpdateFunction(), deltaTime); } void Application::Draw() { BeginDrawing(); ClearBackground(RAYWHITE); // Show script error status in top left if there's an error, otherwise show normal message if (scriptCompilationError) { DrawText("SCRIPT ERROR - Check console for details", 10, 10, 16, RED); } // Call script Draw function scriptEngine.CallScriptFunction(scriptEngine.GetDrawFunction()); EndDrawing(); } void Application::Shutdown() { if (hotReload) { delete hotReload; hotReload = nullptr; } scriptEngine.Shutdown(); // Clear the trace log callback before closing window to prevent logging after cleanup SetTraceLogCallback(nullptr); CloseWindow(); // Close log file after everything else is cleaned up if (logFile) { fclose(logFile); logFile = nullptr; } }