5#include <grpcpp/grpcpp.h>
6#include "protos/canvas_automation.pb.h"
7#include "protos/canvas_automation.grpc.pb.h"
16grpc::Status ConvertStatus(
const absl::Status& status) {
18 return grpc::Status::OK;
21 grpc::StatusCode code;
22 switch (status.code()) {
23 case absl::StatusCode::kNotFound:
24 code = grpc::StatusCode::NOT_FOUND;
26 case absl::StatusCode::kInvalidArgument:
27 code = grpc::StatusCode::INVALID_ARGUMENT;
29 case absl::StatusCode::kFailedPrecondition:
30 code = grpc::StatusCode::FAILED_PRECONDITION;
32 case absl::StatusCode::kOutOfRange:
33 code = grpc::StatusCode::OUT_OF_RANGE;
35 case absl::StatusCode::kUnimplemented:
36 code = grpc::StatusCode::UNIMPLEMENTED;
38 case absl::StatusCode::kInternal:
39 code = grpc::StatusCode::INTERNAL;
41 case absl::StatusCode::kUnavailable:
42 code = grpc::StatusCode::UNAVAILABLE;
45 code = grpc::StatusCode::UNKNOWN;
49 return grpc::Status(code, std::string(status.message()));
54void CanvasAutomationServiceImpl::RegisterCanvas(
const std::string& canvas_id,
55 gui::Canvas* canvas) {
56 canvases_[canvas_id] = canvas;
59void CanvasAutomationServiceImpl::RegisterOverworldEditor(
60 const std::string& canvas_id, editor::OverworldEditor* editor) {
61 overworld_editors_[canvas_id] = editor;
64gui::Canvas* CanvasAutomationServiceImpl::GetCanvas(
const std::string& canvas_id) {
65 auto it = canvases_.find(canvas_id);
66 if (it != canvases_.end()) {
72editor::OverworldEditor* CanvasAutomationServiceImpl::GetOverworldEditor(
73 const std::string& canvas_id) {
74 auto it = overworld_editors_.find(canvas_id);
75 if (it != overworld_editors_.end()) {
85absl::Status CanvasAutomationServiceImpl::SetTile(
86 const proto::SetTileRequest* request, proto::SetTileResponse* response) {
88 auto* canvas = GetCanvas(request->canvas_id());
90 response->set_success(
false);
91 response->set_error(
"Canvas not found: " + request->canvas_id());
92 return absl::NotFoundError(response->error());
95 auto* api = canvas->GetAutomationAPI();
96 bool success = api->SetTileAt(request->x(), request->y(), request->tile_id());
98 response->set_success(success);
100 response->set_error(
"Failed to set tile - out of bounds or callback failed");
103 return absl::OkStatus();
106absl::Status CanvasAutomationServiceImpl::GetTile(
107 const proto::GetTileRequest* request, proto::GetTileResponse* response) {
109 auto* canvas = GetCanvas(request->canvas_id());
111 response->set_success(
false);
112 response->set_error(
"Canvas not found: " + request->canvas_id());
113 return absl::NotFoundError(response->error());
116 auto* api = canvas->GetAutomationAPI();
117 int tile_id = api->GetTileAt(request->x(), request->y());
120 response->set_tile_id(tile_id);
121 response->set_success(
true);
123 response->set_success(
false);
124 response->set_error(
"Tile not found - out of bounds or no callback set");
127 return absl::OkStatus();
130absl::Status CanvasAutomationServiceImpl::SetTiles(
131 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, 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) {
179 auto* canvas = GetCanvas(request->canvas_id());
181 response->set_success(
false);
182 response->set_error(
"Canvas not found: " + request->canvas_id());
183 return absl::NotFoundError(response->error());
186 auto* api = canvas->GetAutomationAPI();
187 const auto& rect = request->rect();
188 api->SelectTileRect(rect.x1(), rect.y1(), rect.x2(), rect.y2());
190 auto selection = api->GetSelection();
191 response->set_success(
true);
192 response->set_tiles_selected(selection.selected_tiles.size());
194 return absl::OkStatus();
197absl::Status CanvasAutomationServiceImpl::GetSelection(
198 const proto::GetSelectionRequest* request,
199 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) {
232 auto* canvas = GetCanvas(request->canvas_id());
234 response->set_success(
false);
235 return absl::NotFoundError(
"Canvas not found: " + request->canvas_id());
238 auto* api = canvas->GetAutomationAPI();
239 api->ClearSelection();
240 response->set_success(
true);
242 return absl::OkStatus();
249absl::Status CanvasAutomationServiceImpl::ScrollToTile(
250 const proto::ScrollToTileRequest* request,
251 proto::ScrollToTileResponse* response) {
253 auto* canvas = GetCanvas(request->canvas_id());
255 response->set_success(
false);
256 response->set_error(
"Canvas not found: " + request->canvas_id());
257 return absl::NotFoundError(response->error());
260 auto* api = canvas->GetAutomationAPI();
261 api->ScrollToTile(request->x(), request->y(), request->center());
262 response->set_success(
true);
264 return absl::OkStatus();
267absl::Status CanvasAutomationServiceImpl::CenterOn(
268 const proto::CenterOnRequest* request, proto::CenterOnResponse* response) {
270 auto* canvas = GetCanvas(request->canvas_id());
272 response->set_success(
false);
273 response->set_error(
"Canvas not found: " + request->canvas_id());
274 return absl::NotFoundError(response->error());
277 auto* api = canvas->GetAutomationAPI();
278 api->CenterOn(request->x(), request->y());
279 response->set_success(
true);
281 return absl::OkStatus();
284absl::Status CanvasAutomationServiceImpl::SetZoom(
285 const proto::SetZoomRequest* request, proto::SetZoomResponse* response) {
287 auto* canvas = GetCanvas(request->canvas_id());
289 response->set_success(
false);
290 response->set_error(
"Canvas not found: " + request->canvas_id());
291 return absl::NotFoundError(response->error());
294 auto* api = canvas->GetAutomationAPI();
295 api->SetZoom(request->zoom());
297 float actual_zoom = api->GetZoom();
298 response->set_success(
true);
299 response->set_actual_zoom(actual_zoom);
301 return absl::OkStatus();
304absl::Status CanvasAutomationServiceImpl::GetZoom(
305 const proto::GetZoomRequest* request, proto::GetZoomResponse* response) {
307 auto* canvas = GetCanvas(request->canvas_id());
309 return absl::NotFoundError(
"Canvas not found: " + request->canvas_id());
312 auto* api = canvas->GetAutomationAPI();
313 response->set_zoom(api->GetZoom());
315 return absl::OkStatus();
322absl::Status CanvasAutomationServiceImpl::GetDimensions(
323 const proto::GetDimensionsRequest* request,
324 proto::GetDimensionsResponse* response) {
326 auto* canvas = GetCanvas(request->canvas_id());
328 return absl::NotFoundError(
"Canvas not found: " + request->canvas_id());
331 auto* api = canvas->GetAutomationAPI();
332 auto dims = api->GetDimensions();
334 auto* proto_dims = response->mutable_dimensions();
335 proto_dims->set_width_tiles(dims.width_tiles);
336 proto_dims->set_height_tiles(dims.height_tiles);
337 proto_dims->set_tile_size(dims.tile_size);
339 return absl::OkStatus();
342absl::Status CanvasAutomationServiceImpl::GetVisibleRegion(
343 const proto::GetVisibleRegionRequest* request,
344 proto::GetVisibleRegionResponse* response) {
346 auto* canvas = GetCanvas(request->canvas_id());
348 return absl::NotFoundError(
"Canvas not found: " + request->canvas_id());
351 auto* api = canvas->GetAutomationAPI();
352 auto region = api->GetVisibleRegion();
354 auto* proto_region = response->mutable_region();
355 proto_region->set_min_x(region.min_x);
356 proto_region->set_min_y(region.min_y);
357 proto_region->set_max_x(region.max_x);
358 proto_region->set_max_y(region.max_y);
360 return absl::OkStatus();
363absl::Status CanvasAutomationServiceImpl::IsTileVisible(
364 const proto::IsTileVisibleRequest* request,
365 proto::IsTileVisibleResponse* response) {
367 auto* canvas = GetCanvas(request->canvas_id());
369 return absl::NotFoundError(
"Canvas not found: " + request->canvas_id());
372 auto* api = canvas->GetAutomationAPI();
373 response->set_is_visible(api->IsTileVisible(request->x(), request->y()));
375 return absl::OkStatus();
389class CanvasAutomationServiceGrpc final :
public proto::CanvasAutomation::Service {
391 explicit CanvasAutomationServiceGrpc(CanvasAutomationServiceImpl* impl)
395 grpc::Status SetTile(grpc::ServerContext* context,
396 const proto::SetTileRequest* request,
397 proto::SetTileResponse* response)
override {
398 return ConvertStatus(impl_->SetTile(request, response));
401 grpc::Status GetTile(grpc::ServerContext* context,
402 const proto::GetTileRequest* request,
403 proto::GetTileResponse* response)
override {
404 return ConvertStatus(impl_->GetTile(request, response));
407 grpc::Status SetTiles(grpc::ServerContext* context,
408 const proto::SetTilesRequest* request,
409 proto::SetTilesResponse* response)
override {
410 return ConvertStatus(impl_->SetTiles(request, response));
414 grpc::Status SelectTile(grpc::ServerContext* context,
415 const proto::SelectTileRequest* request,
416 proto::SelectTileResponse* response)
override {
417 return ConvertStatus(impl_->SelectTile(request, response));
420 grpc::Status SelectTileRect(grpc::ServerContext* context,
421 const proto::SelectTileRectRequest* request,
422 proto::SelectTileRectResponse* response)
override {
423 return ConvertStatus(impl_->SelectTileRect(request, response));
426 grpc::Status GetSelection(grpc::ServerContext* context,
427 const proto::GetSelectionRequest* request,
428 proto::GetSelectionResponse* response)
override {
429 return ConvertStatus(impl_->GetSelection(request, response));
432 grpc::Status ClearSelection(grpc::ServerContext* context,
433 const proto::ClearSelectionRequest* request,
434 proto::ClearSelectionResponse* response)
override {
435 return ConvertStatus(impl_->ClearSelection(request, response));
439 grpc::Status ScrollToTile(grpc::ServerContext* context,
440 const proto::ScrollToTileRequest* request,
441 proto::ScrollToTileResponse* response)
override {
442 return ConvertStatus(impl_->ScrollToTile(request, response));
445 grpc::Status CenterOn(grpc::ServerContext* context,
446 const proto::CenterOnRequest* request,
447 proto::CenterOnResponse* response)
override {
448 return ConvertStatus(impl_->CenterOn(request, response));
451 grpc::Status SetZoom(grpc::ServerContext* context,
452 const proto::SetZoomRequest* request,
453 proto::SetZoomResponse* response)
override {
454 return ConvertStatus(impl_->SetZoom(request, response));
457 grpc::Status GetZoom(grpc::ServerContext* context,
458 const proto::GetZoomRequest* request,
459 proto::GetZoomResponse* response)
override {
460 return ConvertStatus(impl_->GetZoom(request, response));
464 grpc::Status GetDimensions(grpc::ServerContext* context,
465 const proto::GetDimensionsRequest* request,
466 proto::GetDimensionsResponse* response)
override {
467 return ConvertStatus(impl_->GetDimensions(request, response));
470 grpc::Status GetVisibleRegion(grpc::ServerContext* context,
471 const proto::GetVisibleRegionRequest* request,
472 proto::GetVisibleRegionResponse* response)
override {
473 return ConvertStatus(impl_->GetVisibleRegion(request, response));
476 grpc::Status IsTileVisible(grpc::ServerContext* context,
477 const proto::IsTileVisibleRequest* request,
478 proto::IsTileVisibleResponse* response)
override {
479 return ConvertStatus(impl_->IsTileVisible(request, response));
483 CanvasAutomationServiceImpl* impl_;
488std::unique_ptr<grpc::Service> CreateCanvasAutomationServiceGrpc(
489 CanvasAutomationServiceImpl* impl) {
490 return std::make_unique<CanvasAutomationServiceGrpc>(impl);
Main namespace for the application.