PLCnext API Documentation  22.9.0.33
NonBlockingNotificationRegistration3.hpp
1 //
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>
15 namespace Arp { namespace System { namespace Nm
16 {
17 
18 class NotificationManager;
19 
49 template<typename PayloadType, typename ArgumentsType = typename PayloadType::ArgumentsType>
51  : public NotificationRegistrationBase<NonBlockingNotificationRegistration3<PayloadType, ArgumentsType>>
53 {
54  friend class NotificationManager; // to call private constructor
55 
56 private:
58 
59 public:
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 
68 private:
71  NonBlockingNotificationRegistration3(const String& notificationName, const String& senderName, Severity severity,
72  size_t argumentsBufferCapacity, std::unique_ptr<NonBlockingNotificationSendingAdapter> adapter);
73 
74 public:
79 
83 
86 
91  template<typename... Args>
93 
98  template<typename... Args>
99  Future<NotificationIdType> SendNotificationWithTimestamp(const DateTime& timestamp, Args&& ... args);
100 
103 
104 private:
105  void DisposeImpl() override;
106 
108  static RawPayloadType CreatePayload(CreatePayloadFunctorArg arg);
109 
110 protected:
112 
113 private:
114  // shared ownership is required here
115  std::shared_ptr<ArgumentsBuffer> argumentsBuffer = nullptr;
116 };
117 
118 template<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 
129 template<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 
138 template<typename PayloadType, typename ArgumentsType>
139 NonBlockingNotificationRegistration3<PayloadType, ArgumentsType>::~NonBlockingNotificationRegistration3()
140 {
141  this->Dispose();
142 }
143 
144 template<typename PayloadType, typename ArgumentsType>
145 NonBlockingNotificationRegistration3<PayloadType, ArgumentsType>&
146 NonBlockingNotificationRegistration3<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 
162 template<typename PayloadType, typename ArgumentsType>
163 void NonBlockingNotificationRegistration3<PayloadType, ArgumentsType>::DisposeImpl()
164 {
165  this->Unregister();
166 }
167 
168 template<typename PayloadType, typename ArgumentsType>
169 template<typename... Args>
171  Args&& ... args)
172 {
173  return this->SendNotificationWithTimestamp(DateTime::Now(), std::forward<Args>(args)...);
174 }
175 
176 template<typename PayloadType, typename ArgumentsType>
177 template<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 
198 template<typename PayloadType, typename ArgumentsType>
200 {
201  return this->GetNotificationNameIdInternal();
202 }
203 
204 template<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:22
PayloadTypeIdType GetPayloadTypeId() const
Returns the PayloadTypeId
Definition: NotificationRegistrationBase.hpp:119
@ 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