7#include <grpcpp/grpcpp.h>
11#include "protos/canvas_automation.grpc.pb.h"
12#include "protos/canvas_automation.pb.h"
19grpc::Status ConvertStatus(
const absl::Status& status) {
21 return grpc::Status::OK;
24 grpc::StatusCode code;
25 switch (status.code()) {
26 case absl::StatusCode::kNotFound:
27 code = grpc::StatusCode::NOT_FOUND;
29 case absl::StatusCode::kInvalidArgument:
30 code = grpc::StatusCode::INVALID_ARGUMENT;
32 case absl::StatusCode::kFailedPrecondition:
33 code = grpc::StatusCode::FAILED_PRECONDITION;
35 case absl::StatusCode::kOutOfRange:
36 code = grpc::StatusCode::OUT_OF_RANGE;
38 case absl::StatusCode::kUnimplemented:
39 code = grpc::StatusCode::UNIMPLEMENTED;
41 case absl::StatusCode::kInternal:
42 code = grpc::StatusCode::INTERNAL;
44 case absl::StatusCode::kUnavailable:
45 code = grpc::StatusCode::UNAVAILABLE;
48 code = grpc::StatusCode::UNKNOWN;
52 return grpc::Status(code, std::string(status.message().data(), status.message().size()));
57void CanvasAutomationServiceImpl::RegisterCanvas(
const std::string& canvas_id,
58 gui::Canvas* canvas) {
59 canvases_[canvas_id] = canvas;
62void CanvasAutomationServiceImpl::RegisterOverworldEditor(
63 const std::string& canvas_id, editor::OverworldEditor* editor) {
64 overworld_editors_[canvas_id] = editor;
67gui::Canvas* CanvasAutomationServiceImpl::GetCanvas(
68 const std::string& canvas_id) {
69 auto it = canvases_.find(canvas_id);
70 if (it != canvases_.end()) {
76editor::OverworldEditor* CanvasAutomationServiceImpl::GetOverworldEditor(
77 const std::string& canvas_id) {
78 auto it = overworld_editors_.find(canvas_id);
79 if (it != overworld_editors_.end()) {
89absl::Status CanvasAutomationServiceImpl::SetTile(
90 const proto::SetTileRequest* request, proto::SetTileResponse* response) {
91 auto* canvas = GetCanvas(request->canvas_id());
93 response->set_success(
false);
94 response->set_error(
"Canvas not found: " + request->canvas_id());
95 return absl::NotFoundError(response->error());
98 auto* api = canvas->GetAutomationAPI();
99 bool success = api->SetTileAt(request->x(), request->y(), request->tile_id());
101 response->set_success(success);
104 "Failed to set tile - out of bounds or callback failed");
107 return absl::OkStatus();
110absl::Status CanvasAutomationServiceImpl::GetTile(
111 const proto::GetTileRequest* request, proto::GetTileResponse* response) {
112 auto* canvas = GetCanvas(request->canvas_id());
114 response->set_success(
false);
115 response->set_error(
"Canvas not found: " + request->canvas_id());
116 return absl::NotFoundError(response->error());
119 auto* api = canvas->GetAutomationAPI();
120 int tile_id = api->GetTileAt(request->x(), request->y());
123 response->set_tile_id(tile_id);
124 response->set_success(
true);
126 response->set_success(
false);
127 response->set_error(
"Tile not found - out of bounds or no callback set");
130 return absl::OkStatus();
133absl::Status CanvasAutomationServiceImpl::SetTiles(
134 const proto::SetTilesRequest* request, proto::SetTilesResponse* response) {
135 auto* canvas = GetCanvas(request->canvas_id());
137 response->set_success(
false);
138 response->set_error(
"Canvas not found: " + request->canvas_id());
139 return absl::NotFoundError(response->error());
142 auto* api = canvas->GetAutomationAPI();
144 std::vector<std::tuple<int, int, int>> tiles;
145 for (
const auto& tile : request->tiles()) {
146 tiles.push_back({tile.x(), tile.y(), tile.tile_id()});
149 bool success = api->SetTiles(tiles);
150 response->set_success(success);
151 response->set_tiles_painted(tiles.size());
153 return absl::OkStatus();
160absl::Status CanvasAutomationServiceImpl::SelectTile(
161 const proto::SelectTileRequest* request,
162 proto::SelectTileResponse* response) {
163 auto* canvas = GetCanvas(request->canvas_id());
165 response->set_success(
false);
166 response->set_error(
"Canvas not found: " + request->canvas_id());
167 return absl::NotFoundError(response->error());
170 auto* api = canvas->GetAutomationAPI();
171 api->SelectTile(request->x(), request->y());
172 response->set_success(
true);
174 return absl::OkStatus();
177absl::Status CanvasAutomationServiceImpl::SelectTileRect(
178 const proto::SelectTileRectRequest* request,
179 proto::SelectTileRectResponse* response) {
180 auto* canvas = GetCanvas(request->canvas_id());
182 response->set_success(
false);
183 response->set_error(
"Canvas not found: " + request->canvas_id());
184 return absl::NotFoundError(response->error());
187 auto* api = canvas->GetAutomationAPI();
188 const auto& rect = request->rect();
189 api->SelectTileRect(rect.x1(), rect.y1(), rect.x2(), rect.y2());
191 auto selection = api->GetSelection();
192 response->set_success(
true);
193 response->set_tiles_selected(selection.selected_tiles.size());
195 return absl::OkStatus();
198absl::Status CanvasAutomationServiceImpl::GetSelection(
199 const proto::GetSelectionRequest* request,
200 proto::GetSelectionResponse* response) {
201 auto* canvas = GetCanvas(request->canvas_id());
203 return absl::NotFoundError(
"Canvas not found: " + request->canvas_id());
206 auto* api = canvas->GetAutomationAPI();
207 auto selection = api->GetSelection();
209 response->set_has_selection(selection.has_selection);
211 for (
const auto& tile : selection.selected_tiles) {
212 auto* coord = response->add_selected_tiles();
213 coord->set_x(
static_cast<int>(tile.x));
214 coord->set_y(
static_cast<int>(tile.y));
217 auto* start = response->mutable_selection_start();
218 start->set_x(
static_cast<int>(selection.selection_start.x));
219 start->set_y(
static_cast<int>(selection.selection_start.y));
221 auto* end = response->mutable_selection_end();
222 end->set_x(
static_cast<int>(selection.selection_end.x));
223 end->set_y(
static_cast<int>(selection.selection_end.y));
225 return absl::OkStatus();
228absl::Status CanvasAutomationServiceImpl::ClearSelection(
229 const proto::ClearSelectionRequest* request,
230 proto::ClearSelectionResponse* response) {
231 auto* canvas = GetCanvas(request->canvas_id());
233 response->set_success(
false);
234 return absl::NotFoundError(
"Canvas not found: " + request->canvas_id());
237 auto* api = canvas->GetAutomationAPI();
238 api->ClearSelection();
239 response->set_success(
true);
241 return absl::OkStatus();
248absl::Status CanvasAutomationServiceImpl::ScrollToTile(
249 const proto::ScrollToTileRequest* request,
250 proto::ScrollToTileResponse* response) {
251 auto* canvas = GetCanvas(request->canvas_id());
253 response->set_success(
false);
254 response->set_error(
"Canvas not found: " + request->canvas_id());
255 return absl::NotFoundError(response->error());
258 auto* api = canvas->GetAutomationAPI();
259 api->ScrollToTile(request->x(), request->y(), request->center());
260 response->set_success(
true);
262 return absl::OkStatus();
265absl::Status CanvasAutomationServiceImpl::CenterOn(
266 const proto::CenterOnRequest* request, proto::CenterOnResponse* response) {
267 auto* canvas = GetCanvas(request->canvas_id());
269 response->set_success(
false);
270 response->set_error(
"Canvas not found: " + request->canvas_id());
271 return absl::NotFoundError(response->error());
274 auto* api = canvas->GetAutomationAPI();
275 api->CenterOn(request->x(), request->y());
276 response->set_success(
true);
278 return absl::OkStatus();
281absl::Status CanvasAutomationServiceImpl::SetZoom(
282 const proto::SetZoomRequest* request, proto::SetZoomResponse* response) {
283 auto* canvas = GetCanvas(request->canvas_id());
285 response->set_success(
false);
286 response->set_error(
"Canvas not found: " + request->canvas_id());
287 return absl::NotFoundError(response->error());
290 auto* api = canvas->GetAutomationAPI();
291 api->SetZoom(request->zoom());
293 float actual_zoom = api->GetZoom();
294 response->set_success(
true);
295 response->set_actual_zoom(actual_zoom);
297 return absl::OkStatus();
300absl::Status CanvasAutomationServiceImpl::GetZoom(
301 const proto::GetZoomRequest* request, proto::GetZoomResponse* response) {
302 auto* canvas = GetCanvas(request->canvas_id());
304 return absl::NotFoundError(
"Canvas not found: " + request->canvas_id());
307 auto* api = canvas->GetAutomationAPI();
308 response->set_zoom(api->GetZoom());
310 return absl::OkStatus();
317absl::Status CanvasAutomationServiceImpl::GetDimensions(
318 const proto::GetDimensionsRequest* request,
319 proto::GetDimensionsResponse* response) {
320 auto* canvas = GetCanvas(request->canvas_id());
322 return absl::NotFoundError(
"Canvas not found: " + request->canvas_id());
325 auto* api = canvas->GetAutomationAPI();
326 auto dims = api->GetDimensions();
328 auto* proto_dims = response->mutable_dimensions();
329 proto_dims->set_width_tiles(dims.width_tiles);
330 proto_dims->set_height_tiles(dims.height_tiles);
331 proto_dims->set_tile_size(dims.tile_size);
333 return absl::OkStatus();
336absl::Status CanvasAutomationServiceImpl::GetVisibleRegion(
337 const proto::GetVisibleRegionRequest* request,
338 proto::GetVisibleRegionResponse* response) {
339 auto* canvas = GetCanvas(request->canvas_id());
341 return absl::NotFoundError(
"Canvas not found: " + request->canvas_id());
344 auto* api = canvas->GetAutomationAPI();
345 auto region = api->GetVisibleRegion();
347 auto* proto_region = response->mutable_region();
348 proto_region->set_min_x(region.min_x);
349 proto_region->set_min_y(region.min_y);
350 proto_region->set_max_x(region.max_x);
351 proto_region->set_max_y(region.max_y);
353 return absl::OkStatus();
356absl::Status CanvasAutomationServiceImpl::IsTileVisible(
357 const proto::IsTileVisibleRequest* request,
358 proto::IsTileVisibleResponse* response) {
359 auto* canvas = GetCanvas(request->canvas_id());
361 return absl::NotFoundError(
"Canvas not found: " + request->canvas_id());
364 auto* api = canvas->GetAutomationAPI();
365 response->set_is_visible(api->IsTileVisible(request->x(), request->y()));
367 return absl::OkStatus();
381class CanvasAutomationServiceGrpc final
382 :
public proto::CanvasAutomation::Service {
384 explicit CanvasAutomationServiceGrpc(CanvasAutomationServiceImpl* impl)
388 grpc::Status SetTile(grpc::ServerContext* context,
389 const proto::SetTileRequest* request,
390 proto::SetTileResponse* response)
override {
391 return ConvertStatus(impl_->SetTile(request, response));
394 grpc::Status GetTile(grpc::ServerContext* context,
395 const proto::GetTileRequest* request,
396 proto::GetTileResponse* response)
override {
397 return ConvertStatus(impl_->GetTile(request, response));
400 grpc::Status SetTiles(grpc::ServerContext* context,
401 const proto::SetTilesRequest* request,
402 proto::SetTilesResponse* response)
override {
403 return ConvertStatus(impl_->SetTiles(request, response));
407 grpc::Status SelectTile(grpc::ServerContext* context,
408 const proto::SelectTileRequest* request,
409 proto::SelectTileResponse* response)
override {
410 return ConvertStatus(impl_->SelectTile(request, response));
413 grpc::Status SelectTileRect(
414 grpc::ServerContext* context,
const proto::SelectTileRectRequest* request,
415 proto::SelectTileRectResponse* response)
override {
416 return ConvertStatus(impl_->SelectTileRect(request, response));
419 grpc::Status GetSelection(grpc::ServerContext* context,
420 const proto::GetSelectionRequest* request,
421 proto::GetSelectionResponse* response)
override {
422 return ConvertStatus(impl_->GetSelection(request, response));
425 grpc::Status ClearSelection(
426 grpc::ServerContext* context,
const proto::ClearSelectionRequest* request,
427 proto::ClearSelectionResponse* response)
override {
428 return ConvertStatus(impl_->ClearSelection(request, response));
432 grpc::Status ScrollToTile(grpc::ServerContext* context,
433 const proto::ScrollToTileRequest* request,
434 proto::ScrollToTileResponse* response)
override {
435 return ConvertStatus(impl_->ScrollToTile(request, response));
438 grpc::Status CenterOn(grpc::ServerContext* context,
439 const proto::CenterOnRequest* request,
440 proto::CenterOnResponse* response)
override {
441 return ConvertStatus(impl_->CenterOn(request, response));
444 grpc::Status SetZoom(grpc::ServerContext* context,
445 const proto::SetZoomRequest* request,
446 proto::SetZoomResponse* response)
override {
447 return ConvertStatus(impl_->SetZoom(request, response));
450 grpc::Status GetZoom(grpc::ServerContext* context,
451 const proto::GetZoomRequest* request,
452 proto::GetZoomResponse* response)
override {
453 return ConvertStatus(impl_->GetZoom(request, response));
457 grpc::Status GetDimensions(grpc::ServerContext* context,
458 const proto::GetDimensionsRequest* request,
459 proto::GetDimensionsResponse* response)
override {
460 return ConvertStatus(impl_->GetDimensions(request, response));
463 grpc::Status GetVisibleRegion(
464 grpc::ServerContext* context,
465 const proto::GetVisibleRegionRequest* request,
466 proto::GetVisibleRegionResponse* response)
override {
467 return ConvertStatus(impl_->GetVisibleRegion(request, response));
470 grpc::Status IsTileVisible(grpc::ServerContext* context,
471 const proto::IsTileVisibleRequest* request,
472 proto::IsTileVisibleResponse* response)
override {
473 return ConvertStatus(impl_->IsTileVisible(request, response));
477 CanvasAutomationServiceImpl* impl_;
482std::unique_ptr<grpc::Service> CreateCanvasAutomationServiceGrpc(
483 CanvasAutomationServiceImpl* impl) {
484 return std::make_unique<CanvasAutomationServiceGrpc>(impl);