diff --git a/CMakeLists.txt b/CMakeLists.txt index aee39d9..900c66a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -147,6 +147,7 @@ if(BEDROCK_WITH_TRANSPORT_DEPS) file(MAKE_DIRECTORY "${PALANTIR_PROTO_OUT_DIR}") set(CAPABILITIES_PROTO "${PALANTIR_PROTO_DIR}/palantir/capabilities.proto") + set(XYSINE_PROTO "${PALANTIR_PROTO_DIR}/palantir/xysine.proto") if(EXISTS "${CAPABILITIES_PROTO}") add_custom_command( @@ -160,9 +161,34 @@ if(BEDROCK_WITH_TRANSPORT_DEPS) DEPENDS "${CAPABILITIES_PROTO}" COMMENT "Generating C++ from Palantir Capabilities.proto" ) + endif() + + if(EXISTS "${XYSINE_PROTO}") + add_custom_command( + OUTPUT + "${PALANTIR_PROTO_OUT_DIR}/palantir/xysine.pb.cc" + "${PALANTIR_PROTO_OUT_DIR}/palantir/xysine.pb.h" + COMMAND "${PROTOC_EXECUTABLE}" + --proto_path="${PALANTIR_PROTO_DIR}" + --cpp_out="${PALANTIR_PROTO_OUT_DIR}" + "${XYSINE_PROTO}" + DEPENDS "${XYSINE_PROTO}" + COMMENT "Generating C++ from Palantir xysine.proto" + ) + endif() + # Build proto library with all available proto files + set(PROTO_SOURCES) + if(EXISTS "${CAPABILITIES_PROTO}") + list(APPEND PROTO_SOURCES "${PALANTIR_PROTO_OUT_DIR}/palantir/capabilities.pb.cc") + endif() + if(EXISTS "${XYSINE_PROTO}") + list(APPEND PROTO_SOURCES "${PALANTIR_PROTO_OUT_DIR}/palantir/xysine.pb.cc") + endif() + + if(PROTO_SOURCES) add_library(bedrock_palantir_proto STATIC - "${PALANTIR_PROTO_OUT_DIR}/palantir/capabilities.pb.cc" + ${PROTO_SOURCES} ) target_include_directories(bedrock_palantir_proto PUBLIC @@ -182,16 +208,33 @@ if(BEDROCK_WITH_TRANSPORT_DEPS) find_library(ABSL_LOG_INTERNAL_CHECK_OP_LIB absl_log_internal_check_op PATHS /opt/homebrew/opt/abseil/lib NO_DEFAULT_PATH) find_library(ABSL_LOG_INTERNAL_CONDITIONS_LIB absl_log_internal_conditions PATHS /opt/homebrew/opt/abseil/lib NO_DEFAULT_PATH) find_library(ABSL_LOG_INTERNAL_MESSAGE_LIB absl_log_internal_message PATHS /opt/homebrew/opt/abseil/lib NO_DEFAULT_PATH) + find_library(ABSL_LOG_INTERNAL_NULLGUARD_LIB absl_log_internal_nullguard PATHS /opt/homebrew/opt/abseil/lib NO_DEFAULT_PATH) - if(ABSL_DIE_IF_NULL_LIB AND ABSL_LOG_INITIALIZE_LIB AND ABSL_STATUSOR_LIB) - target_link_libraries(bedrock_palantir_proto PUBLIC - ${ABSL_DIE_IF_NULL_LIB} - ${ABSL_LOG_INITIALIZE_LIB} - ${ABSL_STATUSOR_LIB} - ${ABSL_LOG_INTERNAL_CHECK_OP_LIB} - ${ABSL_LOG_INTERNAL_CONDITIONS_LIB} - ${ABSL_LOG_INTERNAL_MESSAGE_LIB} - ) + set(ABSEIL_LIBS) + if(ABSL_DIE_IF_NULL_LIB) + list(APPEND ABSEIL_LIBS ${ABSL_DIE_IF_NULL_LIB}) + endif() + if(ABSL_LOG_INITIALIZE_LIB) + list(APPEND ABSEIL_LIBS ${ABSL_LOG_INITIALIZE_LIB}) + endif() + if(ABSL_STATUSOR_LIB) + list(APPEND ABSEIL_LIBS ${ABSL_STATUSOR_LIB}) + endif() + if(ABSL_LOG_INTERNAL_CHECK_OP_LIB) + list(APPEND ABSEIL_LIBS ${ABSL_LOG_INTERNAL_CHECK_OP_LIB}) + endif() + if(ABSL_LOG_INTERNAL_CONDITIONS_LIB) + list(APPEND ABSEIL_LIBS ${ABSL_LOG_INTERNAL_CONDITIONS_LIB}) + endif() + if(ABSL_LOG_INTERNAL_MESSAGE_LIB) + list(APPEND ABSEIL_LIBS ${ABSL_LOG_INTERNAL_MESSAGE_LIB}) + endif() + if(ABSL_LOG_INTERNAL_NULLGUARD_LIB) + list(APPEND ABSEIL_LIBS ${ABSL_LOG_INTERNAL_NULLGUARD_LIB}) + endif() + + if(ABSEIL_LIBS) + target_link_libraries(bedrock_palantir_proto PUBLIC ${ABSEIL_LIBS}) endif() message(STATUS "Palantir proto codegen enabled: Capabilities.proto -> bedrock_palantir_proto") @@ -236,6 +279,11 @@ if(BEDROCK_WITH_TRANSPORT_DEPS) bedrock_capabilities_service ) + # Link abseil libraries (required by protobuf 6.33+) + if(ABSEIL_LIBS) + target_link_libraries(bedrock_palantir_server PUBLIC ${ABSEIL_LIBS}) + endif() + target_compile_definitions(bedrock_palantir_server PRIVATE BEDROCK_WITH_TRANSPORT_DEPS) # --------------------------------------- diff --git a/docs/palantir b/docs/palantir index b6563fe..0a544e9 160000 --- a/docs/palantir +++ b/docs/palantir @@ -1 +1 @@ -Subproject commit b6563feef6870fbb0a7714b94b8a9ccacb57cb3c +Subproject commit 0a544e9f66cdd8401745370d1ccb7e121dc252e0 diff --git a/src/palantir/PalantirServer.cpp b/src/palantir/PalantirServer.cpp index c076fb9..6add816 100644 --- a/src/palantir/PalantirServer.cpp +++ b/src/palantir/PalantirServer.cpp @@ -10,6 +10,10 @@ #include #include +#ifdef BEDROCK_WITH_TRANSPORT_DEPS +#include "palantir/xysine.pb.h" +#endif + PalantirServer::PalantirServer(QObject *parent) : QObject(parent) , server_(std::make_unique(this)) @@ -161,10 +165,17 @@ void PalantirServer::onHeartbeatTimer() void PalantirServer::handleMessage(QLocalSocket* client, const QByteArray& message) { // Parse message type and dispatch - // WP1: Only handle CapabilitiesRequest + // WP1: Handle CapabilitiesRequest and XYSineRequest // Future: Add StartJob, Cancel, Ping/Pong when those proto messages are defined #ifdef BEDROCK_WITH_TRANSPORT_DEPS + // Try to parse as XYSineRequest (check before CapabilitiesRequest for specificity) + palantir::XYSineRequest xySineRequest; + if (xySineRequest.ParseFromArray(message.data(), message.size())) { + handleXYSineRequest(client, xySineRequest); + return; + } + // Try to parse as CapabilitiesRequest palantir::CapabilitiesRequest request; if (request.ParseFromArray(message.data(), message.size())) { @@ -238,6 +249,65 @@ void PalantirServer::handleCapabilitiesRequest(QLocalSocket* client) #endif } +void PalantirServer::handleXYSineRequest(QLocalSocket* client, const palantir::XYSineRequest& request) +{ +#ifdef BEDROCK_WITH_TRANSPORT_DEPS + // Compute XY Sine + std::vector xValues, yValues; + computeXYSine(request, xValues, yValues); + + // Build response + palantir::XYSineResponse response; + response.mutable_x()->Reserve(static_cast(xValues.size())); + response.mutable_y()->Reserve(static_cast(yValues.size())); + for (double x : xValues) { + response.add_x(x); + } + for (double y : yValues) { + response.add_y(y); + } + response.set_status("OK"); + + // Send response + sendMessage(client, response); +#else + qWarning() << "XY Sine requested but transport deps disabled"; +#endif +} + +void PalantirServer::computeXYSine(const palantir::XYSineRequest& request, std::vector& xValues, std::vector& yValues) +{ + // Parse parameters from request (proto3 provides default values: 0.0 for double, 0 for int32) + // Use explicit defaults to match Phoenix behavior + double frequency = request.frequency() != 0.0 ? request.frequency() : 1.0; + double amplitude = request.amplitude() != 0.0 ? request.amplitude() : 1.0; + double phase = request.phase(); // 0.0 is valid default + int samples = request.samples() != 0 ? request.samples() : 1000; + + // Validate samples (minimum 2) - matches Phoenix behavior + if (samples < 2) { + samples = 2; + } + + // Compute sine wave using EXACT Phoenix algorithm + // t = i / (samples - 1) from 0 to 1 + // x = t * 2π (0..2π domain) + // y = amplitude * sin(2π * frequency * t + phase) + xValues.clear(); + yValues.clear(); + xValues.reserve(samples); + yValues.reserve(samples); + + for (int i = 0; i < samples; ++i) { + double t = static_cast(i) / (samples - 1.0); // 0 to 1 + double x = t * 2.0 * M_PI; // Scale to 0..2π domain + double y = amplitude * std::sin(2.0 * M_PI * frequency * t + phase); + + xValues.push_back(x); + yValues.push_back(y); + } +} + // WP1: Ping/Pong handler disabled (proto message not yet defined) // Future: Re-enable when Pong proto is added /* diff --git a/src/palantir/PalantirServer.hpp b/src/palantir/PalantirServer.hpp index ec2561a..d4cfdd6 100644 --- a/src/palantir/PalantirServer.hpp +++ b/src/palantir/PalantirServer.hpp @@ -14,6 +14,7 @@ #ifdef BEDROCK_WITH_TRANSPORT_DEPS #include "palantir/capabilities.pb.h" +#include "palantir/xysine.pb.h" #include "CapabilitiesService.hpp" #endif @@ -49,6 +50,8 @@ private slots: void handleMessage(QLocalSocket* client, const QByteArray& message); #ifdef BEDROCK_WITH_TRANSPORT_DEPS void handleCapabilitiesRequest(QLocalSocket* client); + void handleXYSineRequest(QLocalSocket* client, const palantir::XYSineRequest& request); + void computeXYSine(const palantir::XYSineRequest& request, std::vector& xValues, std::vector& yValues); #endif // Future: Add StartJob, Cancel, Ping handlers when proto messages are defined // void handleStartJob(QLocalSocket* client, const palantir::StartJob& startJob);