7#include "absl/strings/str_format.h"
12#include "imgui/imgui.h"
13#include "imgui/misc/cpp/imgui_stdlib.h"
19constexpr ImVec4
kGreen{0.2f, 0.75f, 0.3f, 1.0f};
20constexpr ImVec4
kRed{0.85f, 0.2f, 0.2f, 1.0f};
21constexpr ImVec4
kYellow{0.85f, 0.75f, 0.1f, 1.0f};
22constexpr ImVec4
kGrey{0.55f, 0.55f, 0.55f, 1.0f};
29 return flag ?
"OK" :
"X";
34 ImGui::TextColored(
kGreen,
"[ran]");
37 if (state ==
"skipped") {
38 ImGui::TextColored(
kGrey,
"[skipped]");
41 ImGui::TextColored(
kYellow,
"[%s]", state.c_str());
45 ImGui::Text(
" %s", label);
47 if (flag.has_value()) {
51 ImGui::TextColored(
kGrey,
"-");
58 std::ifstream file(path);
59 if (!file.is_open()) {
82 project->GetZ3dkArtifactPath(
"annotations.json"), &annotations);
83 const bool has_hooks =
85 if (!has_lint && !has_annotations && !has_hooks) {
89 if (!ImGui::CollapsingHeader(
"z3dk Artifacts",
90 ImGuiTreeNodeFlags_DefaultOpen)) {
96 ?
static_cast<int>(lint[
"errors"].
size())
100 ?
static_cast<int>(lint[
"warnings"].
size())
102 ImGui::Text(
"Lint diagnostics: %d error(s), %d warning(s)", errors,
105 if (has_annotations) {
106 const int count = annotations.
contains(
"annotations") &&
107 annotations[
"annotations"].
is_array()
108 ?
static_cast<int>(annotations[
"annotations"].
size())
110 ImGui::Text(
"Annotations: %d", count);
114 ?
static_cast<int>(hooks[
"hooks"].
size())
116 ImGui::Text(
"Hook/write blocks: %d", count);
128 return "oracle.validation";
132 return "Hack Validation";
148 return "Hack Validation";
152 return "Run project validation and readiness checks for the active hack";
158 return project !=
nullptr && project->project_opened() && backend !=
nullptr;
162 return "Validation backend is not available for the active hack project";
190 return project->rom_filename;
195 return "roms/zelda3.sfc";
202 if (
pending_.wait_for(std::chrono::milliseconds(0)) !=
203 std::future_status::ready) {
236 Rom* rom_context =
nullptr;
244 pending_ = std::async(std::launch::async, [mode, smoke_opts, preflight_opts,
247 return backend->RunValidation(mode, smoke_opts, preflight_opts,
254 result.
error_message =
"No hack workflow backend registered";
255 result.
status_code = absl::StatusCode::kFailedPrecondition;
261 ImGui::SeparatorText(
"Options");
263 ImGui::SetNextItemWidth(320.0f);
264 ImGui::InputText(
"ROM Path", &
rom_path_);
266 if (ImGui::SmallButton(
"From ROM")) {
270 ImGui::SetNextItemWidth(80.0f);
276 ImGui::SeparatorText(
"Preflight options");
277 ImGui::SetNextItemWidth(200.0f);
280 ImGui::TextDisabled(
"(e.g. 0x25,0x27)");
284 ImGui::SetNextItemWidth(280.0f);
291 const bool rom_missing =
294 ImGui::BeginDisabled();
297 ImGui::BeginDisabled();
300 if (ImGui::Button(
"Run Structural Smoke")) {
304 if (ImGui::Button(
"Run Strict Readiness")) {
308 if (ImGui::Button(
"Run Oracle Preflight")) {
313 ImGui::EndDisabled();
318 ImGui::EndDisabled();
320 ImGui::TextColored(kRed,
"Load a ROM first");
326 ImGui::TextDisabled(
"No results yet. Run a check above.");
331 const char* mode_label =
335 ?
"Strict Readiness Smoke"
336 :
"Structural Smoke");
337 const bool overall_ok =
338 result.smoke.has_value()
340 : (result.preflight.has_value() && result.preflight->ok);
342 ImGui::TextColored(overall_ok ? kGreen : kRed,
"%s %s", CheckStr(overall_ok),
344 ImGui::SameLine(0.0f, 16.0f);
345 ImGui::TextColored(kGrey,
"%s", result.timestamp.c_str());
347 ImGui::SetNextItemWidth(380.0f);
348 ImGui::InputText(
"##cli_cmd",
const_cast<char*
>(result.cli_command.c_str()),
349 result.cli_command.size() + 1, ImGuiInputTextFlags_ReadOnly);
351 if (ImGui::SmallButton(
"Copy")) {
352 ImGui::SetClipboardText(result.cli_command.c_str());
355 if (!result.error_message.empty()) {
356 ImGui::TextColored(kRed,
ICON_MD_ERROR " %s", result.error_message.c_str());
358 "Hint: check that the ROM is loaded and the command is available.");
363 if (result.json_parse_failed) {
364 ImGui::TextColored(kYellow,
370 if (result.smoke.has_value()) {
373 if (result.preflight.has_value()) {
376 DrawZ3dkArtifactSummary();
381 if (ImGui::CollapsingHeader(
"D4 Zora Temple",
382 ImGuiTreeNodeFlags_DefaultOpen)) {
383 ImGui::TextColored(BoolColor(smoke.
d4.
structural_ok),
" Structural %s",
385 ImGui::Text(
" Required rooms check:");
388 DrawOptionalBool(
" Rooms 0x25/0x27 have collision:",
392 if (ImGui::CollapsingHeader(
"D6 Goron Mines",
393 ImGuiTreeNodeFlags_DefaultOpen)) {
398 ImGui::TextColored(BoolColor(smoke.
d6.
ok),
" Audit command %s",
399 CheckStr(smoke.
d6.
ok));
402 if (ImGui::CollapsingHeader(
"D3 Kalyxo Castle",
403 ImGuiTreeNodeFlags_DefaultOpen)) {
404 ImGui::Text(
" Readiness check:");
407 DrawOptionalBool(
" Room 0x32 has collision:", smoke.
d3.
ok);
413 if (ImGui::CollapsingHeader(
"Water Fill", ImGuiTreeNodeFlags_DefaultOpen)) {
415 " Region present %s",
422 if (ImGui::CollapsingHeader(
"Custom Collision",
423 ImGuiTreeNodeFlags_DefaultOpen)) {
427 ImGui::Text(
" Required rooms check:");
430 DrawOptionalBool(
" Required rooms have data:",
434 if (!preflight.
errors.empty()) {
435 const std::string errors_label = absl::StrFormat(
436 "Errors (%d)###preflight_errors", preflight.
error_count);
437 if (ImGui::CollapsingHeader(errors_label.c_str())) {
438 for (
const auto& err : preflight.
errors) {
439 ImGui::TextColored(kRed,
" [%s] %s", err.code.c_str(),
440 err.message.c_str());
441 if (err.room_id.has_value()) {
443 ImGui::TextColored(kGrey,
" room %s", err.room_id->c_str());
452 if (ImGui::CollapsingHeader(
"Raw Output (diagnostics)")) {
453 ImGui::InputTextMultiline(
454 "##raw",
const_cast<char*
>(result.
raw_output.c_str()),
455 result.
raw_output.size() + 1, ImVec2(-1.0f, 120.0f),
456 ImGuiInputTextFlags_ReadOnly);
bool contains(const std::string &) const
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
void DrawSmokeCards(const oracle_validation::SmokeResult &smoke)
std::optional< oracle_validation::OracleRunResult > last_result_
std::string GetWorkflowDescription() const override
Optional workflow description for menus/command palette.
std::string status_message_
void DrawRawOutput(const oracle_validation::OracleRunResult &result)
float GetPreferredWidth() const override
Get preferred width for this panel (optional)
std::string GetIcon() const override
Material Design icon for this panel.
std::string GetWorkflowGroup() const override
Optional workflow group for hack-centric actions.
std::string required_collision_rooms_
WindowLifecycle GetWindowLifecycle() const override
Get the lifecycle category for this window.
std::string GetId() const override
Unique identifier for this panel.
std::string GetWorkflowLabel() const override
Optional workflow label for menus/command palette.
void Draw(bool *p_open) override
Draw the panel content.
std::future< oracle_validation::OracleRunResult > pending_
std::string GetDisplayName() const override
Human-readable name shown in menus and title bars.
bool IsEnabled() const override
Check if this panel is currently enabled.
void LaunchRun(oracle_validation::RunMode mode)
std::string GetDisabledTooltip() const override
Get tooltip text when panel is disabled.
static std::string DefaultRomPath()
~OracleValidationPanel() override
std::string GetEditorCategory() const override
Editor category this panel belongs to.
void DrawPreflightCards(const oracle_validation::PreflightResult &preflight)
#define ICON_MD_VERIFIED_USER
Rom * rom()
Get the current ROM instance.
::yaze::project::YazeProject * current_project()
Get the current project instance.
workflow::ValidationCapability * hack_validation_backend()
ImVec4 BoolColor(bool flag)
void DrawZ3dkArtifactSummary()
void DrawOptionalBool(const char *label, const std::optional< bool > &flag)
void DrawCheckBadge(const std::string &state)
const char * CheckStr(bool flag)
bool LoadJsonSummaryFile(const std::string &path, Json *out)
std::string CurrentTimestamp()
Editors are the view controllers for the application.
WindowLifecycle
Defines lifecycle behavior for editor windows.
@ CrossEditor
User can pin to persist across editors.
#define REGISTER_PANEL(PanelClass)
Auto-registration macro for panels with default constructors.
std::string error_message
absl::StatusCode status_code
std::string required_collision_rooms
std::string required_rooms_check
bool water_fill_region_ok
bool custom_collision_maps_ok
std::vector< PreflightError > errors
std::optional< bool > required_rooms_ok
std::string readiness_check
std::string required_rooms_check
std::optional< bool > required_rooms_ok
bool meets_min_track_rooms