VLink 2.0.0
A high-performance communication middleware
载入中...
搜索中...
未找到
intra_data.h
浏览该文件的文档.
1/*
2 * Copyright (C) 2026 by Thun Lu. All rights reserved.
3 * Author: Thun Lu <thun.lu@zohomail.cn>
4 * Repo: https://github.com/thun-res/vlink
5 * _ __ __ _ __
6 * | | / / / / (_) ____ / /__
7 * | | / / / / / / / __ \ / //_/
8 * | |/ / / /___ / / / / / / / ,<
9 * |___/ /_____/ /_/ /_/ /_/ /_/|_|
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
14 *
15 * http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
22 */
23
24/**
25 * @file intra_data.h
26 * @brief Zero-serialisation in-process message container for intra:// transport.
27 *
28 * @details
29 * @c IntraData is the zero-copy message type used exclusively on the
30 * @c intra:// transport, where publisher and subscriber reside in the same process.
31 * Instead of serialising a message to @c Bytes and immediately deserialising it
32 * on the other side, a @c shared_ptr to the payload object is passed directly.
33 *
34 * @par Usage Pattern
35 * The @c VLINK_INTRA_DATA_DECLARE(target_type, declare_name) macro generates two
36 * types for a given VLink message type @c T:
37 * - @c declare_nameType -- concrete @c IntraDataType subclass holding a @c T value
38 * plus serialisation/deserialisation helpers.
39 * - @c declare_name -- a @c std::shared_ptr<declare_nameType> wrapper with a static
40 * @c create() factory and implicit conversions from the base @c shared_ptr.
41 *
42 * @par Example
43 * @code
44 * // Declare once (typically in a generated or per-type header):
45 * VLINK_INTRA_DATA_DECLARE(MyProtoMsg, MyProtoIntra)
46 *
47 * // In Publisher:
48 * auto data = MyProtoIntra::create();
49 * data->value.set_field(42);
50 * pub.publish_intra(data); // zero-copy path
51 *
52 * // In Subscriber:
53 * sub.listen([](const MyProtoIntra& intra) {
54 * // use typed->value directly
55 * });
56 * @endcode
57 *
58 * @note @c IntraData messages are only supported on @c intra:// topics. Attempting
59 * to call @c write(IntraData) on a non-intra @c PublisherImpl logs a warning
60 * and returns @c false.
61 */
62
63#pragma once
64
65#include <memory>
66#include <string>
67
68#include "../serializer.h"
69#include "./types.h"
70
71namespace vlink {
72
73/**
74 * @struct IntraDataType
75 * @brief Polymorphic base for all typed in-process message containers.
76 *
77 * @details
78 * Concrete subtypes generated by @c VLINK_INTRA_DATA_DECLARE carry the actual
79 * message value and implement @c operator<< / @c operator>> for on-demand
80 * serialisation when the message must cross a transport boundary.
81 */
83 IntraDataType() = default;
84 virtual ~IntraDataType() = default;
85};
86
87/**
88 * @brief Shared-ownership handle for an @c IntraDataType payload.
89 *
90 * @details
91 * Passed between the publisher and subscriber in the same process by reference
92 * counting, avoiding any serialisation or data copy. Downcast to the concrete
93 * @c declareNameType via @c std::static_pointer_cast<> or use the typed
94 * @c declare_name wrapper generated by @c VLINK_INTRA_DATA_DECLARE.
95 */
96using IntraData = std::shared_ptr<IntraDataType>;
97
98} // namespace vlink
99
100/**
101 * @def VLINK_INTRA_DATA_DECLARE
102 * @brief Generates a typed in-process message container pair.
103 *
104 * @details
105 * Expands to two declarations:
106 *
107 * -# @c declare_nameType -- a concrete @c IntraDataType subclass with:
108 * - @c target_type value -- the message payload.
109 * - @c static constexpr Serializer::Type kValueType -- compile-time type tag.
110 * - @c bool operator<<(const Bytes&) -- deserialise @c Bytes into @c value.
111 * - @c bool operator>>(Bytes&) const -- serialise @c value into @c Bytes.
112 * - @c size_t get_serialized_size() const -- byte count needed for serialisation.
113 * - @c static std::string get_serialized_type() -- type name string.
114 * - A @c static_assert ensuring @c target_type is a supported serialiser type.
115 *
116 * -# @c declare_name -- a @c std::shared_ptr<declare_nameType> subclass with:
117 * - Constructors and conversions from the base @c shared_ptr.
118 * - @c static declare_name create() -- factory returning a heap-allocated instance.
119 *
120 * @param target_type The VLink message type (must be a supported @c Serializer::Type).
121 * @param declare_name The name to give the generated container types.
122 */
123#define VLINK_INTRA_DATA_DECLARE(target_type, declare_name) \
124 struct declare_name##Type : public vlink::IntraDataType { \
125 target_type value; \
126 \
127 static constexpr vlink::Serializer::Type kValueType = vlink::Serializer::get_type_of<target_type>(); \
128 \
129 static_assert(vlink::Serializer::is_supported(kValueType), \
130 "VLINK_INTRA_DATA_DECLARE(target_type) is not a supported Serializer type."); \
131 \
132 bool operator<<(const vlink::Bytes& bytes) noexcept { \
133 return vlink::Serializer::deserialize<kValueType>(bytes, value); \
134 } \
135 \
136 bool operator>>(vlink::Bytes& bytes) const noexcept { \
137 return vlink::Serializer::serialize<kValueType>(value, bytes); \
138 } \
139 \
140 [[nodiscard]] size_t get_serialized_size() const noexcept { \
141 return vlink::Serializer::get_serialized_size<kValueType>(value); \
142 } \
143 \
144 [[nodiscard]] static std::string get_serialized_type() noexcept { \
145 return vlink::Serializer::get_serialized_type<kValueType, target_type>(); \
146 } \
147 \
148 [[nodiscard]] static constexpr vlink::SchemaType get_schema_type() noexcept { \
149 return vlink::Serializer::get_schema_type<kValueType, target_type>(); \
150 } \
151 }; \
152 \
153 struct declare_name : public std::shared_ptr<declare_name##Type> { \
154 using Base = std::shared_ptr<declare_name##Type>; \
155 using Base::Base; \
156 \
157 /*NOLINTBEGIN*/ \
158 declare_name() noexcept = default; \
159 \
160 declare_name(Base&& other) noexcept : Base(std::move(other)) {} \
161 \
162 declare_name(const Base& other) noexcept : Base(other) {} \
163 \
164 [[nodiscard]] static declare_name create() noexcept { \
165 return declare_name(std::make_shared<declare_name##Type>()); \
166 } \
167 /*NOLINTEND*/ \
168 };
Compile-time type-detection and serialisation utilities for VLink messages.
Core type definitions shared across all VLink node implementations.