From 9c2a6f90193d403188c034e4242caea10defd043 Mon Sep 17 00:00:00 2001 From: Antoine Pilote Date: Fri, 16 Aug 2024 17:58:06 -0400 Subject: [PATCH] Now displaying compilation errors in logger with status bar --- Editor/src/Windows/EditorInterface.cpp | 72 ++++++++++++++++++---- Nuake/src/Core/OS.cpp | 6 +- Nuake/src/Core/OS.h | 2 +- Nuake/src/Scripting/ScriptingEngineNet.cpp | 65 ++++++++++++++++++- 4 files changed, 128 insertions(+), 17 deletions(-) diff --git a/Editor/src/Windows/EditorInterface.cpp b/Editor/src/Windows/EditorInterface.cpp index d7036adf..24ba3425 100644 --- a/Editor/src/Windows/EditorInterface.cpp +++ b/Editor/src/Windows/EditorInterface.cpp @@ -497,21 +497,37 @@ namespace Nuake { std::string statusMessage = ICON_FA_HAMMER + std::string(" Building .Net solution..."); SetStatusMessage(statusMessage); + + auto job = [this]() { - ScriptingEngineNet::Get().BuildProjectAssembly(Engine::GetProject()); + this->errors = ScriptingEngineNet::Get().BuildProjectAssembly(Engine::GetProject()); }; Selection = EditorSelection(); JobSystem::Get().Dispatch(job, [this]() { - SetStatusMessage("Entering play mode..."); - - PushCommand(SetGameState(GameState::Playing)); + if (errors.size() > 0) + { + SetStatusMessage("Failed to build scripts! See Logger for more info", { 1.0f, 0.1f, 0.1f, 1.0f }); - std::string statusMessage = ICON_FA_RUNNING + std::string(" Playing..."); - SetStatusMessage(statusMessage.c_str(), { 97.0 / 255.0, 0, 1, 1 }); + Logger::Log("Build FAILED.", ".net", CRITICAL); + for (CompilationError error : errors) + { + const std::string errorMessage = error.file + "( line " + std::to_string(error.line) + "): " + error.message; + Logger::Log(errorMessage, ".net", CRITICAL); + } + } + else + { + SetStatusMessage("Entering play mode..."); + + PushCommand(SetGameState(GameState::Playing)); + + std::string statusMessage = ICON_FA_RUNNING + std::string(" Playing..."); + SetStatusMessage(statusMessage.c_str(), { 97.0 / 255.0, 0, 1, 1 }); + } }); } } @@ -608,11 +624,31 @@ namespace Nuake { if (ImGui::Button(ICON_FA_HAMMER, ImVec2(30, 30))) { - JobSystem::Get().Dispatch([]() + SetStatusMessage(std::string(ICON_FA_HAMMER)+ " Building solution...", { 0.1f, 0.1f, 1.0f, 1.0f }); + + auto job = [this]() { - Nuake::ScriptingEngineNet::Get().BuildProjectAssembly(Engine::GetProject()); - }, []() {} - ); + this->errors = ScriptingEngineNet::Get().BuildProjectAssembly(Engine::GetProject()); + }; + + JobSystem::Get().Dispatch(job, [this]() + { + if (errors.size() > 0) + { + SetStatusMessage("Failed to build scripts! See Logger for more info", { 1.0f, 0.1f, 0.1f, 1.0f }); + + Logger::Log("Build FAILED.", ".net", CRITICAL); + for (CompilationError error : errors) + { + const std::string errorMessage = error.file + "( line " + std::to_string(error.line) + "): " + error.message; + Logger::Log(errorMessage, ".net", CRITICAL); + } + } + else + { + SetStatusMessage("Build succesful!"); + } + }); } if (ImGui::BeginItemTooltip()) @@ -2088,6 +2124,8 @@ namespace Nuake { else severityText = "critical"; + ImVec4 redColor = ImVec4(0.6, 0.1f, 0.1f, 0.2f); + ImVec4 yellowColor = ImVec4(0.6, 0.6f, 0.1f, 0.2f); ImVec4 colorGreen = ImVec4(0.59, 0.76, 0.47, 1.0); ImGui::PushStyleColor(ImGuiCol_Text, colorGreen); ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, ImGui::GetColorU32(ImVec4(0.59, 0.76, 0.47, 0.2)), -1); @@ -2107,7 +2145,19 @@ namespace Nuake { ImVec4 color = ImVec4(1, 1, 1, 1.0); ImGui::PushStyleColor(ImGuiCol_Text, color); - ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, ImGui::GetColorU32(ImVec4(1, 1, 1, 0.0)), -1); + + if (l.type == CRITICAL) + { + ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, ImGui::GetColorU32(redColor), -1); + } + else if (l.type == WARNING) + { + ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, ImGui::GetColorU32(yellowColor), -1); + } + else + { + ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, ImGui::GetColorU32(ImVec4(1, 1, 1, 0.0)), -1); + } std::string displayMessage = l.message; if (l.count > 0) diff --git a/Nuake/src/Core/OS.cpp b/Nuake/src/Core/OS.cpp index 234883e0..d03f3308 100644 --- a/Nuake/src/Core/OS.cpp +++ b/Nuake/src/Core/OS.cpp @@ -142,7 +142,7 @@ namespace Nuake { return path; } - void OS::CompileSln(const std::string& slnPath) + std::string OS::CompileSln(const std::string& slnPath) { std::string output = ""; std::string err = ""; @@ -154,9 +154,11 @@ namespace Nuake { Logger::Log(err.c_str(), ".NET", LOG_TYPE::COMPILATION); } - Logger::Log(output.c_str(), ".NET"); + return output; } + + int OS::Subprocess(const std::string& command, std::string& out, std::string& err) { auto splits = String::Split(command, ' '); diff --git a/Nuake/src/Core/OS.h b/Nuake/src/Core/OS.h index f8f618b4..d7b1a391 100644 --- a/Nuake/src/Core/OS.h +++ b/Nuake/src/Core/OS.h @@ -19,7 +19,7 @@ namespace Nuake static void OpenTrenchbroomMap(const std::string& filePath); static void OpenURL(const std::string& url); static std::string GetConfigFolderPath(); - static void CompileSln(const std::string& slnPath); + static std::string CompileSln(const std::string& slnPath); static int Subprocess(const std::string& command, std::string& out, std::string& err); }; diff --git a/Nuake/src/Scripting/ScriptingEngineNet.cpp b/Nuake/src/Scripting/ScriptingEngineNet.cpp index 78ca6811..f46e46cf 100644 --- a/Nuake/src/Scripting/ScriptingEngineNet.cpp +++ b/Nuake/src/Scripting/ScriptingEngineNet.cpp @@ -66,6 +66,55 @@ namespace Nuake m_HostInstance->Shutdown(); } + std::vector ScriptingEngineNet::ExtractErrors(const std::string& output) + { + std::vector errors; + + std::istringstream stream(output); + std::string line; + + while (std::getline(stream, line)) + { + auto trimmed = String::RemoveWhiteSpace(line); + auto parenSplit = String::Split(trimmed, '('); + if (parenSplit.size() > 1) + { + const std::string filePath = parenSplit[0]; + const std::string restOfLine = parenSplit[1]; + + auto numbersString = String::Split(restOfLine, ')'); + if (numbersString.size() > 1) + { + auto lineCharNums = String::Split(numbersString[0], ','); + + int lineNum = std::stoi(lineCharNums[0]); + int charNum = std::stoi(lineCharNums[1]); + + // error message + std::string errMesg = ""; + int i = 0; + for (auto s : String::Split(line, ':')) + { + if (i >= 3) + { + errMesg += s; + } + i++; + } + + CompilationError compilationError; + compilationError.message = errMesg; + compilationError.file = filePath; + compilationError.line = lineNum; + errors.push_back(compilationError); + } + } + + } + + return errors; + } + ScriptingEngineNet& ScriptingEngineNet::Get() { static ScriptingEngineNet instance; @@ -149,16 +198,26 @@ namespace Nuake return m_GameEntityTypes[className].exposedVars; } - void ScriptingEngineNet::BuildProjectAssembly(Ref project) + std::vector ScriptingEngineNet::BuildProjectAssembly(Ref project) { const std::string sanitizedProjectName = String::Sanitize(project->Name); if (!FileSystem::FileExists(sanitizedProjectName + ".sln")) { Logger::Log("Couldn't find .net solution. Have you created a solution?", ".net", CRITICAL); - return; + return std::vector(); } - OS::CompileSln(FileSystem::Root + sanitizedProjectName + ".sln"); + std::string result = OS::CompileSln(FileSystem::Root + sanitizedProjectName + ".sln"); + + return ExtractErrors(result); + //if (errors.size() > 0) + //{ + // Logger::Log("Build failed!", ".net", CRITICAL); + // for (auto& err : errors) + // { + // Logger::Log(err.file + " line " + std::to_string(err.line) + " : " + err.message, ".net", CRITICAL); + // } + //} } void ScriptingEngineNet::LoadProjectAssembly(Ref project)