diff --git a/serialization/protobuf/protobuf/CMakeLists.txt b/serialization/protobuf/protobuf/CMakeLists.txt index e1587fdf82..6b871f4ec9 100644 --- a/serialization/protobuf/protobuf/CMakeLists.txt +++ b/serialization/protobuf/protobuf/CMakeLists.txt @@ -77,7 +77,8 @@ target_sources(protobuf_core FILES include/ecal/msg/protobuf/client.h include/ecal/msg/protobuf/client_instance.h - include/ecal/msg/protobuf/client_response_parser.h + include/ecal/msg/protobuf/client_protobuf_utils.h + include/ecal/msg/protobuf/client_response_parser.h include/ecal/msg/protobuf/client_typed_response.h include/ecal/msg/protobuf/dynamic_json_subscriber.h include/ecal/msg/protobuf/dynamic_publisher.h diff --git a/serialization/protobuf/protobuf/include/ecal/msg/protobuf/client.h b/serialization/protobuf/protobuf/include/ecal/msg/protobuf/client.h index cdce40b811..31623696ee 100644 --- a/serialization/protobuf/protobuf/include/ecal/msg/protobuf/client.h +++ b/serialization/protobuf/protobuf/include/ecal/msg/protobuf/client.h @@ -26,8 +26,10 @@ #include #include + #include -#include // our new templated CClientInstance +#include +#include #ifdef _MSC_VER #pragma warning(push, 0) // disable proto warnings @@ -63,7 +65,7 @@ namespace eCAL * @brief Constructor (using protobuf‐defined service name). */ CServiceClient(const ClientEventCallbackT& event_callback_ = ClientEventCallbackT()) - : eCAL::CServiceClient(GetServiceNameFromDescriptor(), CreateServiceMethodInformationSet(), event_callback_) + : eCAL::CServiceClient(GetServiceNameFromDescriptor(), CreateServiceMethodInformationSet(), event_callback_) { } @@ -73,7 +75,7 @@ namespace eCAL * @param service_name_ Unique service name. */ explicit CServiceClient(const std::string& service_name_, const ClientEventCallbackT& event_callback_ = ClientEventCallbackT()) - : eCAL::CServiceClient(service_name_, CreateServiceMethodInformationSet(), event_callback_) + : eCAL::CServiceClient(service_name_, CreateServiceMethodInformationSet(), event_callback_) { } @@ -258,61 +260,6 @@ namespace eCAL using eCAL::CServiceClient::CallWithResponse; using eCAL::CServiceClient::CallWithCallback; using eCAL::CServiceClient::CallWithCallbackAsync; - - private: - /** - * @brief Retrieves the full service name from the Protobuf descriptor. - */ - static std::string GetServiceNameFromDescriptor() - { - struct U : T {}; // Temporary subclass to access protected GetDescriptor() - U temp_instance; - return temp_instance.GetDescriptor()->full_name(); - } - - /** - * @brief Generates the method information set for the service. - * - * @return A set containing method information. - */ - static ServiceMethodInformationSetT CreateServiceMethodInformationSet() - { - struct U : T {}; // Temporary subclass to access protected GetDescriptor() - U temp_instance; - const google::protobuf::ServiceDescriptor* service_descriptor = temp_instance.GetDescriptor(); - - if (service_descriptor == nullptr) - { - throw std::runtime_error("Failed to retrieve service descriptor."); - } - - ServiceMethodInformationSetT method_information_map; - CProtoDynDecoder dyn_decoder; - std::string error_s; - - for (int i = 0; i < service_descriptor->method_count(); ++i) - { - const google::protobuf::MethodDescriptor* method_descriptor = service_descriptor->method(i); - const std::string& method_name = method_descriptor->name(); - - const std::string& request_type_name = method_descriptor->input_type()->name(); - const std::string& response_type_name = method_descriptor->output_type()->name(); - - std::string request_type_descriptor; - std::string response_type_descriptor; - - dyn_decoder.GetServiceMessageDescFromType(service_descriptor, request_type_name, request_type_descriptor, error_s); - dyn_decoder.GetServiceMessageDescFromType(service_descriptor, response_type_name, response_type_descriptor, error_s); - - method_information_map.emplace(SServiceMethodInformation{ - method_name, - SDataTypeInformation{request_type_name, "proto", request_type_descriptor}, - SDataTypeInformation{response_type_name, "proto", response_type_descriptor} - }); - } - - return method_information_map; - } }; } // namespace protobuf } // namespace eCAL diff --git a/serialization/protobuf/protobuf/include/ecal/msg/protobuf/client_protobuf_utils.h b/serialization/protobuf/protobuf/include/ecal/msg/protobuf/client_protobuf_utils.h new file mode 100644 index 0000000000..89413debb7 --- /dev/null +++ b/serialization/protobuf/protobuf/include/ecal/msg/protobuf/client_protobuf_utils.h @@ -0,0 +1,105 @@ +/* ========================= eCAL LICENSE ================================= + * + * Copyright (C) 2016 - 2025 Continental Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ========================= eCAL LICENSE ================================= +*/ + +/** + * @file client_protobuf_utils.h + * @brief eCAL client protobuf service utility functions +**/ + +#pragma once + +#include +#include + +#include +#include + +#include +#include + +namespace eCAL +{ + namespace protobuf + { + /** + * @brief Retrieves the full service name from the Protobuf descriptor of the given type T. + * + * The service type T is expected to be generated by Protobuf and have + * a static method_descriptor or a protected GetDescriptor() method. + * + * @tparam T The Protobuf-generated service class. + * + * @return The full service name (e.g. "myproto.MyService"). + */ + template + std::string GetServiceNameFromDescriptor() + { + struct U : T {}; // Temporary subclass to access protected GetDescriptor() + U temp_instance; + return temp_instance.GetDescriptor()->full_name(); + } + + /** + * @brief Creates a ServiceMethodInformationSetT for all methods in service type T, + * so that eCAL knows how to serialize/deserialize them (proto). + * + * @tparam T The Protobuf-generated service class. + * @return The set of method info for eCAL registration. + */ + template + eCAL::ServiceMethodInformationSetT CreateServiceMethodInformationSet() + { + struct U : T {}; // Temporary subclass to access protected GetDescriptor() + U temp_instance; + const google::protobuf::ServiceDescriptor* service_descriptor = temp_instance.GetDescriptor(); + + if (service_descriptor == nullptr) + { + throw std::runtime_error("Failed to retrieve service descriptor."); + } + + ServiceMethodInformationSetT method_information_set; + CProtoDynDecoder dyn_decoder; + std::string error_s; + + for (int i = 0; i < service_descriptor->method_count(); ++i) + { + const google::protobuf::MethodDescriptor* method_descriptor = service_descriptor->method(i); + const std::string& method_name = method_descriptor->name(); + + const std::string& request_type_name = method_descriptor->input_type()->name(); + const std::string& response_type_name = method_descriptor->output_type()->name(); + + std::string request_type_descriptor; + std::string response_type_descriptor; + + dyn_decoder.GetServiceMessageDescFromType(service_descriptor, request_type_name, request_type_descriptor, error_s); + dyn_decoder.GetServiceMessageDescFromType(service_descriptor, response_type_name, response_type_descriptor, error_s); + + method_information_set.emplace(SServiceMethodInformation{ + method_name, + SDataTypeInformation{request_type_name, "proto", request_type_descriptor}, + SDataTypeInformation{response_type_name, "proto", response_type_descriptor} + }); + } + + return method_information_set; + } + } // namespace protobuf +} // namespace eCAL diff --git a/serialization/protobuf/protobuf/include/ecal/msg/protobuf/client_response_parser.h b/serialization/protobuf/protobuf/include/ecal/msg/protobuf/client_response_parser.h index 5b21182502..d99c2bc5b6 100644 --- a/serialization/protobuf/protobuf/include/ecal/msg/protobuf/client_response_parser.h +++ b/serialization/protobuf/protobuf/include/ecal/msg/protobuf/client_response_parser.h @@ -21,6 +21,7 @@ * @file client_response_parser.h * @brief eCAL client response message parser **/ + #include #include