PLCnext API Documentation 23.0.2.9
NonBlockingNotificationRegistration3.hpp
1
2//
3// Copyright PHOENIX CONTACT Electronics GmbH
4//
6#pragma once
7#include "Arp/System/Commons/Threading/LockGuard.hpp"
8#include "Arp/System/Commons/Threading/Mutex.hpp"
9#include "Arp/System/Nm/NonBlockingNotificationRegistration3ArgumentsBuffer.hpp"
10#include "Arp/System/Nm/NonBlockingNotificationRegistration3Base.hpp"
11#include "Arp/System/Nm/NonBlockingNotificationSendingAdapter.hpp"
12#include "Arp/System/Nm/NotificationRegistrationBase.hpp"
13#include <limits>
14#include <numeric>
15namespace Arp { namespace System { namespace Nm
16{
17
18class NotificationManager;
19
49template<typename PayloadType, typename ArgumentsType = typename PayloadType::ArgumentsType>
51 : public NotificationRegistrationBase<NonBlockingNotificationRegistration3<PayloadType, ArgumentsType>>
53{
54 friend class NotificationManager; // to call private constructor
55
56private:
58
59public:
60 using payload_type = PayloadType;
61 using arguments_type = ArgumentsType;
62
63 static_assert(std::is_constructible<PayloadType, typename std::add_const<ArgumentsType>::type>::value,
64 "PayloadType must be constructible by const ArgumentsType!");
65 static_assert(std::is_default_constructible<ArgumentsType>::value, "ArgumentType must be default constructible");
66 static_assert(std::is_copy_assignable<ArgumentsType>::value, "ArgumentsType must be copy assignable");
67
68private:
71 NonBlockingNotificationRegistration3(const String& notificationName, const String& senderName, Severity severity,
72 size_t argumentsBufferCapacity, std::unique_ptr<NonBlockingNotificationSendingAdapter> adapter);
73
74public:
79
83
86
91 template<typename... Args>
93
98 template<typename... Args>
99 Future<NotificationIdType> SendNotificationWithTimestamp(const DateTime& timestamp, Args&& ... args);
100
103
104private:
105 void DisposeImpl() override;
106
108 static RawPayloadType CreatePayload(CreatePayloadFunctorArg arg);
109
110protected:
112
113private:
114 // shared ownership is required here
115 std::shared_ptr<ArgumentsBuffer> argumentsBuffer = nullptr;
116};
117
118template<typename PayloadType, typename ArgumentsType>
120 const String& notificationName, const String& senderName, Severity severity, size_t argumentsBufferCapacity,
121 std::unique_ptr<NonBlockingNotificationSendingAdapter> adapter)
122 : base_type(notificationName, senderName, severity),
124 argumentsBuffer(std::make_shared<ArgumentsBuffer>(argumentsBufferCapacity))
125{
126 this->Register(notificationName, senderName, severity, this->GetPayloadTypeId());
127}
128
129template<typename PayloadType, typename ArgumentsType>
131 NonBlockingNotificationRegistration3<PayloadType, ArgumentsType>&& other) noexcept
132 : base_type(std::move(other)),
133 NonBlockingNotificationRegistration3Base(std::move(other)),
134 argumentsBuffer(std::move(other.argumentsBuffer))
135{
136}
137
138template<typename PayloadType, typename ArgumentsType>
139NonBlockingNotificationRegistration3<PayloadType, ArgumentsType>::~NonBlockingNotificationRegistration3()
140{
141 this->Dispose();
142}
143
144template<typename PayloadType, typename ArgumentsType>
145NonBlockingNotificationRegistration3<PayloadType, ArgumentsType>&
146NonBlockingNotificationRegistration3<PayloadType, ArgumentsType>::operator=(
147 NonBlockingNotificationRegistration3<PayloadType, ArgumentsType>&& other) noexcept
148{
149 if (this == &other)
150 {
151 return *this;
152 }
153
154 base_type::operator=(std::move(other));
155 NonBlockingNotificationRegistration3Base::operator=(std::move(other));
156
157 this->argumentsBuffer = std::move(other.argumentsBuffer);
158
159 return *this;
160}
161
162template<typename PayloadType, typename ArgumentsType>
163void NonBlockingNotificationRegistration3<PayloadType, ArgumentsType>::DisposeImpl()
164{
165 this->Unregister();
166}
167
168template<typename PayloadType, typename ArgumentsType>
169template<typename... Args>
171 Args&& ... args)
172{
173 return this->SendNotificationWithTimestamp(DateTime::Now(), std::forward<Args>(args)...);
174}
175
176template<typename PayloadType, typename ArgumentsType>
177template<typename... Args>
180 const DateTime& timestamp, Args&& ... args)
181{
182 static_assert(std::is_constructible<ArgumentsType, Args...>::value,
183 "The ArgumentsType must be constructible by the passed arguments (Args).");
184
185 if (this->IsReadyToSend())
186 {
187 auto insertResult = this->argumentsBuffer->Insert(ArgumentsType{std::forward<Args>(args)...});
188 this->SendNotificationInternal(
189 timestamp, this->argumentsBuffer, insertResult, &NonBlockingNotificationRegistration3::CreatePayload);
190 }
191 else
192 {
193 this->ResetFutureNotificationId();
194 }
195 return this->GetFutureNotificationId();
196}
197
198template<typename PayloadType, typename ArgumentsType>
200{
201 return this->GetNotificationNameIdInternal();
202}
203
204template<typename PayloadType, typename ArgumentsType>
206 CreatePayloadFunctorArg arg)
207{
208 auto buffer = std::dynamic_pointer_cast<ArgumentsBuffer>(arg.BufferPtr);
209 if (!buffer)
210 {
211 return {};
212 }
213
214 auto removeResult = buffer->Remove(arg.Index);
215 if (!removeResult.IsValid)
216 {
217 return {};
218 }
219
220 return PayloadType{removeResult.Args}.MoveOutRawPayload();
221}
222
223}}} // namespace Arp::System::Nm
The class contains date and time informations.
Definition: DateTime.hpp:45
static DateTime Now(void)
Gets the current time as DateTime, expressed as the UTC time.
Future object as proxy for return value an asynchronous function call
Definition: Future.hpp:114
Definition: NonBlockingNotificationRegistration3ArgumentsBuffer.hpp:20
Internal class for pimpl pattern
Definition: NonBlockingNotificationRegistration3Base.hpp:19
Proxy object for a non-blocking NotificationRegistration
Definition: NonBlockingNotificationRegistration3.hpp:53
Future< NotificationIdType > SendNotification(Args &&... args)
Sends a notification
Definition: NonBlockingNotificationRegistration3.hpp:170
NonBlockingNotificationRegistration3()=default
Creates an empty NotificationRegistration
NotificationNameIdType GetNotificationNameId() const override
Returns the NotificationNameId
Definition: NonBlockingNotificationRegistration3.hpp:199
Future< NotificationIdType > SendNotificationWithTimestamp(const DateTime &timestamp, Args &&... args)
Sends a notification with a specified timestamp
Definition: NonBlockingNotificationRegistration3.hpp:179
Primary access to the NotificationManager
Definition: NotificationManager.hpp:49
Base class with common behavior of NotificationRegistration and NonBlockingNotificationRegistration
Definition: NotificationRegistrationBase.hpp:24
PayloadTypeIdType GetPayloadTypeId() const
Returns the PayloadTypeId
Definition: NotificationRegistrationBase.hpp:121
@ System
System components used by the System, Device, Plc or Io domains.
Severity
Enumeration of Severities for notifications
Definition: Severity.hpp:15
std::vector< Arp::System::Rsc::Services::RscVariant< RawPayloadTypeLength > > RawPayloadType
type for the internally transferred payloads
Definition: NotificationManagerTypes.hpp:34
Root namespace for the PLCnext API
Namespace of the C++ standard library
Definition: NonBlockingNotificationSendingAdapter.hpp:28