IDS peak genericC++  v1.6.0
peak_device_manager.hpp
Go to the documentation of this file.
1 
11 #pragma once
12 
18 #include <peak/generic/peak_t_callback_manager.hpp>
24 
25 #include <type_traits>
26 #include <unordered_map>
27 #include <unordered_set>
28 #include <algorithm>
29 #include <atomic>
30 #include <exception>
31 #include <functional>
32 #include <future>
33 #include <iterator>
34 #include <memory>
35 #include <mutex>
36 #include <utility>
37 #include <vector>
38 #include <cstdlib>
39 #include <new>
40 
41 namespace peak
42 {
43 
71 class DeviceManager final
72 {
73 public:
75  enum class UpdatePolicy
76  {
79  };
81  enum class ResetPolicy
82  {
83  ErrorOnOpenDevices,
84  IgnoreOpenDevices
85  };
86 
88  using SystemFoundCallback = std::function<void(const std::shared_ptr<const core::System>& foundSystem)>;
92  using InterfaceFoundCallback = std::function<void(const std::shared_ptr<const core::Interface>& foundInterface)>;
96  using InterfaceLostCallback = std::function<void(const std::string& lostInterfaceKey)>;
100  using DeviceFoundCallback = std::function<void(const std::shared_ptr<core::DeviceDescriptor>& foundDevice)>;
104  using DeviceLostCallback = std::function<void(const std::string& lostDeviceKey)>;
108  using UpdateErrorCallback = std::function<void(const std::string& errorDescription)>;
109 
115  static DeviceManager& Instance();
116 
133  void AddProducerLibrary(const std::string& ctiPath);
134 
154  const UpdateErrorCallback& errorCallback = UpdateErrorCallback());
197  void SetInterfaceUpdateTimeout(core::Timeout timeout_ms);
221  void SetDeviceUpdateTimeout(core::Timeout timeout_ms);
222 
232  std::vector<std::shared_ptr<const core::System>> Systems() const;
242  std::vector<std::shared_ptr<const core::Interface>> Interfaces() const;
252  std::vector<std::shared_ptr<core::DeviceDescriptor>> Devices() const;
253 
399 
400 private:
401  friend class Library;
402 
403  DeviceManager() = default;
404  ~DeviceManager();
405 
406  DeviceManager(const DeviceManager& other) = delete;
407  DeviceManager& operator=(const DeviceManager& other) = delete;
408 
409  void GetLostDevicesFromLostInterfaces(
410  const std::unordered_set<std::string>& lostInterfaces, std::vector<std::string>& lostDevices);
411 
412  void TriggerSystemFoundCallbacks(const std::shared_ptr<const core::System>& foundSystem) const;
413  void TriggerInterfaceFoundCallbacks(const std::shared_ptr<const core::Interface>& foundInterface) const;
414  void TriggerInterfaceLostCallbacks(const std::string& lostInterfaceKey) const;
415  void TriggerDeviceFoundCallbacks(const std::shared_ptr<core::DeviceDescriptor>& foundDevice) const;
416  void TriggerDeviceLostCallbacks(const std::string& lostDeviceKey) const;
417 
418  void CheckDevicesOpened() const;
419 
420  std::mutex m_updateMutex;
421  std::atomic<core::Timeout> m_interfaceUpdateTimeout_ms{ 100 };
422  std::atomic<core::Timeout> m_deviceUpdateTimeout_ms{ 300 };
423 
424  std::vector<std::string> m_producerLibrariesToAdd;
425 
426  std::unordered_map<std::string, std::shared_ptr<core::ProducerLibrary>> m_producerLibraries;
427  std::vector<std::shared_ptr<const core::System>> m_systems;
428  std::vector<std::shared_ptr<const core::Interface>> m_interfaces;
429  std::vector<std::shared_ptr<core::DeviceDescriptor>> m_devices;
430 
431  struct OpenedDevice
432  {
433  std::weak_ptr<core::Device> device;
434  std::string displayName;
435  };
436  std::vector<OpenedDevice> m_openedDevices;
437 
438  core::TTriggerCallbackManager<SystemFoundCallbackHandle, SystemFoundCallback> m_systemFoundCallbackManager;
439  core::TTriggerCallbackManager<InterfaceFoundCallbackHandle, InterfaceFoundCallback> m_interfaceFoundCallbackManager;
440  core::TTriggerCallbackManager<InterfaceLostCallbackHandle, InterfaceLostCallback> m_interfaceLostCallbackManager;
441  core::TTriggerCallbackManager<DeviceFoundCallbackHandle, DeviceFoundCallback> m_deviceFoundCallbackManager;
442  core::TTriggerCallbackManager<DeviceLostCallbackHandle, DeviceLostCallback> m_deviceLostCallbackManager;
443 
444  std::mutex m_producerLibrariesToAddMutex;
445  mutable std::mutex m_systemsMutex;
446  mutable std::mutex m_interfacesMutex;
447  mutable std::mutex m_devicesMutex;
448  mutable std::mutex m_openedDevicesMutex;
449 
450 #ifndef _MSC_VER
451  template <typename T,
452  typename std::enable_if<(noexcept(std::declval<T>()())
453  || (std::is_pointer<typename std::decay<T>::type>::value && __cplusplus < 201703L)
454  // NOTE pre c++17 there is no way to check weather a function pointer is noexcept
455  )
456  && std::is_same<void, decltype(std::declval<T>()())>::value && std::is_move_constructible<T>::value
457  && std::is_nothrow_move_constructible<T>::value,
458  int>::type = 0>
459 #else
460  template <typename T>
461 #endif
462  class RAIIGuard
463  {
464  T m_fun;
465 
466  public:
467  RAIIGuard(T&& fun) noexcept
468  : m_fun(std::forward<T>(fun))
469  {}
470  RAIIGuard(RAIIGuard const&) = delete;
471  RAIIGuard(RAIIGuard&& other) noexcept
472  : m_fun(std::move(other.m_fun))
473  {}
474  ~RAIIGuard() noexcept
475  {
476  m_fun();
477  }
478  };
479  template <typename T>
480  static RAIIGuard<T> makeRAIIGuard(T&& fun) noexcept
481  {
482  return { std::forward<T>(fun) };
483  }
484 
485  template<typename T = DeviceManager>
486  class LifetimeTracker
487  {
488  public:
489  static void Create();
490  static void Destroy();
491  static T& Instance();
492 
493  private:
494  static T* m_instance;
495  static std::mutex m_mtx;
496  static size_t m_initializedCount;
497  };
498 };
499 
500 } /* namespace peak */
501 
502 /* Implementation */
503 namespace peak
504 {
505 
506 template<typename T>
507 T* DeviceManager::LifetimeTracker<T>::m_instance = {};
508 
509 template<typename T>
510 std::mutex DeviceManager::LifetimeTracker<T>::m_mtx = {};
511 
512 template<typename T>
513 size_t DeviceManager::LifetimeTracker<T>::m_initializedCount = {};
514 
515 template<typename T>
516 void DeviceManager::LifetimeTracker<T>::Create()
517 {
518  std::lock_guard<decltype(m_mtx)> lock{m_mtx};
519 
520  if (!m_instance)
521  {
522  m_instance = new T{};
523  }
524 
525  m_initializedCount++;
526 }
527 
528 template<typename T>
529 void DeviceManager::LifetimeTracker<T>::Destroy()
530 {
531  std::lock_guard<decltype(m_mtx)> lock{m_mtx};
532 
533  if (0 == m_initializedCount)
534  {
535  return;
536  }
537 
538  m_initializedCount--;
539 
540  if (0 == m_initializedCount)
541  {
542  if (m_instance)
543  {
544  delete m_instance;
545  m_instance = nullptr;
546  }
547  }
548 }
549 
550 template<typename T>
551 T& DeviceManager::LifetimeTracker<T>::Instance()
552 {
553  return *m_instance;
554 }
555 
557 {
558  return DeviceManager::LifetimeTracker<>::Instance();
559 }
560 
561 inline DeviceManager::~DeviceManager()
562 {
564 }
565 
566 inline void DeviceManager::AddProducerLibrary(const std::string& ctiPath)
567 {
568  std::lock_guard<std::mutex> lock(m_producerLibrariesToAddMutex);
569 
570  m_producerLibrariesToAdd.emplace_back(ctiPath);
571 }
572 
573 inline void DeviceManager::Update(UpdatePolicy updatePolicy /*= UpdatePolicy::ScanEnvironmentForProducerLibraries*/,
574  const UpdateErrorCallback& errorCallback /*= UpdateErrorCallback()*/)
575 {
576  std::lock_guard<std::mutex> lockUpdate(m_updateMutex);
577 
578  std::vector<std::shared_ptr<core::System>> allFoundSystems;
579  std::vector<std::shared_ptr<core::Interface>> allFoundInterfaces;
580  std::vector<std::string> allLostInterfaces;
581  std::vector<std::shared_ptr<core::DeviceDescriptor>> allFoundDevices;
582  std::vector<std::string> allLostDevices;
583 
584  auto interfaceUpdateTimeout_ms = m_interfaceUpdateTimeout_ms.load();
585  auto deviceUpdateTimeout_ms = m_deviceUpdateTimeout_ms.load();
586 
587  std::vector<std::string> ctiPaths;
588  // We look for all producer libraries in the current environment if we have to
590  {
592  }
593  // We look for the manually added producer libraries
594  {
595  std::lock_guard<std::mutex> lock(m_producerLibrariesToAddMutex);
596 
597  ctiPaths.reserve(ctiPaths.size() + m_producerLibrariesToAdd.size());
598  std::move(
599  std::begin(m_producerLibrariesToAdd), std::end(m_producerLibrariesToAdd), std::back_inserter(ctiPaths));
600 
601  m_producerLibrariesToAdd.clear();
602  }
603  for (const auto& ctiPath : ctiPaths)
604  {
605  if (!m_producerLibraries.count(ctiPath))
606  {
607  try
608  {
609  auto producerLibrary = core::ProducerLibrary::Open(ctiPath);
610  auto system = producerLibrary->System()->OpenSystem();
611 
612  m_producerLibraries.emplace(ctiPath, producerLibrary);
613  allFoundSystems.emplace_back(system);
614  }
615  catch (const core::NotAvailableException&)
616  {
617  // TL not available or not supported.
618  continue;
619  }
620  catch (const core::NotInitializedException&)
621  {
622  // TODO: check this on creation of DeviceManager?
623  throw; // if this exception occurs, nothing else will work. so we stop here
624  }
625  catch (const core::Exception& ex)
626  {
627  if (errorCallback)
628  {
629  try
630  {
631  errorCallback("[CTI - " + ctiPath + "]: " + ex.what());
632  }
633  catch (...)
634  {}
635  }
636  }
637  }
638  }
639 
640  auto interfaceUpdateFunc = [&interfaceUpdateTimeout_ms, &errorCallback](const std::shared_ptr<core::System>& system)
641  -> std::tuple<std::vector<std::shared_ptr<core::Interface>>, std::vector<std::string>> {
642  std::vector<std::shared_ptr<core::Interface>> foundInterfaces;
643  std::vector<std::string> lostInterfaces;
644 
645  try
646  {
647  auto foundCallbackHandle = system->RegisterInterfaceFoundCallback(
648  [&foundInterfaces](const std::shared_ptr<core::InterfaceDescriptor>& foundInterface) {
649  foundInterfaces.emplace_back(foundInterface->OpenInterface());
650  });
651  auto const foundCallbackCleanupGuard = makeRAIIGuard([system, &foundCallbackHandle]() noexcept {
652  try
653  {
654  system->UnregisterInterfaceFoundCallback(foundCallbackHandle);
655  }
656  catch (const core::Exception&)
657  {
658  std::terminate();
659  }
660  });
661 
662  auto keysById = std::unordered_map<std::string, std::string>();
663  for (const auto& iface : system->Interfaces())
664  {
665  keysById.emplace(iface->ID(), iface->Key());
666  }
667  auto lostCallbackHandle = system->RegisterInterfaceLostCallback(
668  [&lostInterfaces, &keysById](const std::string& lostInterfaceId) {
669  auto idKeyPairIt = keysById.find(lostInterfaceId);
670 
671  if (idKeyPairIt != keysById.end())
672  {
673  lostInterfaces.emplace_back((*idKeyPairIt).second);
674  }
675  });
676  auto const lostCallbackCleanupGuard = makeRAIIGuard([system, &lostCallbackHandle]() noexcept {
677  try
678  {
679  system->UnregisterInterfaceLostCallback(lostCallbackHandle);
680  }
681  catch (const core::Exception&)
682  {
683  std::terminate();
684  }
685  });
686 
687  system->UpdateInterfaces(interfaceUpdateTimeout_ms);
688  }
689  catch (const core::Exception& ex)
690  {
691  if (errorCallback)
692  {
693  try
694  {
695  errorCallback("[System - " + system->Key() + "]: " + ex.what());
696  }
697  catch (...)
698  {}
699  }
700  }
701 
702  return std::make_tuple(foundInterfaces, lostInterfaces);
703  };
704 
705  // We do an update on all available systems
706  const std::launch launchPolicy =
707  std::launch::async; // switching this to std::launch::deferred makes debugging easier
708  std::vector<std::future<std::tuple<std::vector<std::shared_ptr<core::Interface>>, std::vector<std::string>>>>
709  interfaceUpdateFutures;
710  for (const auto& system : m_systems)
711  {
712  interfaceUpdateFutures.emplace_back(
713  std::async(launchPolicy, interfaceUpdateFunc, std::const_pointer_cast<core::System>(system)));
714  }
715  for (const auto& system : allFoundSystems)
716  {
717  interfaceUpdateFutures.emplace_back(std::async(launchPolicy, interfaceUpdateFunc, system));
718  }
719  for (auto& future : interfaceUpdateFutures)
720  {
721  auto foundLostInterfacesTuple = future.get();
722  auto foundInterfaces = std::get<0>(foundLostInterfacesTuple);
723  auto lostInterfaces = std::get<1>(foundLostInterfacesTuple);
724  allFoundInterfaces.reserve(allFoundInterfaces.size() + foundInterfaces.size());
725  std::move(std::begin(foundInterfaces), std::end(foundInterfaces), std::back_inserter(allFoundInterfaces));
726  allLostInterfaces.reserve(allLostInterfaces.size() + lostInterfaces.size());
727  std::move(std::begin(lostInterfaces), std::end(lostInterfaces), std::back_inserter(allLostInterfaces));
728  }
729 
730  auto deviceUpdateFunc = [this, &deviceUpdateTimeout_ms, &errorCallback](
731  const std::shared_ptr<core::Interface>& iface)
732  -> std::tuple<std::vector<std::shared_ptr<core::DeviceDescriptor>>, std::vector<std::string>> {
733  std::vector<std::shared_ptr<core::DeviceDescriptor>> foundDevices;
734  std::vector<std::string> lostDevices;
735 
736  try
737  {
738  auto foundCallbackHandle = iface->RegisterDeviceFoundCallback(
739  [this, &foundDevices](const std::shared_ptr<core::DeviceDescriptor>& foundDevice) {
740  foundDevice->RegisterDeviceOpenedCallback(
741  [this](const std::shared_ptr<core::Device>& openedDevice) {
742  std::lock_guard<std::mutex> lock(m_openedDevicesMutex);
743 
744  // clear out closed devices
745  m_openedDevices.erase(std::remove_if(std::begin(m_openedDevices), std::end(m_openedDevices),
746  [](const OpenedDevice& dev) { return dev.device.expired(); }),
747  std::end(m_openedDevices));
748 
749  // add the new one
750  OpenedDevice device;
751  device.device = openedDevice;
752  device.displayName = openedDevice->DisplayName();
753  m_openedDevices.push_back(device);
754  });
755 
756  foundDevices.emplace_back(foundDevice);
757  });
758  auto const foundCallbackCleanupGuard = makeRAIIGuard([iface, &foundCallbackHandle]() noexcept {
759  try
760  {
761  iface->UnregisterDeviceFoundCallback(foundCallbackHandle);
762  }
763  catch (const core::Exception&)
764  {
765  std::terminate();
766  }
767  });
768 
769  auto keysById = std::unordered_map<std::string, std::string>();
770  for (const auto& device : iface->Devices())
771  {
772  keysById.emplace(device->ID(), device->Key());
773  }
774  auto lostCallbackHandle = iface->RegisterDeviceLostCallback(
775  [&lostDevices, &keysById](const std::string& lostDeviceId) {
776  auto idKeyPairIt = keysById.find(lostDeviceId);
777 
778  if (idKeyPairIt != keysById.end())
779  {
780  lostDevices.emplace_back((*idKeyPairIt).second);
781  }
782  });
783  auto const lostCallbackCleanupGuard = makeRAIIGuard([iface, &lostCallbackHandle]() noexcept {
784  try
785  {
786  iface->UnregisterDeviceLostCallback(lostCallbackHandle);
787  }
788  catch (const core::Exception&)
789  {
790  std::terminate();
791  }
792  });
793 
794  iface->UpdateDevices(deviceUpdateTimeout_ms);
795  }
796  catch (const core::Exception& ex)
797  {
798  if (errorCallback)
799  {
800  try
801  {
802  errorCallback("[Interface - " + iface->Key() + "]: " + ex.what());
803  }
804  catch (...)
805  {}
806  }
807  }
808 
809  return std::make_tuple(foundDevices, lostDevices);
810  };
811 
812  // We do an update on all available interfaces
813  std::vector<std::future<std::tuple<std::vector<std::shared_ptr<core::DeviceDescriptor>>, std::vector<std::string>>>>
814  deviceUpdateFutures;
815  for (const auto& iface : m_interfaces)
816  {
817  deviceUpdateFutures.emplace_back(
818  std::async(launchPolicy, deviceUpdateFunc, std::const_pointer_cast<core::Interface>(iface)));
819  }
820  for (const auto& iface : allFoundInterfaces)
821  {
822  deviceUpdateFutures.emplace_back(std::async(launchPolicy, deviceUpdateFunc, iface));
823  }
824  for (auto& future : deviceUpdateFutures)
825  {
826  auto foundLostDevicesTuple = future.get();
827  auto foundDevices = std::get<0>(foundLostDevicesTuple);
828  auto lostDevices = std::get<1>(foundLostDevicesTuple);
829  allFoundDevices.reserve(allFoundDevices.size() + foundDevices.size());
830  std::move(std::begin(foundDevices), std::end(foundDevices), std::back_inserter(allFoundDevices));
831  allLostDevices.reserve(allLostDevices.size() + lostDevices.size());
832  std::move(std::begin(lostDevices), std::end(lostDevices), std::back_inserter(allLostDevices));
833  }
834 
835  // We trigger all callbacks
836  for (const auto& foundSystem : allFoundSystems)
837  {
838  TriggerSystemFoundCallbacks(foundSystem);
839  }
840 
841  for (const auto& foundInterface : allFoundInterfaces)
842  {
843  TriggerInterfaceFoundCallbacks(foundInterface);
844  }
845  std::unordered_set<std::string> allLostInterfacesLookUp;
846  for (const auto& lostInterfaceKey : allLostInterfaces)
847  {
848  TriggerInterfaceLostCallbacks(lostInterfaceKey);
849  allLostInterfacesLookUp.emplace(lostInterfaceKey);
850  }
851 
852  for (const auto& foundDevice : allFoundDevices)
853  {
854  TriggerDeviceFoundCallbacks(foundDevice);
855  }
856  GetLostDevicesFromLostInterfaces(allLostInterfacesLookUp, allLostDevices);
857  for (const auto& lostDeviceKey : allLostDevices)
858  {
859  TriggerDeviceLostCallbacks(lostDeviceKey);
860  }
861 
862  // We apply the update changes to our internal lists
863  {
864  std::lock_guard<std::mutex> lock(m_systemsMutex);
865  std::lock_guard<std::mutex> lock2(m_interfacesMutex);
866  std::lock_guard<std::mutex> lock3(m_devicesMutex);
867 
868  m_systems.reserve(m_systems.size() + allFoundSystems.size());
869  std::move(std::begin(allFoundSystems), std::end(allFoundSystems), std::back_inserter(m_systems));
870 
871  for (const auto& lostInterfaceKey : allLostInterfaces)
872  {
873  m_interfaces.erase(std::find_if(std::begin(m_interfaces), std::end(m_interfaces),
874  [&lostInterfaceKey](const std::shared_ptr<const core::Interface>& interfaceToCheck) -> bool {
875  return interfaceToCheck->Key() == lostInterfaceKey;
876  }));
877  }
878  m_interfaces.reserve(m_interfaces.size() + allFoundInterfaces.size());
879  std::move(std::begin(allFoundInterfaces), std::end(allFoundInterfaces), std::back_inserter(m_interfaces));
880 
881  for (const auto& lostDeviceKey : allLostDevices)
882  {
883  m_devices.erase(std::find_if(std::begin(m_devices), std::end(m_devices),
884  [&lostDeviceKey](const std::shared_ptr<core::DeviceDescriptor>& deviceToCheck) -> bool {
885  return deviceToCheck->Key() == lostDeviceKey;
886  }));
887  }
888  m_devices.reserve(m_devices.size() + allFoundDevices.size());
889  std::move(std::begin(allFoundDevices), std::end(allFoundDevices), std::back_inserter(m_devices));
890  }
891 }
892 
893 inline void DeviceManager::Reset(ResetPolicy resetPolicy)
894 {
895  std::lock_guard<std::mutex> lockUpdate(m_updateMutex);
896 
897  if (resetPolicy == ResetPolicy::ErrorOnOpenDevices)
898  {
899  // check if any devices are running
900  CheckDevicesOpened();
901  }
902 
903  {
904  std::lock_guard<std::mutex> lock(m_systemsMutex);
905  std::lock_guard<std::mutex> lock2(m_interfacesMutex);
906  std::lock_guard<std::mutex> lock3(m_devicesMutex);
907 
908  for (const auto& lostDevice : m_devices)
909  {
910  TriggerDeviceLostCallbacks(lostDevice->Key());
911  }
912  m_devices.clear();
913 
914  for (const auto& lostInterface : m_interfaces)
915  {
916  TriggerInterfaceLostCallbacks(lostInterface->Key());
917  }
918  m_interfaces.clear();
919 
920  m_systems.clear();
921  m_producerLibraries.clear();
922  }
923 
924  {
925  std::lock_guard<std::mutex> lock(m_producerLibrariesToAddMutex);
926  m_producerLibrariesToAdd.clear();
927  }
928 }
929 
930 inline void DeviceManager::CheckDevicesOpened() const
931 {
932  size_t openDevicesFound = 0;
933  std::string deviceDisplayNames;
934 
935  {
936  std::lock_guard<std::mutex> lock(m_openedDevicesMutex);
937 
938  for (const auto& openedDevice : m_openedDevices)
939  {
940  auto openDevice = openedDevice.device.lock();
941  if (openDevice)
942  {
943  ++openDevicesFound;
944  deviceDisplayNames += openedDevice.displayName;
945  deviceDisplayNames += " ";
946  }
947  }
948  }
949 
950  if (openDevicesFound > 0)
951  {
953  "Can't reset the device manager while there are devices open. The following devices ("
954  + std::to_string(openDevicesFound) + ") are open: " + deviceDisplayNames);
955  }
956 }
957 
959 {
960  return m_interfaceUpdateTimeout_ms;
961 }
962 
964 {
965  m_interfaceUpdateTimeout_ms = timeout_ms;
966 }
967 
969 {
970  return m_deviceUpdateTimeout_ms;
971 }
972 
974 {
975  m_deviceUpdateTimeout_ms = timeout_ms;
976 }
977 
978 inline std::vector<std::shared_ptr<const core::System>> DeviceManager::Systems() const
979 {
980  std::lock_guard<std::mutex> lock(m_systemsMutex);
981 
982  return m_systems;
983 }
984 
985 inline std::vector<std::shared_ptr<const core::Interface>> DeviceManager::Interfaces() const
986 {
987  std::lock_guard<std::mutex> lock(m_interfacesMutex);
988 
989  return m_interfaces;
990 }
991 
992 inline std::vector<std::shared_ptr<core::DeviceDescriptor>> DeviceManager::Devices() const
993 {
994  std::lock_guard<std::mutex> lock(m_devicesMutex);
995 
996  return m_devices;
997 }
998 
1000  const DeviceManager::SystemFoundCallback& callback)
1001 {
1002  return m_systemFoundCallbackManager.RegisterCallback(callback);
1003 }
1004 
1006 {
1007  m_systemFoundCallbackManager.UnregisterCallback(callbackHandle);
1008 }
1009 
1011  const DeviceManager::InterfaceFoundCallback& callback)
1012 {
1013  return m_interfaceFoundCallbackManager.RegisterCallback(callback);
1014 }
1015 
1017 {
1018  m_interfaceFoundCallbackManager.UnregisterCallback(callbackHandle);
1019 }
1020 
1022  const DeviceManager::InterfaceLostCallback& callback)
1023 {
1024  return m_interfaceLostCallbackManager.RegisterCallback(callback);
1025 }
1026 
1028 {
1029  m_interfaceLostCallbackManager.UnregisterCallback(callbackHandle);
1030 }
1031 
1033  const DeviceManager::DeviceFoundCallback& callback)
1034 {
1035  return m_deviceFoundCallbackManager.RegisterCallback(callback);
1036 }
1037 
1039 {
1040  m_deviceFoundCallbackManager.UnregisterCallback(callbackHandle);
1041 }
1042 
1044  const DeviceManager::DeviceLostCallback& callback)
1045 {
1046  return m_deviceLostCallbackManager.RegisterCallback(callback);
1047 }
1048 
1050 {
1051  m_deviceLostCallbackManager.UnregisterCallback(callbackHandle);
1052 }
1053 
1054 inline void DeviceManager::GetLostDevicesFromLostInterfaces(
1055  const std::unordered_set<std::string>& lostInterfaces, std::vector<std::string>& lostDevices)
1056 {
1057  std::lock_guard<std::mutex> lock(m_devicesMutex);
1058 
1059  for (const auto& device : m_devices)
1060  {
1061  if (lostInterfaces.count(device->ParentInterface()->Key()))
1062  {
1063  lostDevices.emplace_back(device->Key());
1064  }
1065  }
1066 }
1067 
1068 inline void DeviceManager::TriggerSystemFoundCallbacks(const std::shared_ptr<const core::System>& foundSystem) const
1069 {
1070  m_systemFoundCallbackManager.TriggerCallbacks(foundSystem);
1071 }
1072 
1073 inline void DeviceManager::TriggerInterfaceFoundCallbacks(
1074  const std::shared_ptr<const core::Interface>& foundInterface) const
1075 {
1076  m_interfaceFoundCallbackManager.TriggerCallbacks(foundInterface);
1077 }
1078 
1079 inline void DeviceManager::TriggerInterfaceLostCallbacks(const std::string& lostInterfaceKey) const
1080 {
1081  m_interfaceLostCallbackManager.TriggerCallbacks(lostInterfaceKey);
1082 }
1083 
1084 inline void DeviceManager::TriggerDeviceFoundCallbacks(const std::shared_ptr<core::DeviceDescriptor>& foundDevice) const
1085 {
1086  m_deviceFoundCallbackManager.TriggerCallbacks(foundDevice);
1087 }
1088 
1089 inline void DeviceManager::TriggerDeviceLostCallbacks(const std::string& lostDeviceKey) const
1090 {
1091  m_deviceLostCallbackManager.TriggerCallbacks(lostDeviceKey);
1092 }
1093 
1094 } /* namespace peak */
std::function< void(const std::string &errorDescription)> UpdateErrorCallback
Definition: peak_device_manager.hpp:108
void AddProducerLibrary(const std::string &ctiPath)
Adds the given producer library (CTI).
Definition: peak_device_manager.hpp:566
std::function< void(const std::string &lostInterfaceKey)> InterfaceLostCallback
Definition: peak_device_manager.hpp:96
static std::shared_ptr< ProducerLibrary > Open(const std::string &ctiPath)
Opens the given producer library (CTI).
Definition: peak_producer_library.hpp:109
std::vector< std::shared_ptr< core::DeviceDescriptor > > Devices() const
Returns the found devices.
Definition: peak_device_manager.hpp:992
void SetDeviceUpdateTimeout(core::Timeout timeout_ms)
Sets the device update timeout.
Definition: peak_device_manager.hpp:973
UpdatePolicy
Enum holding the possible update policies.
Definition: peak_device_manager.hpp:75
ResetPolicy
Enum holding the possible reset policies.
Definition: peak_device_manager.hpp:81
The "peak" namespace directly contains convenience functionality like the DeviceManager as well as th...
Definition: peak_dynamic_loader.h:32
DeviceLostCallbackHandle RegisterDeviceLostCallback(const DeviceLostCallback &callback)
Registers a callback for signaling a lost device.
Definition: peak_device_manager.hpp:1043
The exception thrown for signaling that the library was not initialized.
Definition: peak_exception.hpp:123
std::function< void(const std::shared_ptr< const core::Interface > &foundInterface)> InterfaceFoundCallback
Definition: peak_device_manager.hpp:92
std::vector< std::shared_ptr< const core::Interface > > Interfaces() const
Returns the found and opened interfaces.
Definition: peak_device_manager.hpp:985
InterfaceLostCallback * InterfaceLostCallbackHandle
Definition: peak_device_manager.hpp:98
std::function< void(const std::shared_ptr< const core::System > &foundSystem)> SystemFoundCallback
Definition: peak_device_manager.hpp:88
SystemFoundCallbackHandle RegisterSystemFoundCallback(const SystemFoundCallback &callback)
Registers a callback for signaling a found system.
Definition: peak_device_manager.hpp:999
void Reset(ResetPolicy resetPolicy=ResetPolicy::ErrorOnOpenDevices)
Resets the DeviceManager.
Definition: peak_device_manager.hpp:893
void UnregisterSystemFoundCallback(SystemFoundCallbackHandle callbackHandle)
Unregisters a system found callback.
Definition: peak_device_manager.hpp:1005
A collection of global library functions.
Definition: peak_library.hpp:30
core::Timeout InterfaceUpdateTimeout() const
Returns the interface update timeout.
Definition: peak_device_manager.hpp:958
void UnregisterInterfaceFoundCallback(InterfaceFoundCallbackHandle callbackHandle)
Unregisters a interface found callback.
Definition: peak_device_manager.hpp:1016
InterfaceFoundCallbackHandle RegisterInterfaceFoundCallback(const InterfaceFoundCallback &callback)
Registers a callback for signaling a found interface.
Definition: peak_device_manager.hpp:1010
void Update(UpdatePolicy updatePolicy=UpdatePolicy::ScanEnvironmentForProducerLibraries, const UpdateErrorCallback &errorCallback=UpdateErrorCallback())
Starts an update.
Definition: peak_device_manager.hpp:573
static std::vector< std::string > CollectCTIPaths()
Collects producer library paths found in the current environment.
Definition: peak_environment_inspector.hpp:71
DeviceLostCallback * DeviceLostCallbackHandle
Definition: peak_device_manager.hpp:106
Represents a timeout value in milliseconds.
Definition: peak_timeout.hpp:30
The exception thrown for internal errors.
Definition: peak_exception.hpp:57
The base class for all exceptions thrown by the library.
Definition: peak_exception.hpp:25
DeviceFoundCallbackHandle RegisterDeviceFoundCallback(const DeviceFoundCallback &callback)
Registers a callback for signaling a found device.
Definition: peak_device_manager.hpp:1032
The global DeviceManager (singleton) searches all installed producer libraries (*.cti) and enumerates the modules contained in them.
Definition: peak_device_manager.hpp:71
std::function< void(const std::shared_ptr< core::DeviceDescriptor > &foundDevice)> DeviceFoundCallback
Definition: peak_device_manager.hpp:100
static DeviceManager & Instance()
Returns the global DeviceManager.
Definition: peak_device_manager.hpp:556
InterfaceLostCallbackHandle RegisterInterfaceLostCallback(const InterfaceLostCallback &callback)
Registers a callback for signaling a lost interface.
Definition: peak_device_manager.hpp:1021
std::function< void(const std::string &lostDeviceKey)> DeviceLostCallback
Definition: peak_device_manager.hpp:104
void UnregisterDeviceLostCallback(DeviceLostCallbackHandle callbackHandle)
Unregisters a device lost callback.
Definition: peak_device_manager.hpp:1049
SystemFoundCallback * SystemFoundCallbackHandle
Definition: peak_device_manager.hpp:90
The exception thrown for signaling a feature is not available in the device.
Definition: peak_exception.hpp:97
InterfaceFoundCallback * InterfaceFoundCallbackHandle
Definition: peak_device_manager.hpp:94
DeviceFoundCallback * DeviceFoundCallbackHandle
Definition: peak_device_manager.hpp:102
std::vector< std::shared_ptr< const core::System > > Systems() const
Returns the found and opened systems.
Definition: peak_device_manager.hpp:978
void UnregisterInterfaceLostCallback(InterfaceLostCallbackHandle callbackHandle)
Unregisters an interface lost callback.
Definition: peak_device_manager.hpp:1027
core::Timeout DeviceUpdateTimeout() const
Returns the device update timeout.
Definition: peak_device_manager.hpp:968
void UnregisterDeviceFoundCallback(DeviceFoundCallbackHandle callbackHandle)
Unregisters a device found callback.
Definition: peak_device_manager.hpp:1038
void SetInterfaceUpdateTimeout(core::Timeout timeout_ms)
Sets the interface update timeout.
Definition: peak_device_manager.hpp:963