IDS peak genericC++  v1.4.2
peak_interface.hpp
Go to the documentation of this file.
1 
11 #pragma once
12 
13 
18 #include <peak/dll_interface/peak_dll_interface_util.hpp>
19 #include <peak/generic/peak_t_callback_manager.hpp>
20 
21 #include <unordered_map>
22 #include <cstdint>
23 #include <functional>
24 #include <memory>
25 #include <mutex>
26 #include <string>
27 #include <vector>
28 
29 
30 namespace peak
31 {
32 namespace core
33 {
34 
35 class System;
36 
37 struct DeviceFoundCallbackContainer;
38 
45 class Interface
46  : public EventSupportingModule
47  , public std::enable_shared_from_this<Interface>
48 {
49 public:
51  using DeviceFoundCallback = std::function<void(const std::shared_ptr<DeviceDescriptor>& foundDevice)>;
55  using DeviceLostCallback = std::function<void(const std::string& lostDeviceId)>;
58 
59  Interface() = delete;
60  ~Interface() override;
61  Interface(const Interface& other) = delete;
62  Interface& operator=(const Interface& other) = delete;
63  Interface(Interface&& other) = delete;
64  Interface& operator=(Interface&& other) = delete;
65 
67  std::string Key() const;
68 
70  RawInformation Info(int32_t infoCommand) const;
72  std::string ID() const;
74  std::string DisplayName() const;
76  std::string TLType() const;
77 
92  void UpdateDevices(Timeout timeout_ms);
102  std::vector<std::shared_ptr<DeviceDescriptor>> Devices() const;
104  std::shared_ptr<System> ParentSystem() const;
105 
160 
161 private:
162  struct DeviceFoundCallbackContainer
163  {
164  std::weak_ptr<Interface> _Interface;
166  };
167  static void PEAK_CALL_CONV DeviceFoundCallbackCWrapper(
168  PEAK_DEVICE_DESCRIPTOR_HANDLE foundDevice, void* context);
169  static void PEAK_CALL_CONV DeviceLostCallbackCWrapper(
170  const char* lostDeviceId, size_t lostDeviceIdSize, void* context);
171  std::shared_ptr<DeviceDescriptor> GetOrAddFoundDevice(PEAK_DEVICE_DESCRIPTOR_HANDLE foundDevice);
172 
173  PEAK_MODULE_HANDLE ModuleHandle() const override;
174  PEAK_EVENT_SUPPORTING_MODULE_HANDLE EventSupportingModuleHandle() const override;
175 
176  void InitializeUpdateMechanismIfNecessary();
177 
178  friend ClassCreator<Interface>;
179  Interface(PEAK_INTERFACE_HANDLE interfaceHandle, const std::weak_ptr<System>& parentSystem);
180  PEAK_INTERFACE_HANDLE m_backendHandle;
181 
182  std::weak_ptr<System> m_parentSystem;
183 
184  std::unique_ptr<TCallbackManager<PEAK_DEVICE_FOUND_CALLBACK_HANDLE, DeviceFoundCallbackContainer>>
185  m_deviceFoundCallbackManager;
186  std::unique_ptr<TCallbackManager<PEAK_DEVICE_LOST_CALLBACK_HANDLE, DeviceLostCallback>>
187  m_deviceLostCallbackManager;
188 
189  std::vector<std::shared_ptr<DeviceDescriptor>> m_devices;
190  std::unordered_map<std::string, std::shared_ptr<DeviceDescriptor>> m_devicesByKey;
191  std::unordered_map<std::string, std::string> m_devicesKeyById;
192  mutable std::mutex m_devicesMutex;
193  std::once_flag m_updateMechanismInitializedFlag;
194 
195  std::string m_key;
196 };
197 
198 } /* namespace core */
199 } /* namespace peak */
200 
201 /* Implementation */
202 namespace peak
203 {
204 namespace core
205 {
206 
207 inline Interface::Interface(PEAK_INTERFACE_HANDLE interfaceHandle, const std::weak_ptr<System>& parentSystem)
208  : m_backendHandle(interfaceHandle)
209  , m_parentSystem(parentSystem)
210  , m_deviceFoundCallbackManager()
211  , m_deviceLostCallbackManager()
212  , m_key(QueryStringFromCInterfaceFunction([&](char* key, size_t* keySize) {
213  return PEAK_C_ABI_PREFIX PEAK_Interface_GetKey(interfaceHandle, key, keySize);
214  }))
215 {
216  m_deviceFoundCallbackManager =
217  std::make_unique<TCallbackManager<PEAK_DEVICE_FOUND_CALLBACK_HANDLE, DeviceFoundCallbackContainer>>(
218  [&](void* callbackContext) {
219  return QueryNumericFromCInterfaceFunction<PEAK_DEVICE_FOUND_CALLBACK_HANDLE>(
220  [&](PEAK_DEVICE_FOUND_CALLBACK_HANDLE* deviceFoundCallbackHandle) {
222  m_backendHandle, DeviceFoundCallbackCWrapper, callbackContext, deviceFoundCallbackHandle);
223  });
224  },
225  [&](PEAK_DEVICE_FOUND_CALLBACK_HANDLE callbackHandle) {
226  CallAndCheckCInterfaceFunction([&] {
228  m_backendHandle, callbackHandle);
229  });
230  });
231 
232  m_deviceLostCallbackManager =
233  std::make_unique<TCallbackManager<PEAK_DEVICE_LOST_CALLBACK_HANDLE, DeviceLostCallback>>(
234  [&](void* callbackContext) {
235  return QueryNumericFromCInterfaceFunction<PEAK_DEVICE_LOST_CALLBACK_HANDLE>(
236  [&](PEAK_DEVICE_LOST_CALLBACK_HANDLE* deviceLostCallbackHandle) {
238  m_backendHandle, DeviceLostCallbackCWrapper, callbackContext, deviceLostCallbackHandle);
239  });
240  },
241  [&](PEAK_DEVICE_LOST_CALLBACK_HANDLE callbackHandle) {
242  CallAndCheckCInterfaceFunction([&] {
244  m_backendHandle, callbackHandle);
245  });
246  });
247 }
248 
250 {
251  try
252  {
253  m_deviceFoundCallbackManager->UnregisterAllCallbacks();
254  m_deviceLostCallbackManager->UnregisterAllCallbacks();
255  }
256  catch (const Exception&)
257  {}
258 
259  (void)PEAK_C_ABI_PREFIX PEAK_Interface_Destruct(m_backendHandle);
260 }
261 
262 inline std::string Interface::Key() const
263 {
264  return m_key;
265 }
266 
267 inline RawInformation Interface::Info(int32_t infoCommand) const
268 {
269  return QueryRawInformationFromCInterfaceFunction([&](int32_t* dataType, uint8_t* buffer, size_t* bufferSize) {
271  m_backendHandle, infoCommand, dataType, buffer, bufferSize);
272  });
273 }
274 
275 inline std::string Interface::ID() const
276 {
277  return QueryStringFromCInterfaceFunction([&](char* id, size_t* idSize) {
278  return PEAK_C_ABI_PREFIX PEAK_Interface_GetID(m_backendHandle, id, idSize);
279  });
280 }
281 
282 inline std::string Interface::DisplayName() const
283 {
284  return QueryStringFromCInterfaceFunction([&](char* displayName, size_t* displayNameSize) {
285  return PEAK_C_ABI_PREFIX PEAK_Interface_GetDisplayName(m_backendHandle, displayName, displayNameSize);
286  });
287 }
288 
289 inline std::string Interface::TLType() const
290 {
291  return QueryStringFromCInterfaceFunction([&](char* tlType, size_t* tlTypeSize) {
292  return PEAK_C_ABI_PREFIX PEAK_Interface_GetTLType(m_backendHandle, tlType, tlTypeSize);
293  });
294 }
295 
296 inline void Interface::UpdateDevices(Timeout timeout_ms)
297 {
298  InitializeUpdateMechanismIfNecessary();
299 
300  CallAndCheckCInterfaceFunction(
301  [&] { return PEAK_C_ABI_PREFIX PEAK_Interface_UpdateDevices(m_backendHandle, timeout_ms); });
302 }
303 
304 inline std::vector<std::shared_ptr<DeviceDescriptor>> Interface::Devices() const
305 {
306  std::lock_guard<std::mutex> lock(m_devicesMutex);
307  return m_devices;
308 }
309 
310 inline std::shared_ptr<System> Interface::ParentSystem() const
311 {
312  return LockOrThrow(m_parentSystem);
313 }
314 
316  const Interface::DeviceFoundCallback& callback)
317 {
318  return reinterpret_cast<DeviceFoundCallbackHandle>(
319  m_deviceFoundCallbackManager->RegisterCallback(DeviceFoundCallbackContainer{ shared_from_this(), callback }));
320 }
321 
323 {
324  m_deviceFoundCallbackManager->UnregisterCallback(
325  reinterpret_cast<PEAK_DEVICE_FOUND_CALLBACK_HANDLE>(callbackHandle));
326 }
327 
329  const Interface::DeviceLostCallback& callback)
330 {
331  return reinterpret_cast<DeviceLostCallbackHandle>(m_deviceLostCallbackManager->RegisterCallback(callback));
332 }
333 
335 {
336  m_deviceLostCallbackManager->UnregisterCallback(
337  reinterpret_cast<PEAK_DEVICE_LOST_CALLBACK_HANDLE>(callbackHandle));
338 }
339 
340 inline void PEAK_CALL_CONV Interface::DeviceFoundCallbackCWrapper(
341  PEAK_DEVICE_DESCRIPTOR_HANDLE foundDevice, void* context)
342 {
343  auto callbackContainer = static_cast<DeviceFoundCallbackContainer*>(context);
344 
345  auto interfaceDescriptor = callbackContainer->_Interface.lock()->GetOrAddFoundDevice(foundDevice);
346 
347  callbackContainer->Callback(interfaceDescriptor);
348 }
349 
350 inline void PEAK_CALL_CONV Interface::DeviceLostCallbackCWrapper(
351  const char* lostDeviceId, size_t lostDeviceIdSize, void* context)
352 {
353  auto callback = static_cast<Interface::DeviceLostCallback*>(context);
354 
355  callback->operator()(std::string(lostDeviceId, lostDeviceIdSize - 1));
356 }
357 
358 inline std::shared_ptr<DeviceDescriptor> Interface::GetOrAddFoundDevice(PEAK_DEVICE_DESCRIPTOR_HANDLE foundDevice)
359 {
360  std::lock_guard<std::mutex> lock(m_devicesMutex);
361 
362  const auto deviceKey = QueryStringFromCInterfaceFunction([&](char* key, size_t* keySize) {
363  return PEAK_C_ABI_PREFIX PEAK_DeviceDescriptor_GetKey(foundDevice, key, keySize);
364  });
365  auto keyDevicePairIterator = m_devicesByKey.find(deviceKey);
366  if (keyDevicePairIterator == m_devicesByKey.end())
367  {
368  auto deviceDescriptor = std::static_pointer_cast<DeviceDescriptor>(
369  std::make_shared<ClassCreator<DeviceDescriptor>>(
370  foundDevice, std::weak_ptr<Interface>{ shared_from_this() }));
371  m_devices.emplace_back(deviceDescriptor);
372  m_devicesByKey.emplace(deviceKey, deviceDescriptor);
373  m_devicesKeyById.emplace(deviceDescriptor->ID(), deviceKey);
374 
375  return deviceDescriptor;
376  }
377 
378  return keyDevicePairIterator->second;
379 }
380 
381 inline PEAK_MODULE_HANDLE Interface::ModuleHandle() const
382 {
383  auto moduleHandle = QueryNumericFromCInterfaceFunction<PEAK_MODULE_HANDLE>(
384  [&](PEAK_MODULE_HANDLE* _moduleHandle) {
385  return PEAK_C_ABI_PREFIX PEAK_Interface_ToModule(m_backendHandle, _moduleHandle);
386  });
387 
388  return moduleHandle;
389 }
390 
391 inline PEAK_EVENT_SUPPORTING_MODULE_HANDLE Interface::EventSupportingModuleHandle() const
392 {
393  auto eventSupportingModuleHandle = QueryNumericFromCInterfaceFunction<PEAK_EVENT_SUPPORTING_MODULE_HANDLE>(
394  [&](PEAK_EVENT_SUPPORTING_MODULE_HANDLE* _eventSupportingModuleHandle) {
396  m_backendHandle, _eventSupportingModuleHandle);
397  });
398 
399  return eventSupportingModuleHandle;
400 }
401 
402 inline void Interface::InitializeUpdateMechanismIfNecessary()
403 {
404  std::call_once(m_updateMechanismInitializedFlag, [&] {
405  (void)RegisterDeviceFoundCallback([](const std::shared_ptr<DeviceDescriptor>&) {
406  // Registering an empty callback is enough since DeviceFoundCallbackCWrapper() handles everything else.
407  });
408  (void)RegisterDeviceLostCallback([&](const std::string& lostDeviceId) {
409  std::lock_guard<std::mutex> lock(m_devicesMutex);
410  const auto lostDeviceKey = m_devicesKeyById.at(lostDeviceId);
411  m_devices.erase(std::remove_if(std::begin(m_devices), std::end(m_devices),
412  [lostDeviceKey](const std::shared_ptr<DeviceDescriptor>& device) {
413  return device->Key() == lostDeviceKey;
414  }),
415  std::end(m_devices));
416  m_devicesByKey.erase(lostDeviceKey);
417  m_devicesKeyById.erase(lostDeviceId);
418  });
419  });
420 }
421 
422 } /* namespace core */
423 } /* namespace peak */
DeviceLostCallback * DeviceLostCallbackHandle
Definition: peak_interface.hpp:57
std::function< void(const std::shared_ptr< DeviceDescriptor > &foundDevice)> DeviceFoundCallback
Definition: peak_interface.hpp:51
std::vector< std::shared_ptr< DeviceDescriptor > > Devices() const
Returns the device list.
Definition: peak_interface.hpp:304
Encapsulates the GenTL functions associated with a GenTL Device module&#39;s ID.
Definition: peak_device_descriptor.hpp:102
std::function< void(const std::string &lostDeviceId)> DeviceLostCallback
Definition: peak_interface.hpp:55
PEAK_C_API PEAK_Interface_RegisterDeviceFoundCallback(PEAK_INTERFACE_HANDLE interfaceHandle, PEAK_DEVICE_FOUND_CALLBACK callback, void *callbackContext, PEAK_DEVICE_FOUND_CALLBACK_HANDLE *callbackHandle)
Registers a callback signaling a found device at the given interface.
PEAK_C_API PEAK_Interface_RegisterDeviceLostCallback(PEAK_INTERFACE_HANDLE interfaceHandle, PEAK_DEVICE_LOST_CALLBACK callback, void *callbackContext, PEAK_DEVICE_LOST_CALLBACK_HANDLE *callbackHandle)
Registers a callback signaling a lost device at the given interface.
PEAK_C_API PEAK_Interface_GetTLType(PEAK_INTERFACE_HANDLE interfaceHandle, char *tlType, size_t *tlTypeSize)
Asks the given interface for its TL type.
PEAK_C_API PEAK_Interface_GetDisplayName(PEAK_INTERFACE_HANDLE interfaceHandle, char *displayName, size_t *displayNameSize)
Asks the given interface for its display name.
The "peak" namespace directly contains convenience functionality like the DeviceManager as well as th...
Definition: peak_dynamic_loader.h:32
struct PEAK_EVENT_SUPPORTING_MODULE * PEAK_EVENT_SUPPORTING_MODULE_HANDLE
Definition: peak_backend.h:457
PEAK_C_API PEAK_Interface_GetInfo(PEAK_INTERFACE_HANDLE interfaceHandle, int32_t infoCommand, int32_t *infoDataType, uint8_t *info, size_t *infoSize)
Asks the given interface for an information based on a specific command.
PEAK_C_API PEAK_Interface_GetKey(PEAK_INTERFACE_HANDLE interfaceHandle, char *key, size_t *keySize)
Asks the given interface for its key.
PEAK_C_API PEAK_Interface_ToModule(PEAK_INTERFACE_HANDLE interfaceHandle, PEAK_MODULE_HANDLE *moduleHandle)
Casts the given interface to a module.
DeviceFoundCallbackHandle RegisterDeviceFoundCallback(const DeviceFoundCallback &callback)
Registers a callback for signaling a found device.
Definition: peak_interface.hpp:315
void UpdateDevices(Timeout timeout_ms)
Searches for devices.
Definition: peak_interface.hpp:296
Represents a GenTL Interface module.
Definition: peak_interface.hpp:45
~Interface() override
Definition: peak_interface.hpp:249
PEAK_DEVICE_FOUND_CALLBACK * PEAK_DEVICE_FOUND_CALLBACK_HANDLE
Definition: peak_backend.h:498
PEAK_C_API PEAK_Interface_UnregisterDeviceFoundCallback(PEAK_INTERFACE_HANDLE interfaceHandle, PEAK_DEVICE_FOUND_CALLBACK_HANDLE callbackHandle)
Unregisters the device-found callback with the given handle from the given interface.
void UnregisterDeviceLostCallback(DeviceLostCallbackHandle callbackHandle)
Unregisters a device lost callback.
Definition: peak_interface.hpp:334
std::string DisplayName() const
Returns the display name.
Definition: peak_interface.hpp:282
PEAK_C_API PEAK_Interface_UpdateDevices(PEAK_INTERFACE_HANDLE interfaceHandle, uint64_t timeout_ms)
Tells the given interface to update its devices with the given timeout.
std::string Key() const
Returns the unique key.
Definition: peak_interface.hpp:262
void UnregisterDeviceFoundCallback(DeviceFoundCallbackHandle callbackHandle)
Unregisters a device found callback.
Definition: peak_interface.hpp:322
RawInformation Info(int32_t infoCommand) const
Delivers information based on the given GenTL info command.
Definition: peak_interface.hpp:267
PEAK_C_API PEAK_Interface_ToEventSupportingModule(PEAK_INTERFACE_HANDLE interfaceHandle, PEAK_EVENT_SUPPORTING_MODULE_HANDLE *eventSupportingModuleHandle)
Casts the given interface to an event-supporting module.
Represents a timeout value in milliseconds.
Definition: peak_timeout.hpp:30
PEAK_C_API PEAK_Interface_Destruct(PEAK_INTERFACE_HANDLE interfaceHandle)
Destroys the given interface.
The base class for all exceptions thrown by the library.
Definition: peak_exception.hpp:25
struct PEAK_DEVICE_DESCRIPTOR * PEAK_DEVICE_DESCRIPTOR_HANDLE
Definition: peak_backend.h:365
DeviceFoundCallback * DeviceFoundCallbackHandle
Definition: peak_interface.hpp:53
#define PEAK_CALL_CONV
Definition: peak_dynamic_loader.h:29
#define PEAK_C_ABI_PREFIX
Definition: peak_dll_defines.h:16
std::shared_ptr< System > ParentSystem() const
Returns the parent system.
Definition: peak_interface.hpp:310
std::string TLType() const
Returns the TL (transport layer) type.
Definition: peak_interface.hpp:289
struct PEAK_INTERFACE * PEAK_INTERFACE_HANDLE
Definition: peak_backend.h:361
The struct returned by all raw information functions.
Definition: peak_common_structs.hpp:24
DeviceLostCallbackHandle RegisterDeviceLostCallback(const DeviceLostCallback &callback)
Registers a callback for signaling a lost device.
Definition: peak_interface.hpp:328
struct PEAK_MODULE * PEAK_MODULE_HANDLE
Definition: peak_backend.h:401
PEAK_C_API PEAK_Interface_UnregisterDeviceLostCallback(PEAK_INTERFACE_HANDLE interfaceHandle, PEAK_DEVICE_LOST_CALLBACK_HANDLE callbackHandle)
Unregisters the device-lost callback with the given handle from the given interface.
PEAK_DEVICE_LOST_CALLBACK * PEAK_DEVICE_LOST_CALLBACK_HANDLE
Definition: peak_backend.h:500
The base class for all modules being able to raise events.
Definition: peak_event_supporting_module.hpp:33
std::string ID() const
Returns the ID.
Definition: peak_interface.hpp:275
PEAK_C_API PEAK_DeviceDescriptor_GetKey(PEAK_DEVICE_DESCRIPTOR_HANDLE deviceDescriptorHandle, char *key, size_t *keySize)
Asks the given device descriptor for its key.
PEAK_C_API PEAK_Interface_GetID(PEAK_INTERFACE_HANDLE interfaceHandle, char *id, size_t *idSize)
Asks the given interface for its ID.
Interface & operator=(const Interface &other)=delete