IDS peak genericC++  v1.6.2
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::recursive_mutex m_interfacesMutex;
447  mutable std::recursive_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  if (m_instance == nullptr)
554  {
555  throw core::NotInitializedException("Library is not initialized. Call peak::Library::Initalize() first!");
556  }
557  return *m_instance;
558 }
559 
561 {
562  return DeviceManager::LifetimeTracker<>::Instance();
563 }
564 
565 inline DeviceManager::~DeviceManager()
566 {
568 }
569 
570 inline void DeviceManager::AddProducerLibrary(const std::string& ctiPath)
571 {
572  std::lock_guard<std::mutex> lock(m_producerLibrariesToAddMutex);
573 
574  m_producerLibrariesToAdd.emplace_back(ctiPath);
575 }
576 
577 inline void DeviceManager::Update(UpdatePolicy updatePolicy /*= UpdatePolicy::ScanEnvironmentForProducerLibraries*/,
578  const UpdateErrorCallback& errorCallback /*= UpdateErrorCallback()*/)
579 {
580  std::lock_guard<std::mutex> lockUpdate(m_updateMutex);
581 
582  std::vector<std::shared_ptr<core::System>> allFoundSystems;
583  std::vector<std::shared_ptr<core::Interface>> allFoundInterfaces;
584  std::vector<std::string> allLostInterfaces;
585  std::vector<std::shared_ptr<core::DeviceDescriptor>> allFoundDevices;
586  std::vector<std::string> allLostDevices;
587 
588  auto interfaceUpdateTimeout_ms = m_interfaceUpdateTimeout_ms.load();
589  auto deviceUpdateTimeout_ms = m_deviceUpdateTimeout_ms.load();
590 
591  std::vector<std::string> ctiPaths;
592  // We look for all producer libraries in the current environment if we have to
594  {
596  }
597  // We look for the manually added producer libraries
598  {
599  std::lock_guard<std::mutex> lock(m_producerLibrariesToAddMutex);
600 
601  ctiPaths.reserve(ctiPaths.size() + m_producerLibrariesToAdd.size());
602  std::move(
603  std::begin(m_producerLibrariesToAdd), std::end(m_producerLibrariesToAdd), std::back_inserter(ctiPaths));
604 
605  m_producerLibrariesToAdd.clear();
606  }
607  for (const auto& ctiPath : ctiPaths)
608  {
609  if (!m_producerLibraries.count(ctiPath))
610  {
611  try
612  {
613  auto producerLibrary = core::ProducerLibrary::Open(ctiPath);
614  auto system = producerLibrary->System()->OpenSystem();
615 
616  m_producerLibraries.emplace(ctiPath, producerLibrary);
617  allFoundSystems.emplace_back(system);
618  }
619  catch (const core::NotAvailableException&)
620  {
621  // TL not available or not supported.
622  continue;
623  }
624  catch (const core::NotInitializedException&)
625  {
626  // TODO: check this on creation of DeviceManager?
627  throw; // if this exception occurs, nothing else will work. so we stop here
628  }
629  catch (const core::Exception& ex)
630  {
631  if (errorCallback)
632  {
633  try
634  {
635  errorCallback("[CTI - " + ctiPath + "]: " + ex.what());
636  }
637  catch (...)
638  {}
639  }
640  }
641  }
642  }
643 
644  auto interfaceUpdateFunc = [&interfaceUpdateTimeout_ms, &errorCallback](const std::shared_ptr<core::System>& system)
645  -> std::tuple<std::vector<std::shared_ptr<core::Interface>>, std::vector<std::string>> {
646  std::vector<std::shared_ptr<core::Interface>> foundInterfaces;
647  std::vector<std::string> lostInterfaces;
648 
649  try
650  {
651  auto foundCallbackHandle = system->RegisterInterfaceFoundCallback(
652  [&foundInterfaces](const std::shared_ptr<core::InterfaceDescriptor>& foundInterface) {
653  foundInterfaces.emplace_back(foundInterface->OpenInterface());
654  });
655  auto const foundCallbackCleanupGuard = makeRAIIGuard([system, &foundCallbackHandle]() noexcept {
656  try
657  {
658  system->UnregisterInterfaceFoundCallback(foundCallbackHandle);
659  }
660  catch (const core::Exception&)
661  {
662  std::terminate();
663  }
664  });
665 
666  auto keysById = std::unordered_map<std::string, std::string>();
667  for (const auto& iface : system->Interfaces())
668  {
669  keysById.emplace(iface->ID(), iface->Key());
670  }
671  auto lostCallbackHandle = system->RegisterInterfaceLostCallback(
672  [&lostInterfaces, &keysById](const std::string& lostInterfaceId) {
673  auto idKeyPairIt = keysById.find(lostInterfaceId);
674 
675  if (idKeyPairIt != keysById.end())
676  {
677  lostInterfaces.emplace_back((*idKeyPairIt).second);
678  }
679  });
680  auto const lostCallbackCleanupGuard = makeRAIIGuard([system, &lostCallbackHandle]() noexcept {
681  try
682  {
683  system->UnregisterInterfaceLostCallback(lostCallbackHandle);
684  }
685  catch (const core::Exception&)
686  {
687  std::terminate();
688  }
689  });
690 
691  system->UpdateInterfaces(interfaceUpdateTimeout_ms);
692  }
693  catch (const core::Exception& ex)
694  {
695  if (errorCallback)
696  {
697  try
698  {
699  errorCallback("[System - " + system->Key() + "]: " + ex.what());
700  }
701  catch (...)
702  {}
703  }
704  }
705 
706  return std::make_tuple(foundInterfaces, lostInterfaces);
707  };
708 
709  // We do an update on all available systems
710  const std::launch launchPolicy =
711  std::launch::async; // switching this to std::launch::deferred makes debugging easier
712  std::vector<std::future<std::tuple<std::vector<std::shared_ptr<core::Interface>>, std::vector<std::string>>>>
713  interfaceUpdateFutures;
714  for (const auto& system : m_systems)
715  {
716  interfaceUpdateFutures.emplace_back(
717  std::async(launchPolicy, interfaceUpdateFunc, std::const_pointer_cast<core::System>(system)));
718  }
719  for (const auto& system : allFoundSystems)
720  {
721  interfaceUpdateFutures.emplace_back(std::async(launchPolicy, interfaceUpdateFunc, system));
722  }
723  for (auto& future : interfaceUpdateFutures)
724  {
725  auto foundLostInterfacesTuple = future.get();
726  auto foundInterfaces = std::get<0>(foundLostInterfacesTuple);
727  auto lostInterfaces = std::get<1>(foundLostInterfacesTuple);
728  allFoundInterfaces.reserve(allFoundInterfaces.size() + foundInterfaces.size());
729  std::move(std::begin(foundInterfaces), std::end(foundInterfaces), std::back_inserter(allFoundInterfaces));
730  allLostInterfaces.reserve(allLostInterfaces.size() + lostInterfaces.size());
731  std::move(std::begin(lostInterfaces), std::end(lostInterfaces), std::back_inserter(allLostInterfaces));
732  }
733 
734  auto deviceUpdateFunc = [this, &deviceUpdateTimeout_ms, &errorCallback](
735  const std::shared_ptr<core::Interface>& iface)
736  -> std::tuple<std::vector<std::shared_ptr<core::DeviceDescriptor>>, std::vector<std::string>> {
737  std::vector<std::shared_ptr<core::DeviceDescriptor>> foundDevices;
738  std::vector<std::string> lostDevices;
739 
740  try
741  {
742  auto foundCallbackHandle = iface->RegisterDeviceFoundCallback(
743  [this, &foundDevices](const std::shared_ptr<core::DeviceDescriptor>& foundDevice) {
744  foundDevice->RegisterDeviceOpenedCallback(
745  [this](const std::shared_ptr<core::Device>& openedDevice) {
746  std::lock_guard<std::mutex> lock(m_openedDevicesMutex);
747 
748  // clear out closed devices
749  m_openedDevices.erase(std::remove_if(std::begin(m_openedDevices), std::end(m_openedDevices),
750  [](const OpenedDevice& dev) { return dev.device.expired(); }),
751  std::end(m_openedDevices));
752 
753  // add the new one
754  OpenedDevice device;
755  device.device = openedDevice;
756  device.displayName = openedDevice->DisplayName();
757  m_openedDevices.push_back(device);
758  });
759 
760  foundDevices.emplace_back(foundDevice);
761  });
762  auto const foundCallbackCleanupGuard = makeRAIIGuard([iface, &foundCallbackHandle]() noexcept {
763  try
764  {
765  iface->UnregisterDeviceFoundCallback(foundCallbackHandle);
766  }
767  catch (const core::Exception&)
768  {
769  std::terminate();
770  }
771  });
772 
773  auto keysById = std::unordered_map<std::string, std::string>();
774  for (const auto& device : iface->Devices())
775  {
776  keysById.emplace(device->ID(), device->Key());
777  }
778  auto lostCallbackHandle = iface->RegisterDeviceLostCallback(
779  [&lostDevices, &keysById](const std::string& lostDeviceId) {
780  auto idKeyPairIt = keysById.find(lostDeviceId);
781 
782  if (idKeyPairIt != keysById.end())
783  {
784  lostDevices.emplace_back((*idKeyPairIt).second);
785  }
786  });
787  auto const lostCallbackCleanupGuard = makeRAIIGuard([iface, &lostCallbackHandle]() noexcept {
788  try
789  {
790  iface->UnregisterDeviceLostCallback(lostCallbackHandle);
791  }
792  catch (const core::Exception&)
793  {
794  std::terminate();
795  }
796  });
797 
798  iface->UpdateDevices(deviceUpdateTimeout_ms);
799  }
800  catch (const core::Exception& ex)
801  {
802  if (errorCallback)
803  {
804  try
805  {
806  errorCallback("[Interface - " + iface->Key() + "]: " + ex.what());
807  }
808  catch (...)
809  {}
810  }
811  }
812 
813  return std::make_tuple(foundDevices, lostDevices);
814  };
815 
816  // We do an update on all available interfaces
817  std::vector<std::future<std::tuple<std::vector<std::shared_ptr<core::DeviceDescriptor>>, std::vector<std::string>>>>
818  deviceUpdateFutures;
819  for (const auto& iface : m_interfaces)
820  {
821  deviceUpdateFutures.emplace_back(
822  std::async(launchPolicy, deviceUpdateFunc, std::const_pointer_cast<core::Interface>(iface)));
823  }
824  for (const auto& iface : allFoundInterfaces)
825  {
826  deviceUpdateFutures.emplace_back(std::async(launchPolicy, deviceUpdateFunc, iface));
827  }
828  for (auto& future : deviceUpdateFutures)
829  {
830  auto foundLostDevicesTuple = future.get();
831  auto foundDevices = std::get<0>(foundLostDevicesTuple);
832  auto lostDevices = std::get<1>(foundLostDevicesTuple);
833  allFoundDevices.reserve(allFoundDevices.size() + foundDevices.size());
834  std::move(std::begin(foundDevices), std::end(foundDevices), std::back_inserter(allFoundDevices));
835  allLostDevices.reserve(allLostDevices.size() + lostDevices.size());
836  std::move(std::begin(lostDevices), std::end(lostDevices), std::back_inserter(allLostDevices));
837  }
838 
839  // We apply the update changes to our internal lists
840  {
841  std::lock_guard<std::mutex> lock(m_systemsMutex);
842  std::lock_guard<std::recursive_mutex> lock2(m_interfacesMutex);
843  std::lock_guard<std::recursive_mutex> lock3(m_devicesMutex);
844 
845  m_systems.reserve(m_systems.size() + allFoundSystems.size());
846  std::copy(std::begin(allFoundSystems), std::end(allFoundSystems), std::back_inserter(m_systems));
847 
848  for (const auto& lostInterfaceKey : allLostInterfaces)
849  {
850  m_interfaces.erase(std::find_if(std::begin(m_interfaces), std::end(m_interfaces),
851  [&lostInterfaceKey](const std::shared_ptr<const core::Interface>& interfaceToCheck) -> bool {
852  return interfaceToCheck->Key() == lostInterfaceKey;
853  }));
854  }
855  m_interfaces.reserve(m_interfaces.size() + allFoundInterfaces.size());
856  std::copy(std::begin(allFoundInterfaces), std::end(allFoundInterfaces), std::back_inserter(m_interfaces));
857 
858  for (const auto& lostDeviceKey : allLostDevices)
859  {
860  m_devices.erase(std::find_if(std::begin(m_devices), std::end(m_devices),
861  [&lostDeviceKey](const std::shared_ptr<core::DeviceDescriptor>& deviceToCheck) -> bool {
862  return deviceToCheck->Key() == lostDeviceKey;
863  }));
864  }
865  m_devices.reserve(m_devices.size() + allFoundDevices.size());
866  std::copy(std::begin(allFoundDevices), std::end(allFoundDevices), std::back_inserter(m_devices));
867  }
868 
869  // We trigger all callbacks
870  for (const auto& foundSystem : allFoundSystems)
871  {
872  TriggerSystemFoundCallbacks(foundSystem);
873  }
874 
875  for (const auto& foundInterface : allFoundInterfaces)
876  {
877  TriggerInterfaceFoundCallbacks(foundInterface);
878  }
879  std::unordered_set<std::string> allLostInterfacesLookUp;
880  for (const auto& lostInterfaceKey : allLostInterfaces)
881  {
882  TriggerInterfaceLostCallbacks(lostInterfaceKey);
883  allLostInterfacesLookUp.emplace(lostInterfaceKey);
884  }
885 
886  for (const auto& foundDevice : allFoundDevices)
887  {
888  TriggerDeviceFoundCallbacks(foundDevice);
889  }
890  GetLostDevicesFromLostInterfaces(allLostInterfacesLookUp, allLostDevices);
891  for (const auto& lostDeviceKey : allLostDevices)
892  {
893  TriggerDeviceLostCallbacks(lostDeviceKey);
894  }
895 }
896 
897 inline void DeviceManager::Reset(ResetPolicy resetPolicy)
898 {
899  std::lock_guard<std::mutex> lockUpdate(m_updateMutex);
900 
901  if (resetPolicy == ResetPolicy::ErrorOnOpenDevices)
902  {
903  // check if any devices are running
904  CheckDevicesOpened();
905  }
906 
907  {
908  std::lock_guard<std::mutex> lock(m_systemsMutex);
909  std::lock_guard<std::recursive_mutex> lock2(m_interfacesMutex);
910  std::lock_guard<std::recursive_mutex> lock3(m_devicesMutex);
911 
912  {
913  auto origDevices = m_devices;
914  m_devices.clear();
915  for (const auto& lostDevice : origDevices)
916  {
917  TriggerDeviceLostCallbacks(lostDevice->Key());
918  }
919  }
920 
921  {
922  auto origInterfaces = m_interfaces;
923  m_interfaces.clear();
924  for (const auto& lostInterface : origInterfaces)
925  {
926  TriggerInterfaceLostCallbacks(lostInterface->Key());
927  }
928  }
929 
930  m_systems.clear();
931  m_producerLibraries.clear();
932  }
933 
934  {
935  std::lock_guard<std::mutex> lock(m_producerLibrariesToAddMutex);
936  m_producerLibrariesToAdd.clear();
937  }
938 }
939 
940 inline void DeviceManager::CheckDevicesOpened() const
941 {
942  size_t openDevicesFound = 0;
943  std::string deviceDisplayNames;
944 
945  {
946  std::lock_guard<std::mutex> lock(m_openedDevicesMutex);
947 
948  for (const auto& openedDevice : m_openedDevices)
949  {
950  auto openDevice = openedDevice.device.lock();
951  if (openDevice)
952  {
953  ++openDevicesFound;
954  deviceDisplayNames += openedDevice.displayName;
955  deviceDisplayNames += " ";
956  }
957  }
958  }
959 
960  if (openDevicesFound > 0)
961  {
963  "Can't reset the device manager while there are devices open. The following devices ("
964  + std::to_string(openDevicesFound) + ") are open: " + deviceDisplayNames);
965  }
966 }
967 
969 {
970  return m_interfaceUpdateTimeout_ms;
971 }
972 
974 {
975  m_interfaceUpdateTimeout_ms = timeout_ms;
976 }
977 
979 {
980  return m_deviceUpdateTimeout_ms;
981 }
982 
984 {
985  m_deviceUpdateTimeout_ms = timeout_ms;
986 }
987 
988 inline std::vector<std::shared_ptr<const core::System>> DeviceManager::Systems() const
989 {
990  std::lock_guard<std::mutex> lock(m_systemsMutex);
991 
992  return m_systems;
993 }
994 
995 inline std::vector<std::shared_ptr<const core::Interface>> DeviceManager::Interfaces() const
996 {
997  std::lock_guard<std::recursive_mutex> lock(m_interfacesMutex);
998 
999  return m_interfaces;
1000 }
1001 
1002 inline std::vector<std::shared_ptr<core::DeviceDescriptor>> DeviceManager::Devices() const
1003 {
1004  std::lock_guard<std::recursive_mutex> lock(m_devicesMutex);
1005 
1006  return m_devices;
1007 }
1008 
1010  const DeviceManager::SystemFoundCallback& callback)
1011 {
1012  return m_systemFoundCallbackManager.RegisterCallback(callback);
1013 }
1014 
1016 {
1017  m_systemFoundCallbackManager.UnregisterCallback(callbackHandle);
1018 }
1019 
1021  const DeviceManager::InterfaceFoundCallback& callback)
1022 {
1023  return m_interfaceFoundCallbackManager.RegisterCallback(callback);
1024 }
1025 
1027 {
1028  m_interfaceFoundCallbackManager.UnregisterCallback(callbackHandle);
1029 }
1030 
1032  const DeviceManager::InterfaceLostCallback& callback)
1033 {
1034  return m_interfaceLostCallbackManager.RegisterCallback(callback);
1035 }
1036 
1038 {
1039  m_interfaceLostCallbackManager.UnregisterCallback(callbackHandle);
1040 }
1041 
1043  const DeviceManager::DeviceFoundCallback& callback)
1044 {
1045  return m_deviceFoundCallbackManager.RegisterCallback(callback);
1046 }
1047 
1049 {
1050  m_deviceFoundCallbackManager.UnregisterCallback(callbackHandle);
1051 }
1052 
1054  const DeviceManager::DeviceLostCallback& callback)
1055 {
1056  return m_deviceLostCallbackManager.RegisterCallback(callback);
1057 }
1058 
1060 {
1061  m_deviceLostCallbackManager.UnregisterCallback(callbackHandle);
1062 }
1063 
1064 inline void DeviceManager::GetLostDevicesFromLostInterfaces(
1065  const std::unordered_set<std::string>& lostInterfaces, std::vector<std::string>& lostDevices)
1066 {
1067  std::lock_guard<std::recursive_mutex> lock(m_devicesMutex);
1068 
1069  for (const auto& device : m_devices)
1070  {
1071  if (lostInterfaces.count(device->ParentInterface()->Key()))
1072  {
1073  lostDevices.emplace_back(device->Key());
1074  }
1075  }
1076 }
1077 
1078 inline void DeviceManager::TriggerSystemFoundCallbacks(const std::shared_ptr<const core::System>& foundSystem) const
1079 {
1080  m_systemFoundCallbackManager.TriggerCallbacks(foundSystem);
1081 }
1082 
1083 inline void DeviceManager::TriggerInterfaceFoundCallbacks(
1084  const std::shared_ptr<const core::Interface>& foundInterface) const
1085 {
1086  m_interfaceFoundCallbackManager.TriggerCallbacks(foundInterface);
1087 }
1088 
1089 inline void DeviceManager::TriggerInterfaceLostCallbacks(const std::string& lostInterfaceKey) const
1090 {
1091  m_interfaceLostCallbackManager.TriggerCallbacks(lostInterfaceKey);
1092 }
1093 
1094 inline void DeviceManager::TriggerDeviceFoundCallbacks(const std::shared_ptr<core::DeviceDescriptor>& foundDevice) const
1095 {
1096  m_deviceFoundCallbackManager.TriggerCallbacks(foundDevice);
1097 }
1098 
1099 inline void DeviceManager::TriggerDeviceLostCallbacks(const std::string& lostDeviceKey) const
1100 {
1101  m_deviceLostCallbackManager.TriggerCallbacks(lostDeviceKey);
1102 }
1103 
1104 } /* 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:570
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:1002
void SetDeviceUpdateTimeout(core::Timeout timeout_ms)
Sets the device update timeout.
Definition: peak_device_manager.hpp:983
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:1053
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:995
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:1009
void Reset(ResetPolicy resetPolicy=ResetPolicy::ErrorOnOpenDevices)
Resets the DeviceManager.
Definition: peak_device_manager.hpp:897
void UnregisterSystemFoundCallback(SystemFoundCallbackHandle callbackHandle)
Unregisters a system found callback.
Definition: peak_device_manager.hpp:1015
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:968
void UnregisterInterfaceFoundCallback(InterfaceFoundCallbackHandle callbackHandle)
Unregisters a interface found callback.
Definition: peak_device_manager.hpp:1026
InterfaceFoundCallbackHandle RegisterInterfaceFoundCallback(const InterfaceFoundCallback &callback)
Registers a callback for signaling a found interface.
Definition: peak_device_manager.hpp:1020
void Update(UpdatePolicy updatePolicy=UpdatePolicy::ScanEnvironmentForProducerLibraries, const UpdateErrorCallback &errorCallback=UpdateErrorCallback())
Starts an update.
Definition: peak_device_manager.hpp:577
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:1042
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:560
InterfaceLostCallbackHandle RegisterInterfaceLostCallback(const InterfaceLostCallback &callback)
Registers a callback for signaling a lost interface.
Definition: peak_device_manager.hpp:1031
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:1059
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:988
void UnregisterInterfaceLostCallback(InterfaceLostCallbackHandle callbackHandle)
Unregisters an interface lost callback.
Definition: peak_device_manager.hpp:1037
core::Timeout DeviceUpdateTimeout() const
Returns the device update timeout.
Definition: peak_device_manager.hpp:978
void UnregisterDeviceFoundCallback(DeviceFoundCallbackHandle callbackHandle)
Unregisters a device found callback.
Definition: peak_device_manager.hpp:1048
void SetInterfaceUpdateTimeout(core::Timeout timeout_ms)
Sets the interface update timeout.
Definition: peak_device_manager.hpp:973