yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
unified_grpc_server.cc
Go to the documentation of this file.
2
3#ifdef YAZE_WITH_GRPC
4
6
7#include <grpcpp/grpcpp.h>
8
9#include <iostream>
10#include <thread>
11
12#include "absl/strings/str_format.h"
16#include "protos/canvas_automation.grpc.pb.h"
17#include "rom/rom.h"
18
20
21namespace yaze {
22
23YazeGRPCServer::YazeGRPCServer() : is_running_(false) {}
24
25YazeGRPCServer::~YazeGRPCServer() {
26 Shutdown();
27}
28
29absl::Status YazeGRPCServer::Initialize(
30 int port, test::TestManager* test_manager, RomGetter rom_getter,
31 net::RomVersionManager* version_mgr,
32 net::ProposalApprovalManager* approval_mgr,
33 CanvasAutomationServiceImpl* canvas_service) {
34 if (is_running_) {
35 return absl::FailedPreconditionError("Server is already running");
36 }
37
38 config_.port = port;
39
40 // Create ImGuiTestHarness service if test_manager provided
41 if (config_.enable_test_harness && test_manager) {
42 test_harness_service_ =
43 std::make_unique<test::ImGuiTestHarnessServiceImpl>(test_manager);
44 std::cout << "✓ ImGuiTestHarness service initialized\n";
45 }
46
47 // Create ROM service if rom_getter provided
48 if (config_.enable_rom_service && rom_getter) {
49 rom_service_ = std::make_unique<net::RomServiceImpl>(
50 rom_getter, version_mgr, approval_mgr);
51
52 // Configure ROM service
53 net::RomServiceImpl::Config rom_config;
54 rom_config.require_approval_for_writes =
55 config_.require_approval_for_rom_writes;
56 rom_service_->SetConfig(rom_config);
57
58 std::cout << "✓ ROM service initialized\n";
59 } else if (config_.enable_rom_service) {
60 std::cout << "⚠ ROM service requested but no ROM provided\n";
61 }
62
63 // Create Canvas Automation service if canvas_service provided
64 if (config_.enable_canvas_automation && canvas_service) {
65 // Store the provided service (not owned by us)
66 canvas_service_ = canvas_service;
67 std::cout << "✓ Canvas Automation service initialized\n";
68 } else if (config_.enable_canvas_automation) {
69 std::cout << "⚠ Canvas Automation requested but no service provided\n";
70 }
71
72 if (!test_harness_service_ && !rom_service_ && !canvas_service_) {
73 return absl::InvalidArgumentError(
74 "At least one service must be enabled and initialized");
75 }
76
77 return absl::OkStatus();
78}
79
80absl::Status YazeGRPCServer::Start() {
81 auto status = BuildServer();
82 if (!status.ok()) {
83 return status;
84 }
85
86 std::cout << "✓ YAZE gRPC automation server listening on 0.0.0.0:"
87 << config_.port << "\n";
88
89 if (test_harness_service_) {
90 std::cout << " ✓ ImGuiTestHarness available\n";
91 }
92 if (rom_service_) {
93 std::cout << " ✓ ROM service available\n";
94 }
95 if (canvas_service_) {
96 std::cout << " ✓ Canvas Automation available\n";
97 }
98
99 std::cout << "\nServer is ready to accept requests...\n";
100
101 // Block until server is shut down
102 server_->Wait();
103
104 return absl::OkStatus();
105}
106
107absl::Status YazeGRPCServer::StartAsync() {
108 auto status = BuildServer();
109 if (!status.ok()) {
110 return status;
111 }
112
113 std::cout << "✓ Unified gRPC server started on port " << config_.port << "\n";
114
115 // Server runs in background, doesn't block
116 return absl::OkStatus();
117}
118
119absl::Status YazeGRPCServer::AddService(
120 std::unique_ptr<grpc::Service> service) {
121 if (!service) {
122 return absl::InvalidArgumentError("Service is null");
123 }
124 if (is_running_) {
125 return absl::FailedPreconditionError(
126 "Cannot add services after the server has started");
127 }
128 extra_services_.push_back(std::move(service));
129 return absl::OkStatus();
130}
131
132void YazeGRPCServer::Shutdown() {
133 if (server_ && is_running_) {
134 std::cout << "⏹ Shutting down unified gRPC server...\n";
135 server_->Shutdown();
136 server_.reset();
137 is_running_ = false;
138 std::cout << "✓ Server stopped\n";
139 }
140}
141
142bool YazeGRPCServer::IsRunning() const {
143 return is_running_;
144}
145
146absl::Status YazeGRPCServer::BuildServer() {
147 if (is_running_) {
148 return absl::FailedPreconditionError("Server already running");
149 }
150
151 std::string server_address = absl::StrFormat("0.0.0.0:%d", config_.port);
152
153 grpc::ServerBuilder builder;
154
155 // Listen on all interfaces
156 builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
157
158 // Register services
159 if (test_harness_service_) {
160 // Create gRPC wrapper for the test harness service
161 test_harness_grpc_wrapper_ =
162 test::CreateImGuiTestHarnessServiceGrpc(test_harness_service_.get());
163 std::cout << " Registering ImGuiTestHarness service...\n";
164 builder.RegisterService(test_harness_grpc_wrapper_.get());
165 }
166
167 if (rom_service_) {
168 std::cout << " Registering ROM service...\n";
169 builder.RegisterService(rom_service_.get());
170 }
171
172 if (canvas_service_) {
173 std::cout << " Registering Canvas Automation service...\n";
174 // Create gRPC wrapper using factory function
175 canvas_grpc_service_ = CreateCanvasAutomationServiceGrpc(canvas_service_);
176 builder.RegisterService(canvas_grpc_service_.get());
177 }
178
179 for (auto& service : extra_services_) {
180 builder.RegisterService(service.get());
181 }
182
183 // Build and start
184 server_ = builder.BuildAndStart();
185
186 if (!server_) {
187 return absl::InternalError(
188 absl::StrFormat("Failed to start server on %s", server_address));
189 }
190
191 is_running_ = true;
192
193 return absl::OkStatus();
194}
195
196} // namespace yaze
197
198#endif // YAZE_WITH_GRPC