-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[#13] Implement services (without reflectable parts)
- Loading branch information
Showing
20 changed files
with
1,269 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
<#include "FileHeader.inc.ftl"> | ||
<#include "Service.inc.ftl"> | ||
<@file_header generatorDescription/> | ||
|
||
#include <zserio/SerializeUtil.h> | ||
<@type_includes types.bitBuffer/> | ||
<@system_includes cppSystemIncludes/> | ||
|
||
<@user_include package.path, "${name}.h"/> | ||
<@user_includes cppUserIncludes, false/> | ||
<@namespace_begin package.path/> | ||
<@namespace_begin [name]/> | ||
|
||
Service::Service(const AllocatorType& allocator) : | ||
::zserio::AllocatorHolder<${types.allocator.default}>(allocator) | ||
{} | ||
|
||
${types.serviceDataPtr.name} Service::callMethod( | ||
::std::string_view methodName, ::zserio::Span<const uint8_t> requestData, void* context) | ||
{ | ||
<#list methodList as method> | ||
if (methodName == methodNames()[${method?index}]) | ||
{ | ||
return ${method.name}Method(requestData, context); | ||
} | ||
</#list> | ||
throw ::zserio::ServiceException("${serviceFullName}: Method '") << methodName << "' does not exist!"; | ||
} | ||
|
||
::std::string_view Service::serviceFullName() noexcept | ||
{ | ||
static const ::std::string_view serviceFullName = "${serviceFullName}"; | ||
return serviceFullName; | ||
} | ||
|
||
const ::std::array<::std::string_view, ${methodList?size}>& Service::methodNames() noexcept | ||
{ | ||
static constexpr ::std::array<::std::string_view, ${methodList?size}> names = | ||
{ | ||
<#list methodList as method> | ||
"${method.name}"<#if method?has_next>,</#if> | ||
</#list> | ||
}; | ||
|
||
return names; | ||
} | ||
<#list methodList as method> | ||
|
||
${types.serviceDataPtr.name} Service::${method.name}Method( | ||
::zserio::Span<const uint8_t> requestData, void* context) | ||
{ | ||
<#if !method.requestTypeInfo.isBytes> | ||
${method.requestTypeInfo.typeFullName} request(get_allocator_ref()); | ||
zserio::deserializeFromBytes(requestData, request); | ||
|
||
</#if> | ||
<#if method.responseTypeInfo.isBytes> | ||
return ::std::allocate_shared<${types.rawServiceDataHolder.name}>(get_allocator_ref(), | ||
${method.name}Impl(request<#if method.requestTypeInfo.isBytes>Data</#if>, context)); | ||
<#else> | ||
class ResponseData : public ${types.serviceDataPtr.name}::element_type | ||
{ | ||
public: | ||
ResponseData(${method.responseTypeInfo.typeFullName}&& response, const AllocatorType& allocator) : | ||
m_serviceData(response, allocator) | ||
{} | ||
|
||
::zserio::Span<const uint8_t> getData() const override | ||
{ | ||
return m_serviceData.getData(); | ||
} | ||
|
||
private: | ||
${types.objectServiceData.name} m_serviceData; | ||
}; | ||
|
||
return ::std::allocate_shared<ResponseData>(get_allocator_ref(), | ||
${method.name}Impl(request<#if method.requestTypeInfo.isBytes>Data</#if>, context), <#rt> | ||
<#lt>get_allocator_ref()); | ||
</#if> | ||
} | ||
</#list> | ||
|
||
Client::Client(${types.serviceClient.name}& service, const AllocatorType& allocator) : | ||
::zserio::AllocatorHolder<${types.allocator.default}>(allocator), | ||
m_service(service) | ||
{ | ||
} | ||
<#list methodList as method> | ||
|
||
${method.responseTypeInfo.typeFullName} Client::${method.name}Method(<#rt> | ||
<#lt><@service_arg_type_name method.requestTypeInfo/> request, void* context) | ||
{ | ||
<#if method.requestTypeInfo.isBytes> | ||
const ${types.rawServiceDataView.name} requestData(request); | ||
<#else> | ||
const ${types.objectServiceData.name} requestData(request, get_allocator_ref()); | ||
</#if> | ||
|
||
auto responseData = m_service.callMethod("${method.name}", requestData, context); | ||
<#if method.responseTypeInfo.isBytes> | ||
return responseData; | ||
<#else> | ||
|
||
${method.responseTypeInfo.typeFullName} response(get_allocator_ref()); | ||
zserio::deserializeFromBytes(responseData, response); | ||
return response; | ||
</#if> | ||
} | ||
</#list> | ||
<@namespace_end [name]/> | ||
<@namespace_end package.path/> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
<#include "FileHeader.inc.ftl"> | ||
<#include "DocComment.inc.ftl"> | ||
<#include "Service.inc.ftl"> | ||
<@file_header generatorDescription/> | ||
|
||
<@include_guard_begin package.path, name/> | ||
|
||
<@runtime_version_check generatorVersion/> | ||
|
||
#include <array> | ||
#include <zserio/Types.h> | ||
<@type_includes types.service/> | ||
#include <zserio/AllocatorHolder.h> | ||
#include <zserio/ServiceException.h> | ||
<@system_includes headerSystemIncludes/> | ||
<@user_includes headerUserIncludes/> | ||
<@namespace_begin package.path/> | ||
<@namespace_begin [name]/> | ||
|
||
/** | ||
* Service part of the service ${name}. | ||
* | ||
<#if docComments??> | ||
* \b Description | ||
* | ||
<@doc_comments_inner docComments/> | ||
</#if> | ||
*/ | ||
class Service : | ||
public ${types.service.name}, | ||
public ::zserio::AllocatorHolder<${types.allocator.default}> | ||
{ | ||
public: | ||
/** | ||
* Default constructor. | ||
* | ||
* \param allocator Allocator to construct from. | ||
*/ | ||
explicit Service(const AllocatorType& allocator = AllocatorType()); | ||
|
||
/** Default destructor. */ | ||
~Service() override = default; | ||
|
||
/** Disables copy constructor. */ | ||
Service(const Service&) = delete; | ||
/** Disables assignment operator. */ | ||
Service& operator=(const Service&) = delete; | ||
|
||
/** Default move constructor. */ | ||
Service(Service&&) = default; | ||
/** Disables move assignment operator. */ | ||
Service& operator=(Service&&) = delete; | ||
|
||
/** | ||
* Calls method with the given name synchronously. | ||
* | ||
* \param methodName Name of the service method to call. | ||
* \param requestData Request data to be passed to the method. | ||
* \param context Context specific for particular service. | ||
* | ||
* \return Created response data. | ||
* | ||
* \throw ServiceException if the call fails. | ||
*/ | ||
${types.serviceDataPtr.name} callMethod( | ||
::std::string_view methodName, ::zserio::Span<const uint8_t> requestData, | ||
void* context) override; | ||
|
||
/** | ||
* Gets the service full qualified name. | ||
* | ||
* \return Service name together with its package name. | ||
*/ | ||
static ::std::string_view serviceFullName() noexcept; | ||
|
||
/** | ||
* Gets all method names of the service. | ||
* | ||
* \return Array of all method names of the service. | ||
*/ | ||
static const ::std::array<::std::string_view, ${methodList?size}>& methodNames() noexcept; | ||
|
||
private: | ||
<#if methodList?has_content> | ||
<#list methodList as method> | ||
virtual ${method.responseTypeInfo.typeFullName} ${method.name}Impl(<#rt> | ||
<#lt><@service_arg_type_name method.requestTypeInfo/> request, void* context) = 0; | ||
</#list> | ||
|
||
<#list methodList as method> | ||
${types.serviceDataPtr.name} ${method.name}Method( | ||
::zserio::Span<const uint8_t> requestData, void* context); | ||
</#list> | ||
</#if> | ||
}; | ||
|
||
/** | ||
* Client part of the service ${name}. | ||
* | ||
<#if docComments??> | ||
* \b Description | ||
* | ||
<@doc_comments_inner docComments/> | ||
</#if> | ||
*/ | ||
class Client : public ::zserio::AllocatorHolder<${types.allocator.default}> | ||
{ | ||
public: | ||
/** | ||
* Constructor from the service client backend. | ||
* | ||
* \param service Interface for service client backend. | ||
* \param allocator Allocator to construct from. | ||
*/ | ||
explicit Client(${types.serviceClient.name}& service, const AllocatorType& allocator = AllocatorType()); | ||
|
||
/** Default destructor. */ | ||
~Client() = default; | ||
|
||
/** Disables copy constructor. */ | ||
Client(const Client&) = delete; | ||
/** Disables assignment operator. */ | ||
Client& operator=(const Client&) = delete; | ||
|
||
/** Default move constructor. */ | ||
Client(Client&&) = default; | ||
/** Disables move assignment operator. */ | ||
Client& operator=(Client&&) = delete; | ||
<#list methodList as method> | ||
|
||
/** | ||
* Calls method ${method.name}. | ||
* | ||
<#if method.docComments??> | ||
* \b Description | ||
* | ||
<@doc_comments_inner method.docComments, 1/> | ||
* | ||
</#if> | ||
* \param request Request to be passed to the method. | ||
* \param context Context specific for particular service. | ||
* | ||
* \return Response returned from the method. | ||
*/ | ||
${method.responseTypeInfo.typeFullName} ${method.name}Method(<#rt> | ||
<#lt><@service_arg_type_name method.requestTypeInfo/> request, void* context = nullptr); | ||
</#list> | ||
|
||
private: | ||
${types.serviceClient.name}& m_service; | ||
}; | ||
<@namespace_end [name]/> | ||
<@namespace_end package.path/> | ||
|
||
<@include_guard_end package.path, name/> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
<#macro service_arg_type_name typeInfo> | ||
<#if typeInfo.isBytes> | ||
::zserio::BytesView<#t> | ||
<#else> | ||
const ${typeInfo.typeFullName}&<#t> | ||
</#if> | ||
</#macro> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.