7#include <grpcpp/grpcpp.h>
12#include "absl/strings/str_format.h"
17#include "protos/canvas_automation.grpc.pb.h"
24YazeGRPCServer::YazeGRPCServer() : is_running_(false) {}
26YazeGRPCServer::~YazeGRPCServer() {
30absl::Status YazeGRPCServer::Initialize(
31 int port, emu::IEmulator* emulator, RomGetter rom_getter,
32 RomLoader rom_loader, test::TestManager* test_manager,
33 net::RomVersionManager* version_mgr,
34 net::ProposalApprovalManager* approval_mgr,
35 CanvasAutomationServiceImpl* canvas_service) {
37 return absl::FailedPreconditionError(
"Server is already running");
43 if (config_.enable_test_harness && test_manager) {
44 test_harness_service_ =
45 std::make_unique<test::ImGuiTestHarnessServiceImpl>(test_manager);
46 std::cout <<
"✓ ImGuiTestHarness service initialized\n";
50 if (config_.enable_emulator_service && emulator) {
51 emulator_service_ = std::make_unique<net::EmulatorServiceImpl>(
52 emulator, rom_getter, rom_loader);
53 std::cout <<
"✓ Emulator service initialized\n";
54 }
else if (config_.enable_emulator_service) {
55 std::cout <<
"⚠ Emulator service requested but no emulator provided\n";
59 if (config_.enable_rom_service && rom_getter) {
60 rom_service_ = std::make_unique<net::RomServiceImpl>(
61 rom_getter, version_mgr, approval_mgr);
64 net::RomServiceImpl::Config rom_config;
65 rom_config.require_approval_for_writes =
66 config_.require_approval_for_rom_writes;
67 rom_service_->SetConfig(rom_config);
69 std::cout <<
"✓ ROM service initialized\n";
70 }
else if (config_.enable_rom_service) {
71 std::cout <<
"⚠ ROM service requested but no ROM provided\n";
75 if (config_.enable_canvas_automation && canvas_service) {
77 canvas_service_ = canvas_service;
78 std::cout <<
"✓ Canvas Automation service initialized\n";
79 }
else if (config_.enable_canvas_automation) {
80 std::cout <<
"⚠ Canvas Automation requested but no service provided\n";
83 if (!test_harness_service_ && !rom_service_ && !canvas_service_ &&
85 return absl::InvalidArgumentError(
86 "At least one service must be enabled and initialized");
89 return absl::OkStatus();
92void YazeGRPCServer::SetEmulatorScreenshotCapturer(
93 std::function<absl::StatusOr<test::ScreenshotArtifact>()> capturer) {
94 if (emulator_service_) {
95 emulator_service_->SetScreenshotCapturer(std::move(capturer));
99absl::Status YazeGRPCServer::Start() {
100 auto status = BuildServer();
105 std::cout <<
"✓ YAZE gRPC automation server listening on "
106 << config_.bind_address <<
":" << config_.port <<
"\n";
108 if (test_harness_service_) {
109 std::cout <<
" ✓ ImGuiTestHarness available\n";
111 if (emulator_service_) {
112 std::cout <<
" ✓ EmulatorService available\n";
115 std::cout <<
" ✓ ROM service available\n";
117 if (canvas_service_) {
118 std::cout <<
" ✓ Canvas Automation available\n";
121 std::cout <<
"\nServer is ready to accept requests...\n";
127 return absl::OkStatus();
130absl::Status YazeGRPCServer::StartAsync() {
131 auto status = BuildServer();
136 std::cout <<
"✓ Unified gRPC server started on port " << config_.port <<
"\n";
139 return absl::OkStatus();
142absl::Status YazeGRPCServer::AddService(
143 std::unique_ptr<grpc::Service> service) {
145 return absl::InvalidArgumentError(
"Service is null");
148 return absl::FailedPreconditionError(
149 "Cannot add services after the server has started");
151 extra_services_.push_back(std::move(service));
152 return absl::OkStatus();
155void YazeGRPCServer::Shutdown() {
157 std::cout <<
"⏹ Shutting down unified gRPC server...\n";
164 ReleaseRegisteredServices();
165 std::cout <<
"✓ Server stopped\n";
169bool YazeGRPCServer::IsRunning()
const {
173absl::Status YazeGRPCServer::BuildServer() {
175 return absl::FailedPreconditionError(
"Server already running");
178 std::string server_address =
179 absl::StrFormat(
"%s:%d", config_.bind_address, config_.port);
181 grpc::ServerBuilder builder;
183 int selected_port = 0;
184 builder.AddListeningPort(server_address, grpc::InsecureServerCredentials(),
188 if (test_harness_service_) {
190 test_harness_grpc_wrapper_ =
191 test::CreateImGuiTestHarnessServiceGrpc(test_harness_service_.get());
192 std::cout <<
" Registering ImGuiTestHarness service...\n";
193 builder.RegisterService(test_harness_grpc_wrapper_.get());
196 if (emulator_service_) {
197 std::cout <<
" Registering EmulatorService...\n";
198 builder.RegisterService(emulator_service_.get());
202 std::cout <<
" Registering ROM service...\n";
203 builder.RegisterService(rom_service_.get());
206 if (canvas_service_) {
207 std::cout <<
" Registering Canvas Automation service...\n";
209 canvas_grpc_service_ = CreateCanvasAutomationServiceGrpc(canvas_service_);
210 builder.RegisterService(canvas_grpc_service_.get());
213 for (
auto& service : extra_services_) {
214 builder.RegisterService(service.get());
218 server_ = builder.BuildAndStart();
221 return absl::InternalError(
222 absl::StrFormat(
"Failed to start server on %s", server_address));
226 if (selected_port > 0) {
227 config_.port = selected_port;
230 return absl::OkStatus();
233void YazeGRPCServer::ReleaseRegisteredServices() {
234 canvas_grpc_service_.reset();
235 test_harness_grpc_wrapper_.reset();
236 extra_services_.clear();
237 emulator_service_.reset();
238 rom_service_.reset();
239 test_harness_service_.reset();
240 canvas_service_ =
nullptr;