5#include <grpcpp/grpcpp.h>
9#include "protos/canvas_automation.grpc.pb.h"
10#include "protos/canvas_automation.pb.h"
17grpc::Status ConvertStatus(
const absl::Status& status) {
19 return grpc::Status::OK;
22 grpc::StatusCode code;
23 switch (status.code()) {
24 case absl::StatusCode::kNotFound:
25 code = grpc::StatusCode::NOT_FOUND;
27 case absl::StatusCode::kInvalidArgument:
28 code = grpc::StatusCode::INVALID_ARGUMENT;
30 case absl::StatusCode::kFailedPrecondition:
31 code = grpc::StatusCode::FAILED_PRECONDITION;
33 case absl::StatusCode::kOutOfRange:
34 code = grpc::StatusCode::OUT_OF_RANGE;
36 case absl::StatusCode::kUnimplemented:
37 code = grpc::StatusCode::UNIMPLEMENTED;
39 case absl::StatusCode::kInternal:
40 code = grpc::StatusCode::INTERNAL;
42 case absl::StatusCode::kUnavailable:
43 code = grpc::StatusCode::UNAVAILABLE;
46 code = grpc::StatusCode::UNKNOWN;
50 return grpc::Status(code, std::string(status.message().data(), status.message().size()));
55void CanvasAutomationServiceImpl::RegisterCanvas(
const std::string& canvas_id,
56 gui::Canvas* canvas) {
57 canvases_[canvas_id] = canvas;
60void CanvasAutomationServiceImpl::RegisterOverworldEditor(
61 const std::string& canvas_id, editor::OverworldEditor* editor) {
62 overworld_editors_[canvas_id] = editor;
65gui::Canvas* CanvasAutomationServiceImpl::GetCanvas(
66 const std::string& canvas_id) {
67 auto it = canvases_.find(canvas_id);
68 if (it != canvases_.end()) {
74editor::OverworldEditor* CanvasAutomationServiceImpl::GetOverworldEditor(
75 const std::string& canvas_id) {
76 auto it = overworld_editors_.find(canvas_id);
77 if (it != overworld_editors_.end()) {
87absl::Status CanvasAutomationServiceImpl::SetTile(
88 const proto::SetTileRequest* request, proto::SetTileResponse* response) {
89 auto* canvas = GetCanvas(request->canvas_id());
91 response->set_success(
false);
92 response->set_error(
"Canvas not found: " + request->canvas_id());
93 return absl::NotFoundError(response->error());
96 auto* api = canvas->GetAutomationAPI();
97 bool success = api->SetTileAt(request->x(), request->y(), request->tile_id());
99 response->set_success(success);
102 "Failed to set tile - out of bounds or callback failed");
105 return absl::OkStatus();
108absl::Status CanvasAutomationServiceImpl::GetTile(
109 const proto::GetTileRequest* request, proto::GetTileResponse* response) {
110 auto* canvas = GetCanvas(request->canvas_id());
112 response->set_success(
false);
113 response->set_error(
"Canvas not found: " + request->canvas_id());
114 return absl::NotFoundError(response->error());
117 auto* api = canvas->GetAutomationAPI();
118 int tile_id = api->GetTileAt(request->x(), request->y());
121 response->set_tile_id(tile_id);
122 response->set_success(
true);
124 response->set_success(
false);
125 response->set_error(
"Tile not found - out of bounds or no callback set");
128 return absl::OkStatus();
131absl::Status CanvasAutomationServiceImpl::SetTiles(
132 const proto::SetTilesRequest* request, proto::SetTilesResponse* response) {
133 auto* canvas = GetCanvas(request->canvas_id());
135 response->set_success(
false);
136 response->set_error(
"Canvas not found: " + request->canvas_id());
137 return absl::NotFoundError(response->error());
140 auto* api = canvas->GetAutomationAPI();
142 std::vector<std::tuple<int, int, int>> tiles;
143 for (
const auto& tile : request->tiles()) {
144 tiles.push_back({tile.x(), tile.y(), tile.tile_id()});
147 bool success = api->SetTiles(tiles);
148 response->set_success(success);
149 response->set_tiles_painted(tiles.size());
151 return absl::OkStatus();
158absl::Status CanvasAutomationServiceImpl::SelectTile(
159 const proto::SelectTileRequest* request,
160 proto::SelectTileResponse* response) {
161 auto* canvas = GetCanvas(request->canvas_id());
163 response->set_success(
false);
164 response->set_error(
"Canvas not found: " + request->canvas_id());
165 return absl::NotFoundError(response->error());
168 auto* api = canvas->GetAutomationAPI();
169 api->SelectTile(request->x(), request->y());
170 response->set_success(
true);
172 return absl::OkStatus();
175absl::Status CanvasAutomationServiceImpl::SelectTileRect(
176 const proto::SelectTileRectRequest* request,
177 proto::SelectTileRectResponse* response) {
178 auto* canvas = GetCanvas(request->canvas_id());
180 response->set_success(
false);
181 response->set_error(
"Canvas not found: " + request->canvas_id());
182 return absl::NotFoundError(response->error());
185 auto* api = canvas->GetAutomationAPI();
186 const auto& rect = request->rect();
187 api->SelectTileRect(rect.x1(), rect.y1(), rect.x2(), rect.y2());
189 auto selection = api->GetSelection();
190 response->set_success(
true);
191 response->set_tiles_selected(selection.selected_tiles.size());
193 return absl::OkStatus();
196absl::Status CanvasAutomationServiceImpl::GetSelection(
197 const proto::GetSelectionRequest* request,
198 proto::GetSelectionResponse* response) {
199 auto* canvas = GetCanvas(request->canvas_id());
201 return absl::NotFoundError(
"Canvas not found: " + request->canvas_id());
204 auto* api = canvas->GetAutomationAPI();
205 auto selection = api->GetSelection();
207 response->set_has_selection(selection.has_selection);
209 for (
const auto& tile : selection.selected_tiles) {
210 auto* coord = response->add_selected_tiles();
211 coord->set_x(
static_cast<int>(tile.x));
212 coord->set_y(
static_cast<int>(tile.y));
215 auto* start = response->mutable_selection_start();
216 start->set_x(
static_cast<int>(selection.selection_start.x));
217 start->set_y(
static_cast<int>(selection.selection_start.y));
219 auto* end = response->mutable_selection_end();
220 end->set_x(
static_cast<int>(selection.selection_end.x));
221 end->set_y(
static_cast<int>(selection.selection_end.y));
223 return absl::OkStatus();
226absl::Status CanvasAutomationServiceImpl::ClearSelection(
227 const proto::ClearSelectionRequest* request,
228 proto::ClearSelectionResponse* response) {
229 auto* canvas = GetCanvas(request->canvas_id());
231 response->set_success(
false);
232 return absl::NotFoundError(
"Canvas not found: " + request->canvas_id());
235 auto* api = canvas->GetAutomationAPI();
236 api->ClearSelection();
237 response->set_success(
true);
239 return absl::OkStatus();
246absl::Status CanvasAutomationServiceImpl::ScrollToTile(
247 const proto::ScrollToTileRequest* request,
248 proto::ScrollToTileResponse* response) {
249 auto* canvas = GetCanvas(request->canvas_id());
251 response->set_success(
false);
252 response->set_error(
"Canvas not found: " + request->canvas_id());
253 return absl::NotFoundError(response->error());
256 auto* api = canvas->GetAutomationAPI();
257 api->ScrollToTile(request->x(), request->y(), request->center());
258 response->set_success(
true);
260 return absl::OkStatus();
263absl::Status CanvasAutomationServiceImpl::CenterOn(
264 const proto::CenterOnRequest* request, proto::CenterOnResponse* response) {
265 auto* canvas = GetCanvas(request->canvas_id());
267 response->set_success(
false);
268 response->set_error(
"Canvas not found: " + request->canvas_id());
269 return absl::NotFoundError(response->error());
272 auto* api = canvas->GetAutomationAPI();
273 api->CenterOn(request->x(), request->y());
274 response->set_success(
true);
276 return absl::OkStatus();
279absl::Status CanvasAutomationServiceImpl::SetZoom(
280 const proto::SetZoomRequest* request, proto::SetZoomResponse* response) {
281 auto* canvas = GetCanvas(request->canvas_id());
283 response->set_success(
false);
284 response->set_error(
"Canvas not found: " + request->canvas_id());
285 return absl::NotFoundError(response->error());
288 auto* api = canvas->GetAutomationAPI();
289 api->SetZoom(request->zoom());
291 float actual_zoom = api->GetZoom();
292 response->set_success(
true);
293 response->set_actual_zoom(actual_zoom);
295 return absl::OkStatus();
298absl::Status CanvasAutomationServiceImpl::GetZoom(
299 const proto::GetZoomRequest* request, proto::GetZoomResponse* response) {
300 auto* canvas = GetCanvas(request->canvas_id());
302 return absl::NotFoundError(
"Canvas not found: " + request->canvas_id());
305 auto* api = canvas->GetAutomationAPI();
306 response->set_zoom(api->GetZoom());
308 return absl::OkStatus();
315absl::Status CanvasAutomationServiceImpl::GetDimensions(
316 const proto::GetDimensionsRequest* request,
317 proto::GetDimensionsResponse* response) {
318 auto* canvas = GetCanvas(request->canvas_id());
320 return absl::NotFoundError(
"Canvas not found: " + request->canvas_id());
323 auto* api = canvas->GetAutomationAPI();
324 auto dims = api->GetDimensions();
326 auto* proto_dims = response->mutable_dimensions();
327 proto_dims->set_width_tiles(dims.width_tiles);
328 proto_dims->set_height_tiles(dims.height_tiles);
329 proto_dims->set_tile_size(dims.tile_size);
331 return absl::OkStatus();
334absl::Status CanvasAutomationServiceImpl::GetVisibleRegion(
335 const proto::GetVisibleRegionRequest* request,
336 proto::GetVisibleRegionResponse* response) {
337 auto* canvas = GetCanvas(request->canvas_id());
339 return absl::NotFoundError(
"Canvas not found: " + request->canvas_id());
342 auto* api = canvas->GetAutomationAPI();
343 auto region = api->GetVisibleRegion();
345 auto* proto_region = response->mutable_region();
346 proto_region->set_min_x(region.min_x);
347 proto_region->set_min_y(region.min_y);
348 proto_region->set_max_x(region.max_x);
349 proto_region->set_max_y(region.max_y);
351 return absl::OkStatus();
354absl::Status CanvasAutomationServiceImpl::IsTileVisible(
355 const proto::IsTileVisibleRequest* request,
356 proto::IsTileVisibleResponse* response) {
357 auto* canvas = GetCanvas(request->canvas_id());
359 return absl::NotFoundError(
"Canvas not found: " + request->canvas_id());
362 auto* api = canvas->GetAutomationAPI();
363 response->set_is_visible(api->IsTileVisible(request->x(), request->y()));
365 return absl::OkStatus();
379class CanvasAutomationServiceGrpc final
380 :
public proto::CanvasAutomation::Service {
382 explicit CanvasAutomationServiceGrpc(CanvasAutomationServiceImpl* impl)
386 grpc::Status SetTile(grpc::ServerContext* context,
387 const proto::SetTileRequest* request,
388 proto::SetTileResponse* response)
override {
389 return ConvertStatus(impl_->SetTile(request, response));
392 grpc::Status GetTile(grpc::ServerContext* context,
393 const proto::GetTileRequest* request,
394 proto::GetTileResponse* response)
override {
395 return ConvertStatus(impl_->GetTile(request, response));
398 grpc::Status SetTiles(grpc::ServerContext* context,
399 const proto::SetTilesRequest* request,
400 proto::SetTilesResponse* response)
override {
401 return ConvertStatus(impl_->SetTiles(request, response));
405 grpc::Status SelectTile(grpc::ServerContext* context,
406 const proto::SelectTileRequest* request,
407 proto::SelectTileResponse* response)
override {
408 return ConvertStatus(impl_->SelectTile(request, response));
411 grpc::Status SelectTileRect(
412 grpc::ServerContext* context,
const proto::SelectTileRectRequest* request,
413 proto::SelectTileRectResponse* response)
override {
414 return ConvertStatus(impl_->SelectTileRect(request, response));
417 grpc::Status GetSelection(grpc::ServerContext* context,
418 const proto::GetSelectionRequest* request,
419 proto::GetSelectionResponse* response)
override {
420 return ConvertStatus(impl_->GetSelection(request, response));
423 grpc::Status ClearSelection(
424 grpc::ServerContext* context,
const proto::ClearSelectionRequest* request,
425 proto::ClearSelectionResponse* response)
override {
426 return ConvertStatus(impl_->ClearSelection(request, response));
430 grpc::Status ScrollToTile(grpc::ServerContext* context,
431 const proto::ScrollToTileRequest* request,
432 proto::ScrollToTileResponse* response)
override {
433 return ConvertStatus(impl_->ScrollToTile(request, response));
436 grpc::Status CenterOn(grpc::ServerContext* context,
437 const proto::CenterOnRequest* request,
438 proto::CenterOnResponse* response)
override {
439 return ConvertStatus(impl_->CenterOn(request, response));
442 grpc::Status SetZoom(grpc::ServerContext* context,
443 const proto::SetZoomRequest* request,
444 proto::SetZoomResponse* response)
override {
445 return ConvertStatus(impl_->SetZoom(request, response));
448 grpc::Status GetZoom(grpc::ServerContext* context,
449 const proto::GetZoomRequest* request,
450 proto::GetZoomResponse* response)
override {
451 return ConvertStatus(impl_->GetZoom(request, response));
455 grpc::Status GetDimensions(grpc::ServerContext* context,
456 const proto::GetDimensionsRequest* request,
457 proto::GetDimensionsResponse* response)
override {
458 return ConvertStatus(impl_->GetDimensions(request, response));
461 grpc::Status GetVisibleRegion(
462 grpc::ServerContext* context,
463 const proto::GetVisibleRegionRequest* request,
464 proto::GetVisibleRegionResponse* response)
override {
465 return ConvertStatus(impl_->GetVisibleRegion(request, response));
468 grpc::Status IsTileVisible(grpc::ServerContext* context,
469 const proto::IsTileVisibleRequest* request,
470 proto::IsTileVisibleResponse* response)
override {
471 return ConvertStatus(impl_->IsTileVisible(request, response));
475 CanvasAutomationServiceImpl* impl_;
480std::unique_ptr<grpc::Service> CreateCanvasAutomationServiceGrpc(
481 CanvasAutomationServiceImpl* impl) {
482 return std::make_unique<CanvasAutomationServiceGrpc>(impl);