yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
gui_commands.cc
Go to the documentation of this file.
2
3#include "absl/strings/numbers.h"
4#include "absl/strings/str_format.h"
7
8namespace yaze {
9namespace cli {
10namespace handlers {
11
12// Default port 50051 - should probably be configurable but hardcoded for now to match server
13static const std::string kDefaultServerAddress = "localhost:50051";
14
16 Rom* rom, const resources::ArgumentParser& parser,
17 resources::OutputFormatter& formatter) {
18 auto tile_id_str = parser.GetString("tile").value();
19 auto x_str = parser.GetString("x").value();
20 auto y_str = parser.GetString("y").value();
21
22 int tile_id, x, y;
23 if (!absl::SimpleHexAtoi(tile_id_str, &tile_id) ||
24 !absl::SimpleAtoi(x_str, &x) || !absl::SimpleAtoi(y_str, &y)) {
25 return absl::InvalidArgumentError("Invalid tile ID or coordinate format.");
26 }
27
28 CanvasAutomationClient client(kDefaultServerAddress);
29 auto status = client.Connect();
30 if (!status.ok()) {
31 return absl::UnavailableError("Failed to connect to GUI server: " + std::string(status.message()));
32 }
33
34 // Assume "overworld" canvas for now, or parse from args if needed
35 std::string canvas_id = "overworld";
36 status = client.SetTile(canvas_id, x, y, tile_id);
37
38 formatter.BeginObject("GUI Tile Placement");
39 formatter.AddField("tile_id", absl::StrFormat("0x%03X", tile_id));
40 formatter.AddField("x", x);
41 formatter.AddField("y", y);
42 if (status.ok()) {
43 formatter.AddField("status", "Success");
44 } else {
45 formatter.AddField("status", "Failed");
46 formatter.AddField("error", std::string(status.message()));
47 }
48 formatter.EndObject();
49
50 return status;
51}
52
54 Rom* rom, const resources::ArgumentParser& parser,
55 resources::OutputFormatter& formatter) {
56 auto target = parser.GetString("target").value();
57 auto click_type_str = parser.GetString("click-type").value_or("left");
58
59 ClickType click_type = ClickType::kLeft;
60 if (click_type_str == "right") click_type = ClickType::kRight;
61 else if (click_type_str == "double") click_type = ClickType::kDouble;
62
63 GuiAutomationClient client(kDefaultServerAddress);
64 auto status = client.Connect();
65 if (!status.ok()) {
66 return absl::UnavailableError("Failed to connect to GUI server: " + std::string(status.message()));
67 }
68
69 auto result = client.Click(target, click_type);
70
71 formatter.BeginObject("GUI Click Action");
72 formatter.AddField("target", target);
73 formatter.AddField("click_type", click_type_str);
74
75 if (result.ok()) {
76 formatter.AddField("status", result->success ? "Success" : "Failed");
77 if (!result->success) {
78 formatter.AddField("error", result->message);
79 }
80 formatter.AddField("execution_time_ms", static_cast<int>(result->execution_time.count()));
81 } else {
82 formatter.AddField("status", "Error");
83 formatter.AddField("error", std::string(result.status().message()));
84 }
85 formatter.EndObject();
86
87 return result.status();
88}
89
91 Rom* rom, const resources::ArgumentParser& parser,
92 resources::OutputFormatter& formatter) {
93 auto window = parser.GetString("window").value_or("");
94 auto type_str = parser.GetString("type").value_or("all");
95
96 GuiAutomationClient client(kDefaultServerAddress);
97 auto status = client.Connect();
98 if (!status.ok()) {
99 return absl::UnavailableError("Failed to connect to GUI server: " + std::string(status.message()));
100 }
101
103 query.window_filter = window;
104 // Mapping type string to enum omitted for brevity, defaulting to all
106
107 auto result = client.DiscoverWidgets(query);
108
109 formatter.BeginObject("Widget Discovery");
110 formatter.AddField("window_filter", window);
111
112 if (result.ok()) {
113 formatter.AddField("total_widgets", result->total_widgets);
114 formatter.AddField("status", "Success");
115
116 formatter.BeginArray("windows");
117 for (const auto& win : result->windows) {
118 formatter.BeginObject("window");
119 formatter.AddField("name", win.name);
120 formatter.BeginArray("widgets");
121 // Limit output to avoid flooding
122 int count = 0;
123 for (const auto& widget : win.widgets) {
124 if (count++ > 50) break;
125 formatter.AddArrayItem(absl::StrFormat("%s (%s) - %s", widget.label, widget.type, widget.path));
126 }
127 formatter.EndArray();
128 formatter.EndObject();
129 }
130 formatter.EndArray();
131 } else {
132 formatter.AddField("status", "Error");
133 formatter.AddField("error", std::string(result.status().message()));
134 }
135 formatter.EndObject();
136
137 return result.status();
138}
139
141 Rom* rom, const resources::ArgumentParser& parser,
142 resources::OutputFormatter& formatter) {
143 auto region = parser.GetString("region").value_or("full");
144 auto image_format = parser.GetString("format").value_or("PNG");
145
146 GuiAutomationClient client(kDefaultServerAddress);
147 auto status = client.Connect();
148 if (!status.ok()) {
149 return absl::UnavailableError("Failed to connect to GUI server: " + std::string(status.message()));
150 }
151
152 auto result = client.Screenshot(region, image_format);
153
154 formatter.BeginObject("Screenshot Capture");
155 formatter.AddField("region", region);
156 formatter.AddField("image_format", image_format);
157
158 if (result.ok()) {
159 formatter.AddField("status", result->success ? "Success" : "Failed");
160 if (result->success) {
161 formatter.AddField("output_path", result->message); // Screenshot path is in message
162 } else {
163 formatter.AddField("error", result->message);
164 }
165 } else {
166 formatter.AddField("status", "Error");
167 formatter.AddField("error", std::string(result.status().message()));
168 }
169 formatter.EndObject();
170
171 return result.status();
172}
173
174} // namespace handlers
175} // namespace cli
176} // namespace yaze
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
Definition rom.h:24
absl::Status SetTile(const std::string &canvas_id, int x, int y, int tile_id)
Client for automating YAZE GUI through gRPC.
absl::StatusOr< AutomationResult > Screenshot(const std::string &region="full", const std::string &format="PNG")
Capture a screenshot.
absl::Status Connect()
Connect to the test harness server.
absl::StatusOr< DiscoverWidgetsResult > DiscoverWidgets(const DiscoverWidgetsQuery &query)
absl::StatusOr< AutomationResult > Click(const std::string &target, ClickType type=ClickType::kLeft)
Click a GUI element.
absl::Status Execute(Rom *rom, const resources::ArgumentParser &parser, resources::OutputFormatter &formatter) override
Execute the command business logic.
absl::Status Execute(Rom *rom, const resources::ArgumentParser &parser, resources::OutputFormatter &formatter) override
Execute the command business logic.
absl::Status Execute(Rom *rom, const resources::ArgumentParser &parser, resources::OutputFormatter &formatter) override
Execute the command business logic.
absl::Status Execute(Rom *rom, const resources::ArgumentParser &parser, resources::OutputFormatter &formatter) override
Execute the command business logic.
Utility for parsing common CLI argument patterns.
std::optional< std::string > GetString(const std::string &name) const
Parse a named argument (e.g., –format=json or –format json)
Utility for consistent output formatting across commands.
void BeginArray(const std::string &key)
Begin an array.
void AddArrayItem(const std::string &item)
Add an item to current array.
void BeginObject(const std::string &title="")
Start a JSON object or text section.
void EndObject()
End a JSON object or text section.
void AddField(const std::string &key, const std::string &value)
Add a key-value pair.
ClickType
Type of click action to perform.