IDS peak genericC++ v1.17.0
Loading...
Searching...
No Matches
peak_device_manager.hpp
Go to the documentation of this file.
1
6
7#pragma once
8
15#include <peak/generic/peak_t_callback_manager.hpp>
22#include <utility>
23
24
25#include <type_traits>
26#include <unordered_map>
27#include <unordered_set>
28#include <algorithm>
29#include <atomic>
30#include <cstdlib>
31#include <exception>
32#include <functional>
33#include <future>
34#include <iterator>
35#include <memory>
36#include <mutex>
37#include <new>
38#include <utility>
39#include <vector>
40
41
42namespace peak
43{
44
72
73class DeviceManager final
74{
75public:
85
95
97 using SystemFoundCallback = std::function<void(const std::shared_ptr<const core::System>& foundSystem)>;
98
101
103 using InterfaceFoundCallback = std::function<void(const std::shared_ptr<const core::Interface>& foundInterface)>;
104
107
109 using InterfaceLostCallback = std::function<void(const std::string& lostInterfaceKey)>;
110
113
115 using DeviceFoundCallback = std::function<void(const std::shared_ptr<core::DeviceDescriptor>& foundDevice)>;
116
119
121 using DeviceLostCallback = std::function<void(const std::string& lostDeviceKey)>;
122
125
128 std::function<void(const std::shared_ptr<core::DeviceDescriptor>& disconnectedDevice)>;
129
132
135 std::function<void(const std::shared_ptr<core::DeviceDescriptor>& reconnectedDevice,
136 core::DeviceReconnectInformation reconnectInformation)>;
137
140
142 using DeviceListChangedCallback = std::function<void()>;
143
146
148 using UpdateErrorCallback = std::function<void(const std::string& errorDescription)>;
149
156
172 void AddProducerLibrary(const std::string& ctiPath);
173
188 void RemoveProducerLibrary(const std::string& ctiPath);
189
209 void AddProducerLibrary(const std::shared_ptr<core::ProducerLibrary>& library);
210
225 void RemoveProducerLibrary(const std::shared_ptr<core::ProducerLibrary>& library);
226
248 const UpdateErrorCallback& errorCallback = UpdateErrorCallback());
249
269
280
295
306
320 void SetDeviceUpdateTimeout(core::Timeout timeout_ms);
321
333 PEAK_COMMON_NO_DISCARD std::vector<std::shared_ptr<const core::System>> Systems() const;
334
346 PEAK_COMMON_NO_DISCARD std::vector<std::shared_ptr<const core::Interface>> Interfaces() const;
347
359 PEAK_COMMON_NO_DISCARD std::vector<std::shared_ptr<core::DeviceDescriptor>> Devices() const;
360
374 PEAK_COMMON_NO_DISCARD std::shared_ptr<core::DeviceDescriptor> FirstAvailableDevice(
375 core::DeviceAccessType access) const;
376
391 template <typename Pred>
392 PEAK_COMMON_NO_DISCARD std::vector<std::shared_ptr<core::DeviceDescriptor>> FindDevices(Pred predicate) const;
393
407 PEAK_COMMON_NO_DISCARD std::vector<std::shared_ptr<core::DeviceDescriptor>> AvailableDevices(
408 core::DeviceAccessType access) const;
409
427
440
458
471
489
502
520
533
551
564
580
593
609
622
638
651
652 DeviceManager(const DeviceManager& other) = delete;
653 DeviceManager& operator=(const DeviceManager& other) = delete;
654
655private:
656 friend class Library;
657
658 DeviceManager() = default;
660
661 void GetLostDevicesFromLostInterfaces(
662 const std::vector<std::string>& lostInterfaces, std::vector<std::string>& lostDevices);
663
664 void TriggerSystemFoundCallbacks(const std::shared_ptr<const core::System>& foundSystem) const;
665 void TriggerInterfaceFoundCallbacks(const std::shared_ptr<const core::Interface>& foundInterface) const;
666 void TriggerInterfaceLostCallbacks(const std::string& lostInterfaceKey) const;
667 void TriggerDeviceFoundCallbacks(const std::shared_ptr<core::DeviceDescriptor>& foundDevice) const;
668 void TriggerDeviceLostCallbacks(const std::string& lostDeviceKey) const;
669
670 void AddSystemCallbacks(const std::shared_ptr<core::System>& addSystem);
671 void RemoveSystemCallbacks(const std::shared_ptr<core::System>& removeSystem);
672 void AddInterfaceCallbacks(const std::shared_ptr<core::Interface>& addInterface);
673 void RemoveInterfaceCallbacks(const std::shared_ptr<core::Interface>& removeInterface);
674
675 void CheckDevicesOpened() const;
676
677 std::mutex m_updateMutex;
678 std::atomic<core::Timeout> m_interfaceUpdateTimeout_ms{ 100 };
679 std::atomic<core::Timeout> m_deviceUpdateTimeout_ms{ 300 };
680
681 std::vector<std::string> m_producerLibrariesToAdd;
682
683 std::unordered_map<std::string, std::shared_ptr<core::ProducerLibrary>> m_producerLibraries;
684 std::vector<std::shared_ptr<const core::System>> m_systems;
685 std::vector<std::shared_ptr<const core::Interface>> m_interfaces;
686 std::vector<std::shared_ptr<core::DeviceDescriptor>> m_devices;
687
688 struct SystemCallbackContainer
689 {
690 SystemCallbackContainer(
692 : foundCallbackHandle(foundHandle)
693 , lostCallbackHandle(lostHandle)
694 {}
695 ~SystemCallbackContainer() = default;
696 SystemCallbackContainer(const SystemCallbackContainer&) = delete;
697 SystemCallbackContainer& operator=(const SystemCallbackContainer&) = delete;
698
699 SystemCallbackContainer(SystemCallbackContainer&& a) noexcept
700 {
701 std::lock_guard<std::mutex> lock(a.mutex);
702
703 std::swap(foundCallbackHandle, a.foundCallbackHandle);
704 std::swap(lostCallbackHandle, a.lostCallbackHandle);
705 }
706
707 SystemCallbackContainer& operator=(SystemCallbackContainer&& a) noexcept
708 {
709 std::lock(a.mutex, mutex);
710
711 std::lock_guard<std::mutex> lock1(a.mutex, std::adopt_lock);
712 std::lock_guard<std::mutex> lock2(mutex, std::adopt_lock);
713
714 std::swap(foundCallbackHandle, a.foundCallbackHandle);
715 std::swap(lostCallbackHandle, a.lostCallbackHandle);
716
717 return *this;
718 }
719
720 mutable std::mutex mutex;
721 core::System::InterfaceFoundCallbackHandle foundCallbackHandle{};
722 InterfaceLostCallbackHandle lostCallbackHandle{};
723
724 std::vector<std::shared_ptr<core::Interface>> foundInterfaces;
725 std::vector<std::string> lostInterfaces;
726
727 // TL reports interface lost only with interface id part
728 // in order to get the full interface key we need to map it
729 std::unordered_map<std::string, std::string> interfaceIdKeyMap;
730 };
731
732 struct InterfaceCallbackContainer
733 {
734 InterfaceCallbackContainer(DeviceFoundCallbackHandle foundHandle, DeviceLostCallbackHandle lostHandle,
735 DeviceDisconnectedCallbackHandle disconnectedHandle, DeviceReconnectedCallbackHandle reconnectedHandle,
736 DeviceListChangedCallbackHandle listChangedHandle)
737 : foundCallbackHandle(foundHandle)
738 , lostCallbackHandle(lostHandle)
739 , disconnectedCallbackHandle(disconnectedHandle)
740 , reconnectedCallbackHandle(reconnectedHandle)
741 , deviceListChangedCallbackHandle(listChangedHandle)
742 {}
743
744 ~InterfaceCallbackContainer() = default;
745 InterfaceCallbackContainer(const InterfaceCallbackContainer&) = delete;
746 InterfaceCallbackContainer& operator=(const InterfaceCallbackContainer&) = delete;
747
748 InterfaceCallbackContainer(InterfaceCallbackContainer&& a) noexcept
749 {
750 std::lock_guard<std::mutex> lock(a.mutex);
751
752 std::swap(foundCallbackHandle, a.foundCallbackHandle);
753 std::swap(lostCallbackHandle, a.lostCallbackHandle);
754 std::swap(disconnectedCallbackHandle, a.disconnectedCallbackHandle);
755 std::swap(reconnectedCallbackHandle, a.reconnectedCallbackHandle);
756 std::swap(deviceListChangedCallbackHandle, a.deviceListChangedCallbackHandle);
757 }
758
759 InterfaceCallbackContainer& operator=(InterfaceCallbackContainer&& a) noexcept
760 {
761 std::lock(a.mutex, mutex);
762
763 std::lock_guard<std::mutex> lock1(a.mutex, std::adopt_lock);
764 std::lock_guard<std::mutex> lock2(mutex, std::adopt_lock);
765
766 std::swap(foundCallbackHandle, a.foundCallbackHandle);
767 std::swap(lostCallbackHandle, a.lostCallbackHandle);
768 std::swap(disconnectedCallbackHandle, a.disconnectedCallbackHandle);
769 std::swap(reconnectedCallbackHandle, a.reconnectedCallbackHandle);
770 std::swap(deviceListChangedCallbackHandle, a.deviceListChangedCallbackHandle);
771
772 return *this;
773 }
774
775 mutable std::mutex mutex;
776 DeviceFoundCallbackHandle foundCallbackHandle{};
777 DeviceLostCallbackHandle lostCallbackHandle{};
778 DeviceDisconnectedCallbackHandle disconnectedCallbackHandle{};
779 DeviceReconnectedCallbackHandle reconnectedCallbackHandle{};
780 DeviceListChangedCallbackHandle deviceListChangedCallbackHandle{};
781
782 std::vector<std::shared_ptr<core::DeviceDescriptor>> foundDevices;
783 std::vector<std::string> lostDevices;
784
785 // TL reports device lost only with device id part
786 // in order to get the full device key we need to map it
787 std::unordered_map<std::string, std::string> deviceIdKeyMap;
788 };
789
790 mutable std::mutex m_callbackContainerMutex;
791 std::unordered_map<std::string, SystemCallbackContainer> m_systemCallbackContainers;
792 std::unordered_map<std::string, InterfaceCallbackContainer> m_interfaceCallbackContainers;
793
794 struct OpenedDevice
795 {
796 std::weak_ptr<core::Device> device{};
797 std::string displayName;
798 };
799 std::vector<OpenedDevice> m_openedDevices;
800
801 core::TTriggerCallbackManager<SystemFoundCallbackHandle, SystemFoundCallback> m_systemFoundCallbackManager;
802 core::TTriggerCallbackManager<InterfaceFoundCallbackHandle, InterfaceFoundCallback> m_interfaceFoundCallbackManager;
803 core::TTriggerCallbackManager<InterfaceLostCallbackHandle, InterfaceLostCallback> m_interfaceLostCallbackManager;
804 core::TTriggerCallbackManager<DeviceFoundCallbackHandle, DeviceFoundCallback> m_deviceFoundCallbackManager;
805 core::TTriggerCallbackManager<DeviceLostCallbackHandle, DeviceLostCallback> m_deviceLostCallbackManager;
806 core::TTriggerCallbackManager<DeviceDisconnectedCallbackHandle, DeviceDisconnectedCallback>
807 m_deviceDisconnectedCallbackManager;
808 core::TTriggerCallbackManager<DeviceReconnectedCallbackHandle, DeviceReconnectedCallback>
809 m_deviceReconnectedCallbackManager;
810 core::TTriggerCallbackManager<DeviceListChangedCallbackHandle, DeviceListChangedCallback>
811 m_deviceListChangedCallbackManager;
812
813 std::mutex m_producerLibrariesToAddMutex;
814 mutable std::mutex m_systemsMutex;
815 mutable std::recursive_mutex m_interfacesMutex;
816 mutable std::recursive_mutex m_devicesMutex;
817 mutable std::mutex m_openedDevicesMutex;
818
819#ifndef _MSC_VER
820 template <typename T,
821 typename std::enable_if<(noexcept(std::declval<T>()())
822 || (std::is_pointer<typename std::decay<T>::type>::value && __cplusplus < 201703L)
823 // NOTE pre c++17 there is no way to check whether a function pointer is noexcept
824 )
825 && std::is_same<void, decltype(std::declval<T>()())>::value && std::is_move_constructible<T>::value
826 && std::is_nothrow_move_constructible<T>::value,
827 int>::type = 0>
828#else
829 template <typename T>
830#endif
831 class RAIIGuard
832 {
833 T m_fun;
834
835 public:
836 explicit RAIIGuard(T&& fun) noexcept
837 : m_fun(std::forward<T>(fun))
838 {}
839 RAIIGuard(RAIIGuard const&) = delete;
840 RAIIGuard(RAIIGuard&& other) noexcept
841 : m_fun(std::move(other.m_fun))
842 {}
843 ~RAIIGuard() noexcept
844 {
845 m_fun();
846 }
847 };
848 template <typename T>
849 static RAIIGuard<T> makeRAIIGuard(T&& fun) noexcept
850 {
851 return { std::forward<T>(fun) };
852 }
853
854 template <typename T = DeviceManager>
855 class LifetimeTracker
856 {
857 public:
858 static void Create();
859 static void Destroy();
860 static T& Instance();
861
862 private:
863 static T* m_instance;
864 static std::mutex m_mtx;
865 static size_t m_initializedCount;
866 };
867};
868
869} /* namespace peak */
870
871/* Implementation */
872namespace peak
873{
874
875template <typename T>
876T* DeviceManager::LifetimeTracker<T>::m_instance = {};
877
878template <typename T>
879std::mutex DeviceManager::LifetimeTracker<T>::m_mtx = {};
880
881template <typename T>
882size_t DeviceManager::LifetimeTracker<T>::m_initializedCount = {};
883
884template <typename Pred>
885std::vector<std::shared_ptr<core::DeviceDescriptor>> DeviceManager::FindDevices(Pred predicate) const
886{
887 using ReturnType = decltype(predicate(std::declval<const std::shared_ptr<core::DeviceDescriptor>&>()));
888 static_assert(std::is_convertible<ReturnType, bool>::value, "Predicate result must be convertible to bool!");
889
890 const auto devices = Devices();
891 std::vector<std::shared_ptr<core::DeviceDescriptor>> result;
892
893 std::copy_if(devices.begin(), devices.end(), std::back_inserter(result), predicate);
894 return result;
895}
896
897template <typename T>
898void DeviceManager::LifetimeTracker<T>::Create()
899{
900 std::lock_guard<decltype(m_mtx)> lock{ m_mtx };
901
902 if (!m_instance)
903 {
904 m_instance = new T{};
905 }
906
907 m_initializedCount++;
908}
909
910template <typename T>
911void DeviceManager::LifetimeTracker<T>::Destroy()
912{
913 std::lock_guard<decltype(m_mtx)> lock{ m_mtx };
914
915 if (0 == m_initializedCount)
916 {
917 return;
918 }
919
920 m_initializedCount--;
921
922 if (0 == m_initializedCount)
923 {
924 if (m_instance)
925 {
926 delete m_instance;
927 m_instance = nullptr;
928 }
929 }
930}
931
932template <typename T>
933T& DeviceManager::LifetimeTracker<T>::Instance()
934{
935 if (m_instance == nullptr)
936 {
938 "Library is not initialized. Call peak::Library::Initalize() first!");
939 }
940 return *m_instance;
941}
942
944{
945 return LifetimeTracker<>::Instance();
946}
947
948inline DeviceManager::~DeviceManager()
949{
950 try
951 {
953 }
954 catch (const std::exception&)
955 {}
956}
957
958inline void DeviceManager::AddProducerLibrary(const std::string& ctiPath)
959{
960 std::lock_guard<std::mutex> lock(m_producerLibrariesToAddMutex);
961
962 m_producerLibrariesToAdd.emplace_back(ctiPath);
963}
964
965inline void DeviceManager::RemoveProducerLibrary(const std::string& ctiPath)
966{
967 auto systems = Systems();
968
969 auto it = std::find_if(systems.begin(), systems.end(),
970 [ctiPath](const std::shared_ptr<const core::System>& system) { return system->CTIFullPath() == ctiPath; });
971 if (it != systems.end())
972 {
973 RemoveProducerLibrary((*it)->ParentLibrary());
974 }
975 else
976 {
977 throw core::NotFoundException("The supplied CTI path was not found in the System list!");
978 }
979}
980
981inline void DeviceManager::RemoveProducerLibrary(const std::shared_ptr<core::ProducerLibrary>& library)
982{
983 std::lock_guard<std::mutex> lockUpdate(m_updateMutex);
984
985 std::lock(m_systemsMutex, m_interfacesMutex, m_devicesMutex);
986
987 std::lock_guard<std::mutex> lockSystem(m_systemsMutex, std::adopt_lock);
988 std::lock_guard<std::recursive_mutex> lockInterfaces(m_interfacesMutex, std::adopt_lock);
989 std::lock_guard<std::recursive_mutex> lockDevices(m_devicesMutex, std::adopt_lock);
990
991 decltype(m_devices) lostDevicesList{};
992 decltype(m_interfaces) lostInterfacesList{};
993 decltype(m_systems) lostSystemsList{};
994
995 m_devices.erase(std::remove_if(m_devices.begin(), m_devices.end(),
996 [&library, &lostDevicesList](const std::shared_ptr<core::DeviceDescriptor>& device) {
997 if (device == nullptr)
998 {
999 return false;
1000 }
1001 auto deviceLibrary = device->ParentInterface()->ParentSystem()->ParentLibrary();
1002 if (library == deviceLibrary)
1003 {
1004 lostDevicesList.emplace_back(device);
1005 return true;
1006 }
1007 return false;
1008 }),
1009 m_devices.end());
1010
1011 m_interfaces.erase(std::remove_if(m_interfaces.begin(), m_interfaces.end(),
1012 [&library, &lostInterfacesList](const std::shared_ptr<const core::Interface>& intf) {
1013 if (intf == nullptr)
1014 {
1015 return false;
1016 }
1017 auto intfLibrary = intf->ParentSystem()->ParentLibrary();
1018 if (library == intfLibrary)
1019 {
1020 lostInterfacesList.emplace_back(intf);
1021 return true;
1022 }
1023 return false;
1024 }),
1025 m_interfaces.end());
1026
1027 m_systems.erase(std::remove_if(m_systems.begin(), m_systems.end(),
1028 [&library, &lostSystemsList](const std::shared_ptr<const core::System>& system) {
1029 if (system == nullptr)
1030 {
1031 return false;
1032 }
1033 auto systemLibrary = system->ParentLibrary();
1034 if (library == systemLibrary)
1035 {
1036 lostSystemsList.emplace_back(system);
1037 return true;
1038 }
1039 return false;
1040 }),
1041 m_systems.end());
1042
1043 for (const auto& lostDevice : lostDevicesList)
1044 {
1045 TriggerDeviceLostCallbacks(lostDevice->Key());
1046 }
1047
1048 for (const auto& lostInterface : lostInterfacesList)
1049 {
1050 TriggerInterfaceLostCallbacks(lostInterface->Key());
1051 RemoveInterfaceCallbacks(std::const_pointer_cast<core::Interface>(lostInterface));
1052 }
1053
1054 for (const auto& lostSystem : lostSystemsList)
1055 {
1056 RemoveSystemCallbacks(std::const_pointer_cast<core::System>(lostSystem));
1057 }
1058
1059 for (auto it = m_producerLibraries.begin(); it != m_producerLibraries.end();)
1060 {
1061 if (it->second == library)
1062 {
1063 it = m_producerLibraries.erase(it);
1064 }
1065 else
1066 {
1067 ++it;
1068 }
1069 }
1070
1071 std::lock_guard<std::mutex> lock(m_callbackContainerMutex);
1072
1073 for (const auto& lostInterface : lostInterfacesList)
1074 {
1075 m_interfaceCallbackContainers.erase(lostInterface->Key());
1076 }
1077
1078 for (const auto& lostSystem : lostSystemsList)
1079 {
1080 m_systemCallbackContainers.erase(lostSystem->Key());
1081 }
1082}
1083
1084inline void DeviceManager::AddProducerLibrary(const std::shared_ptr<core::ProducerLibrary>& library)
1085{
1086 std::lock(m_updateMutex, m_systemsMutex);
1087
1088 std::lock_guard<std::mutex> lockUpdate(m_updateMutex, std::adopt_lock);
1089
1090 std::shared_ptr<core::System> newSystem{};
1091 {
1092 std::lock_guard<std::mutex> lockSystems(m_systemsMutex, std::adopt_lock);
1093
1094 const auto systemDescriptor = library->System();
1095 const auto ctiPath = systemDescriptor->CTIFullPath();
1096
1097 // Check if system is already added
1098 if (m_producerLibraries.count(ctiPath) == 0)
1099 {
1100 m_producerLibraries.emplace(ctiPath, library);
1101
1102 newSystem = systemDescriptor->IsOpened() ? systemDescriptor->OpenedSystem() :
1103 systemDescriptor->OpenSystem();
1104 AddSystemCallbacks(newSystem);
1105 m_systems.emplace_back(newSystem);
1106 }
1107 }
1108
1109 if (newSystem)
1110 {
1111 TriggerSystemFoundCallbacks(newSystem);
1112 }
1113}
1114
1115inline void DeviceManager::Update(UpdatePolicy updatePolicy /*= UpdatePolicy::ScanEnvironmentForProducerLibraries*/,
1116 const UpdateErrorCallback& errorCallback /*= UpdateErrorCallback()*/)
1117{
1118 std::lock_guard<std::mutex> lockUpdate(m_updateMutex);
1119
1120 std::vector<std::shared_ptr<core::System>> allFoundSystems;
1121 std::vector<std::shared_ptr<core::Interface>> allFoundInterfaces;
1122 std::vector<std::string> allLostInterfaces;
1123 std::vector<std::shared_ptr<core::DeviceDescriptor>> allFoundDevices;
1124 std::vector<std::string> allLostDevices;
1125
1126 auto interfaceUpdateTimeout_ms = m_interfaceUpdateTimeout_ms.load();
1127 auto deviceUpdateTimeout_ms = m_deviceUpdateTimeout_ms.load();
1128
1129 std::vector<std::string> ctiPaths;
1130 // We look for all producer libraries in the current environment if we have to
1132 {
1134 }
1135
1136 // We look for the manually added producer libraries
1137 {
1138 std::lock_guard<std::mutex> lock(m_producerLibrariesToAddMutex);
1139
1140 ctiPaths.reserve(ctiPaths.size() + m_producerLibrariesToAdd.size());
1141 std::move(
1142 std::begin(m_producerLibrariesToAdd), std::end(m_producerLibrariesToAdd), std::back_inserter(ctiPaths));
1143
1144 m_producerLibrariesToAdd.clear();
1145 }
1146
1147 for (const auto& ctiPath : ctiPaths)
1148 {
1149 if (m_producerLibraries.count(ctiPath) == 0)
1150 {
1151 try
1152 {
1153 auto producerLibrary = core::ProducerLibrary::Open(ctiPath);
1154 auto system = producerLibrary->System()->OpenSystem();
1155
1156 AddSystemCallbacks(system);
1157
1158 m_producerLibraries.emplace(ctiPath, producerLibrary);
1159 allFoundSystems.emplace_back(system);
1160 }
1161 catch (const core::NotAvailableException&)
1162 {
1163 // TL not available or not supported.
1164 continue;
1165 }
1166 catch (const core::NotInitializedException&)
1167 {
1168 throw; // if this exception occurs, nothing else will work. so we stop here
1169 }
1170 catch (const core::Exception& ex)
1171 {
1172 if (errorCallback)
1173 {
1174 try
1175 {
1176 errorCallback("[CTI - " + ctiPath + "]: " + ex.what());
1177 }
1178 catch (...)
1179 {}
1180 }
1181 }
1182 }
1183 }
1184
1185 auto systemUpdateChildren = [&](const std::shared_ptr<core::System>& system) {
1186 try
1187 {
1188 system->UpdateInterfaces(interfaceUpdateTimeout_ms);
1189 }
1190 catch (const core::Exception& ex)
1191 {
1192 if (errorCallback)
1193 {
1194 try
1195 {
1196 errorCallback("[System - " + system->Key() + "]: " + ex.what());
1197 }
1198 catch (...)
1199 {}
1200 }
1201 }
1202 };
1203
1204 // We do an update on all available systems
1205 constexpr auto launchPolicy = std::launch::async; // switching this to std::launch::deferred makes debugging easier
1206
1207 std::vector<std::future<void>> systemUpdateChildrenTasks;
1208
1209 // add already found systems
1210 for (const auto& system : m_systems)
1211 {
1212 systemUpdateChildrenTasks.emplace_back(
1213 std::async(launchPolicy, systemUpdateChildren, std::const_pointer_cast<core::System>(system)));
1214 }
1215
1216 // now add newly found systems
1217 for (const auto& system : allFoundSystems)
1218 {
1219 systemUpdateChildrenTasks.emplace_back(std::async(launchPolicy, systemUpdateChildren, system));
1220 }
1221
1222 // wait for tasks to be done
1223 systemUpdateChildrenTasks.clear();
1224
1225 // copy results to our local lists
1226 for (auto& keyValue : m_systemCallbackContainers)
1227 {
1228 auto& container = keyValue.second;
1229
1230 std::lock_guard<std::mutex> lock(container.mutex);
1231
1232 allFoundInterfaces.reserve(allFoundInterfaces.size() + container.foundInterfaces.size());
1233 for (const auto& foundInterface : container.foundInterfaces)
1234 {
1235 AddInterfaceCallbacks(foundInterface);
1236 allFoundInterfaces.emplace_back(foundInterface);
1237 }
1238 container.foundInterfaces.clear();
1239
1240 allLostInterfaces.reserve(allLostInterfaces.size() + container.lostInterfaces.size());
1241 for (const auto& lostInterface : container.lostInterfaces)
1242 {
1243 auto interfaceIt = std::find_if(std::begin(m_interfaces), std::end(m_interfaces),
1244 [&lostInterface](const auto& intf) { return intf->Key() == lostInterface; });
1245
1246 if (interfaceIt != std::end(m_interfaces))
1247 {
1248 RemoveInterfaceCallbacks(std::const_pointer_cast<core::Interface>(*interfaceIt));
1249 }
1250
1251 allLostInterfaces.emplace_back(lostInterface);
1252 }
1253 container.lostInterfaces.clear();
1254 }
1255
1256 auto interfaceUpdateChildren = [&deviceUpdateTimeout_ms, &errorCallback](
1257 const std::shared_ptr<core::Interface>& iface) {
1258 try
1259 {
1260 iface->UpdateDevices(deviceUpdateTimeout_ms);
1261 }
1262 catch (const core::Exception& ex)
1263 {
1264 if (errorCallback)
1265 {
1266 try
1267 {
1268 errorCallback("[Interface - " + iface->Key() + "]: " + ex.what());
1269 }
1270 catch (...)
1271 {}
1272 }
1273 }
1274 };
1275
1276 // We do an update on all available interfaces
1277 std::vector<std::future<void>> interfaceUpdateChildrenTasks;
1278
1279 // add already found interfaces
1280 for (const auto& iface : m_interfaces)
1281 {
1282 interfaceUpdateChildrenTasks.emplace_back(
1283 std::async(launchPolicy, interfaceUpdateChildren, std::const_pointer_cast<core::Interface>(iface)));
1284 }
1285
1286 // add newly found interfaces
1287 for (const auto& iface : allFoundInterfaces)
1288 {
1289 interfaceUpdateChildrenTasks.emplace_back(std::async(launchPolicy, interfaceUpdateChildren, iface));
1290 }
1291
1292 // wait for tasks to be done
1293 interfaceUpdateChildrenTasks.clear();
1294
1295 // copy results to our local lists
1296 for (auto& keyValue : m_interfaceCallbackContainers)
1297 {
1298 auto& container = keyValue.second;
1299 std::lock_guard<std::mutex> lock(container.mutex);
1300
1301 decltype(container.foundDevices) foundDevices;
1302 std::swap(container.foundDevices, foundDevices);
1303 allFoundDevices.reserve(allFoundDevices.size() + foundDevices.size());
1304 std::move(std::begin(foundDevices), std::end(foundDevices), std::back_inserter(allFoundDevices));
1305
1306 decltype(container.lostDevices) lostDevices;
1307 std::swap(container.lostDevices, lostDevices);
1308 allLostDevices.reserve(allLostDevices.size() + lostDevices.size());
1309 std::move(std::begin(lostDevices), std::end(lostDevices), std::back_inserter(allLostDevices));
1310 }
1311
1312 // We apply the update changes to our internal lists
1313 {
1314 std::lock(m_systemsMutex, m_interfacesMutex, m_devicesMutex);
1315
1316 std::lock_guard<std::mutex> lockSystems(m_systemsMutex, std::adopt_lock);
1317 std::lock_guard<std::recursive_mutex> lockInterfaces(m_interfacesMutex, std::adopt_lock);
1318 std::lock_guard<std::recursive_mutex> lockDevices(m_devicesMutex, std::adopt_lock);
1319
1320 m_systems.reserve(m_systems.size() + allFoundSystems.size());
1321 std::copy(std::begin(allFoundSystems), std::end(allFoundSystems), std::back_inserter(m_systems));
1322
1323 for (const auto& lostInterfaceKey : allLostInterfaces)
1324 {
1325 m_interfaces.erase(std::remove_if(std::begin(m_interfaces), std::end(m_interfaces),
1326 [&lostInterfaceKey](const auto& interfaceToCheck) {
1327 return interfaceToCheck->Key() == lostInterfaceKey;
1328 }),
1329 std::end(m_interfaces));
1330 }
1331 m_interfaces.reserve(m_interfaces.size() + allFoundInterfaces.size());
1332 std::copy(std::begin(allFoundInterfaces), std::end(allFoundInterfaces), std::back_inserter(m_interfaces));
1333
1334 for (const auto& lostDeviceKey : allLostDevices)
1335 {
1336 m_devices.erase(
1337 std::remove_if(std::begin(m_devices), std::end(m_devices),
1338 [&lostDeviceKey](const auto& deviceToCheck) { return deviceToCheck->Key() == lostDeviceKey; }),
1339 std::end(m_devices));
1340 }
1341 m_devices.reserve(m_devices.size() + allFoundDevices.size());
1342 std::copy(std::begin(allFoundDevices), std::end(allFoundDevices), std::back_inserter(m_devices));
1343 }
1344
1345 // We trigger all callbacks
1346 for (const auto& foundSystem : allFoundSystems)
1347 {
1348 TriggerSystemFoundCallbacks(foundSystem);
1349 }
1350
1351 for (const auto& foundInterface : allFoundInterfaces)
1352 {
1353 TriggerInterfaceFoundCallbacks(foundInterface);
1354 }
1355
1356 for (const auto& lostInterfaceKey : allLostInterfaces)
1357 {
1358 TriggerInterfaceLostCallbacks(lostInterfaceKey);
1359 }
1360
1361 for (const auto& foundDevice : allFoundDevices)
1362 {
1363 TriggerDeviceFoundCallbacks(foundDevice);
1364 }
1365
1366 GetLostDevicesFromLostInterfaces(allLostInterfaces, allLostDevices);
1367 for (const auto& lostDeviceKey : allLostDevices)
1368 {
1369 TriggerDeviceLostCallbacks(lostDeviceKey);
1370 }
1371}
1372
1373inline void DeviceManager::Reset(ResetPolicy resetPolicy)
1374{
1375 std::lock_guard<std::mutex> lockUpdate(m_updateMutex);
1376
1377 if (resetPolicy == ResetPolicy::ErrorOnOpenDevices)
1378 {
1379 // check if any devices are running
1380 CheckDevicesOpened();
1381 }
1382
1383 {
1384 std::lock(m_systemsMutex, m_interfacesMutex, m_devicesMutex);
1385
1386 std::lock_guard<std::mutex> lockSystem(m_systemsMutex, std::adopt_lock);
1387 std::lock_guard<std::recursive_mutex> lockInterfaces(m_interfacesMutex, std::adopt_lock);
1388 std::lock_guard<std::recursive_mutex> lockDevices(m_devicesMutex, std::adopt_lock);
1389
1390 // Note: the list must be swapped because the devices must be removed from the list before the callback is
1391 // called
1392 decltype(m_devices) lostDevicesList{};
1393 std::swap(m_devices, lostDevicesList);
1394 for (const auto& lostDevice : lostDevicesList)
1395 {
1396 TriggerDeviceLostCallbacks(lostDevice->Key());
1397 }
1398
1399 decltype(m_interfaces) lostInterfacesList{};
1400 std::swap(m_interfaces, lostInterfacesList);
1401 for (const auto& lostInterface : lostInterfacesList)
1402 {
1403 TriggerInterfaceLostCallbacks(lostInterface->Key());
1404 RemoveInterfaceCallbacks(std::const_pointer_cast<core::Interface>(lostInterface));
1405 }
1406
1407 decltype(m_systems) lostSystemsList{};
1408 std::swap(m_systems, lostSystemsList);
1409 for (const auto& lostSystem : lostSystemsList)
1410 {
1411 RemoveSystemCallbacks(std::const_pointer_cast<core::System>(lostSystem));
1412 }
1413
1414 m_producerLibraries.clear();
1415 }
1416
1417 {
1418 std::lock_guard<std::mutex> lock(m_callbackContainerMutex);
1419
1420 m_systemCallbackContainers.clear();
1421 m_interfaceCallbackContainers.clear();
1422 }
1423
1424 {
1425 std::lock_guard<std::mutex> lock(m_producerLibrariesToAddMutex);
1426 m_producerLibrariesToAdd.clear();
1427 }
1428}
1429
1430inline void DeviceManager::AddSystemCallbacks(const std::shared_ptr<core::System>& addSystem)
1431{
1432 auto SystemKey = addSystem->Key();
1433
1434 const auto foundCallbackHandle = addSystem->RegisterInterfaceFoundCallback(
1435 [this, SystemKey](const std::shared_ptr<core::InterfaceDescriptor>& foundInterface) {
1436 const auto systemIt = m_systemCallbackContainers.find(SystemKey);
1437 if (systemIt != std::end(m_systemCallbackContainers))
1438 {
1439 try
1440 {
1441 auto& container = systemIt->second;
1442 std::lock_guard<std::mutex> lock(container.mutex);
1443
1444 const auto openedInterface = foundInterface->OpenInterface();
1445
1446 container.foundInterfaces.emplace_back(openedInterface);
1447 container.interfaceIdKeyMap.emplace(openedInterface->ID(), openedInterface->Key());
1448 }
1449 catch (const std::exception&)
1450 {}
1451 }
1452 });
1453
1454 const auto lostCallbackHandle = addSystem->RegisterInterfaceLostCallback(
1455 [this, SystemKey](const std::string& lostInterfaceId) {
1456 const auto systemIt = m_systemCallbackContainers.find(SystemKey);
1457 if (systemIt != std::end(m_systemCallbackContainers))
1458 {
1459 auto& container = systemIt->second;
1460 std::lock_guard<std::mutex> lock(container.mutex);
1461
1462 const auto interfaceKeyIt = container.interfaceIdKeyMap.find(lostInterfaceId);
1463 if (interfaceKeyIt != std::end(container.interfaceIdKeyMap))
1464 {
1465 container.lostInterfaces.emplace_back(interfaceKeyIt->second);
1466 container.interfaceIdKeyMap.erase(interfaceKeyIt);
1467 }
1468 }
1469 });
1470
1471 std::lock_guard<std::mutex> lock(m_callbackContainerMutex);
1472
1473 m_systemCallbackContainers.emplace(
1474 addSystem->Key(), SystemCallbackContainer{ foundCallbackHandle, lostCallbackHandle });
1475}
1476
1477inline void DeviceManager::RemoveSystemCallbacks(const std::shared_ptr<core::System>& removeSystem)
1478{
1479 std::lock_guard<std::mutex> lock(m_callbackContainerMutex);
1480
1481 const auto SystemKey = removeSystem->Key();
1482
1483 const auto systemIt = m_systemCallbackContainers.find(SystemKey);
1484
1485 if (systemIt != std::end(m_systemCallbackContainers))
1486 {
1487 const auto& container = systemIt->second;
1488 {
1489 std::lock_guard<std::mutex> lockContainer(container.mutex);
1490
1491 removeSystem->UnregisterInterfaceFoundCallback(container.foundCallbackHandle);
1492 removeSystem->UnregisterInterfaceLostCallback(container.lostCallbackHandle);
1493 }
1494
1495 m_systemCallbackContainers.erase(systemIt);
1496 }
1497}
1498
1499inline void DeviceManager::AddInterfaceCallbacks(const std::shared_ptr<core::Interface>& addInterface)
1500{
1501 auto InterfaceKey = addInterface->Key();
1502
1503 const auto foundCallbackHandle = addInterface->RegisterDeviceFoundCallback(
1504 [this, InterfaceKey](const std::shared_ptr<core::DeviceDescriptor>& foundDevice) {
1505 const auto interfaceIt = m_interfaceCallbackContainers.find(InterfaceKey);
1506
1507 if (interfaceIt != std::end(m_interfaceCallbackContainers))
1508 {
1509 auto& container = interfaceIt->second;
1510 std::lock_guard<std::mutex> lock(container.mutex);
1511
1512 container.foundDevices.emplace_back(foundDevice);
1513 container.deviceIdKeyMap.emplace(foundDevice->ID(), foundDevice->Key());
1514 }
1515
1516 // also keep track about opened devices
1517 foundDevice->RegisterDeviceOpenedCallback([this](const std::shared_ptr<core::Device>& openedDevice) {
1518 std::lock_guard<std::mutex> lock(m_openedDevicesMutex);
1519
1520 // clear out closed devices
1521 m_openedDevices.erase(std::remove_if(std::begin(m_openedDevices), std::end(m_openedDevices),
1522 [](const OpenedDevice& dev) { return dev.device.expired(); }),
1523 std::end(m_openedDevices));
1524
1525 // add the new one
1526 OpenedDevice device;
1527 device.device = openedDevice;
1528 device.displayName = openedDevice->DisplayName();
1529 m_openedDevices.push_back(device);
1530 });
1531 });
1532
1533 const auto lostCallbackHandle = addInterface->RegisterDeviceLostCallback(
1534 [this, InterfaceKey](const std::string& lostDeviceId) {
1535 const auto interfaceIt = m_interfaceCallbackContainers.find(InterfaceKey);
1536
1537 if (interfaceIt != std::end(m_interfaceCallbackContainers))
1538 {
1539 auto& container = interfaceIt->second;
1540 std::lock_guard<std::mutex> lock(container.mutex);
1541
1542 const auto lostDeviceKeyIt = container.deviceIdKeyMap.find(lostDeviceId);
1543 if (lostDeviceKeyIt != std::end(container.deviceIdKeyMap))
1544 {
1545 container.lostDevices.emplace_back(lostDeviceKeyIt->second);
1546 container.deviceIdKeyMap.erase(lostDeviceKeyIt);
1547 }
1548 }
1549 });
1550
1551 const auto reconnectedHandle = addInterface->RegisterDeviceReconnectedCallback(
1552 [this](const std::shared_ptr<core::DeviceDescriptor>& reconnectedDevice,
1553 core::DeviceReconnectInformation reconnectInformation) {
1554 return m_deviceReconnectedCallbackManager.TriggerCallbacks(reconnectedDevice, reconnectInformation);
1555 });
1556
1557 const auto disconnectedHandle = addInterface->RegisterDeviceDisconnectedCallback(
1558 [this](const std::shared_ptr<core::DeviceDescriptor>& disconnectedDevice) {
1559 return m_deviceDisconnectedCallbackManager.TriggerCallbacks(disconnectedDevice);
1560 });
1561
1562 const auto deviceListChangedHandle = addInterface->RegisterDeviceListChangedCallback(
1563 [this]() { return m_deviceListChangedCallbackManager.TriggerCallbacks(); });
1564
1565 std::lock_guard<std::mutex> lock(m_callbackContainerMutex);
1566
1567 m_interfaceCallbackContainers.emplace(addInterface->Key(),
1568 InterfaceCallbackContainer{
1569 foundCallbackHandle, lostCallbackHandle, disconnectedHandle, reconnectedHandle, deviceListChangedHandle });
1570}
1571
1572inline void DeviceManager::RemoveInterfaceCallbacks(const std::shared_ptr<core::Interface>& removeInterface)
1573{
1574 std::lock_guard<std::mutex> lock(m_callbackContainerMutex);
1575
1576 const auto interfaceIt = m_interfaceCallbackContainers.find(removeInterface->Key());
1577
1578 if (interfaceIt != std::end(m_interfaceCallbackContainers))
1579 {
1580 const auto& container = interfaceIt->second;
1581 {
1582 std::lock_guard<std::mutex> lockContainer(container.mutex);
1583
1584 removeInterface->UnregisterDeviceFoundCallback(container.foundCallbackHandle);
1585 removeInterface->UnregisterDeviceLostCallback(container.lostCallbackHandle);
1586 removeInterface->UnregisterDeviceDisconnectedCallback(container.disconnectedCallbackHandle);
1587 removeInterface->UnregisterDeviceReconnectedCallback(container.reconnectedCallbackHandle);
1588 removeInterface->UnregisterDeviceListChangedCallback(container.deviceListChangedCallbackHandle);
1589 }
1590 m_interfaceCallbackContainers.erase(interfaceIt);
1591 }
1592}
1593
1594inline void DeviceManager::CheckDevicesOpened() const
1595{
1596 size_t openDevicesFound = 0;
1597 std::string deviceDisplayNames;
1598
1599 {
1600 std::lock_guard<std::mutex> lock(m_openedDevicesMutex);
1601
1602 for (const auto& openedDevice : m_openedDevices)
1603 {
1604 auto openDevice = openedDevice.device.lock();
1605 if (openDevice)
1606 {
1607 ++openDevicesFound;
1608 deviceDisplayNames += openedDevice.displayName;
1609 deviceDisplayNames += " ";
1610 }
1611 }
1612 }
1613
1614 if (openDevicesFound > 0)
1615 {
1616 throw core::InternalErrorException(
1617 "Can't reset the device manager while there are devices open. The following devices ("
1618 + std::to_string(openDevicesFound) + ") are open: " + deviceDisplayNames);
1619 }
1620}
1621
1623{
1624 return m_interfaceUpdateTimeout_ms;
1625}
1626
1628{
1629 m_interfaceUpdateTimeout_ms = timeout_ms;
1630}
1631
1633{
1634 return m_deviceUpdateTimeout_ms;
1635}
1636
1638{
1639 m_deviceUpdateTimeout_ms = timeout_ms;
1640}
1641
1642inline std::vector<std::shared_ptr<const core::System>> DeviceManager::Systems() const
1643{
1644 std::lock_guard<std::mutex> lock(m_systemsMutex);
1645
1646 return m_systems;
1647}
1648
1649inline std::vector<std::shared_ptr<const core::Interface>> DeviceManager::Interfaces() const
1650{
1651 std::lock_guard<std::recursive_mutex> lock(m_interfacesMutex);
1652
1653 return m_interfaces;
1654}
1655
1656inline std::vector<std::shared_ptr<core::DeviceDescriptor>> DeviceManager::Devices() const
1657{
1658 std::lock_guard<std::recursive_mutex> lock(m_devicesMutex);
1659
1660 return m_devices;
1661}
1662
1663inline std::shared_ptr<core::DeviceDescriptor> DeviceManager::FirstAvailableDevice(core::DeviceAccessType access) const
1664{
1665 const auto devices = AvailableDevices(access);
1666 if (devices.empty())
1667 {
1668 return nullptr;
1669 }
1670 return devices.at(0);
1671}
1672
1673inline std::vector<std::shared_ptr<core::DeviceDescriptor>> DeviceManager::AvailableDevices(
1674 core::DeviceAccessType access) const
1675{
1676 std::lock_guard<std::recursive_mutex> lock(m_devicesMutex);
1677
1678 std::vector<std::shared_ptr<core::DeviceDescriptor>> availableDevices;
1679 std::copy_if(m_devices.begin(), m_devices.end(), std::back_inserter(availableDevices),
1680 [access](const std::shared_ptr<core::DeviceDescriptor>& device) { return device->IsOpenable(access); });
1681
1682 return availableDevices;
1683}
1684
1686 const DeviceManager::SystemFoundCallback& callback)
1687{
1688 return m_systemFoundCallbackManager.RegisterCallback(callback);
1689}
1690
1692{
1693 m_systemFoundCallbackManager.UnregisterCallback(callbackHandle);
1694}
1695
1698{
1699 return m_interfaceFoundCallbackManager.RegisterCallback(callback);
1700}
1701
1703{
1704 m_interfaceFoundCallbackManager.UnregisterCallback(callbackHandle);
1705}
1706
1709{
1710 return m_interfaceLostCallbackManager.RegisterCallback(callback);
1711}
1712
1714{
1715 m_interfaceLostCallbackManager.UnregisterCallback(callbackHandle);
1716}
1717
1719 const DeviceManager::DeviceFoundCallback& callback)
1720{
1721 return m_deviceFoundCallbackManager.RegisterCallback(callback);
1722}
1723
1725{
1726 m_deviceFoundCallbackManager.UnregisterCallback(callbackHandle);
1727}
1728
1730 const DeviceManager::DeviceLostCallback& callback)
1731{
1732 return m_deviceLostCallbackManager.RegisterCallback(callback);
1733}
1734
1736{
1737 m_deviceLostCallbackManager.UnregisterCallback(callbackHandle);
1738}
1739
1742{
1743 return m_deviceDisconnectedCallbackManager.RegisterCallback(callback);
1744}
1745
1748{
1749 m_deviceDisconnectedCallbackManager.UnregisterCallback(callbackHandle);
1750}
1751
1754{
1755 return m_deviceReconnectedCallbackManager.RegisterCallback(callback);
1756}
1757
1760{
1761 m_deviceReconnectedCallbackManager.UnregisterCallback(callbackHandle);
1762}
1763
1766{
1767 return m_deviceListChangedCallbackManager.RegisterCallback(callback);
1768}
1769
1772{
1773 m_deviceListChangedCallbackManager.UnregisterCallback(callbackHandle);
1774}
1775
1776inline void DeviceManager::GetLostDevicesFromLostInterfaces(
1777 const std::vector<std::string>& lostInterfaces, std::vector<std::string>& lostDevices)
1778{
1779 std::lock_guard<std::recursive_mutex> lock(m_devicesMutex);
1780
1781 for (const auto& device : m_devices)
1782 {
1783 auto resultIt = std::find(
1784 std::begin(lostInterfaces), std::end(lostInterfaces), device->ParentInterface()->Key());
1785 if (resultIt != std::end(lostInterfaces))
1786 {
1787 lostDevices.emplace_back(device->Key());
1788 }
1789 }
1790}
1791
1792inline void DeviceManager::TriggerSystemFoundCallbacks(const std::shared_ptr<const core::System>& foundSystem) const
1793{
1794 m_systemFoundCallbackManager.TriggerCallbacks(foundSystem);
1795}
1796
1797inline void DeviceManager::TriggerInterfaceFoundCallbacks(
1798 const std::shared_ptr<const core::Interface>& foundInterface) const
1799{
1800 m_interfaceFoundCallbackManager.TriggerCallbacks(foundInterface);
1801}
1802
1803inline void DeviceManager::TriggerInterfaceLostCallbacks(const std::string& lostInterfaceKey) const
1804{
1805 m_interfaceLostCallbackManager.TriggerCallbacks(lostInterfaceKey);
1806}
1807
1808inline void DeviceManager::TriggerDeviceFoundCallbacks(const std::shared_ptr<core::DeviceDescriptor>& foundDevice) const
1809{
1810 m_deviceFoundCallbackManager.TriggerCallbacks(foundDevice);
1811}
1812
1813inline void DeviceManager::TriggerDeviceLostCallbacks(const std::string& lostDeviceKey) const
1814{
1815 m_deviceLostCallbackManager.TriggerCallbacks(lostDeviceKey);
1816}
1817
1818} /* namespace peak */
PEAK_COMMON_NO_DISCARD core::Timeout InterfaceUpdateTimeout() const
Returns the interface update timeout.
Definition peak_device_manager.hpp:1622
std::function< void(const std::string &lostInterfaceKey)> InterfaceLostCallback
Definition peak_device_manager.hpp:109
InterfaceFoundCallbackHandle RegisterInterfaceFoundCallback(const InterfaceFoundCallback &callback)
Registers a callback for signaling a found interface.
Definition peak_device_manager.hpp:1696
std::function< void(const std::shared_ptr< core::DeviceDescriptor > &disconnectedDevice)> DeviceDisconnectedCallback
Definition peak_device_manager.hpp:127
void UnregisterDeviceFoundCallback(DeviceFoundCallbackHandle callbackHandle)
Unregisters a device found callback.
Definition peak_device_manager.hpp:1724
void UnregisterDeviceDisconnectedCallback(DeviceDisconnectedCallbackHandle callbackHandle)
Unregisters a device disconnected callback.
Definition peak_device_manager.hpp:1746
std::function< void(const std::shared_ptr< core::DeviceDescriptor > &foundDevice)> DeviceFoundCallback
Definition peak_device_manager.hpp:115
PEAK_COMMON_NO_DISCARD std::vector< std::shared_ptr< const core::System > > Systems() const
Returns the found and opened systems.
Definition peak_device_manager.hpp:1642
DeviceReconnectedCallback * DeviceReconnectedCallbackHandle
Definition peak_device_manager.hpp:139
void UnregisterInterfaceLostCallback(InterfaceLostCallbackHandle callbackHandle)
Unregisters an interface lost callback.
Definition peak_device_manager.hpp:1713
void Reset(ResetPolicy resetPolicy=ResetPolicy::ErrorOnOpenDevices)
Resets the DeviceManager.
Definition peak_device_manager.hpp:1373
UpdatePolicy
Enum holding the possible update policies.
Definition peak_device_manager.hpp:78
@ DontScanEnvironmentForProducerLibraries
Definition peak_device_manager.hpp:83
@ ScanEnvironmentForProducerLibraries
Definition peak_device_manager.hpp:80
ResetPolicy
Enum holding the possible reset policies.
Definition peak_device_manager.hpp:88
@ ErrorOnOpenDevices
Definition peak_device_manager.hpp:90
@ IgnoreOpenDevices
Definition peak_device_manager.hpp:93
friend class Library
Definition peak_device_manager.hpp:656
InterfaceFoundCallback * InterfaceFoundCallbackHandle
Definition peak_device_manager.hpp:106
void UnregisterDeviceLostCallback(DeviceLostCallbackHandle callbackHandle)
Unregisters a device lost callback.
Definition peak_device_manager.hpp:1735
PEAK_COMMON_NO_DISCARD core::Timeout DeviceUpdateTimeout() const
Returns the device update timeout.
Definition peak_device_manager.hpp:1632
PEAK_COMMON_NO_DISCARD std::shared_ptr< core::DeviceDescriptor > FirstAvailableDevice(core::DeviceAccessType access) const
Retrieves the first device that supports the given access type.
Definition peak_device_manager.hpp:1663
void Update(UpdatePolicy updatePolicy=UpdatePolicy::ScanEnvironmentForProducerLibraries, const UpdateErrorCallback &errorCallback=UpdateErrorCallback())
Starts an update.
Definition peak_device_manager.hpp:1115
std::function< void()> DeviceListChangedCallback
Definition peak_device_manager.hpp:142
DeviceDisconnectedCallback * DeviceDisconnectedCallbackHandle
Definition peak_device_manager.hpp:131
std::function< void(const std::shared_ptr< const core::Interface > &foundInterface)> InterfaceFoundCallback
Definition peak_device_manager.hpp:103
DeviceManager & operator=(const DeviceManager &other)=delete
static PEAK_COMMON_NO_DISCARD DeviceManager & Instance()
Returns the global DeviceManager.
Definition peak_device_manager.hpp:943
std::function< void(const std::string &errorDescription)> UpdateErrorCallback
Definition peak_device_manager.hpp:148
std::function< void(const std::shared_ptr< const core::System > &foundSystem)> SystemFoundCallback
Definition peak_device_manager.hpp:97
DeviceReconnectedCallbackHandle RegisterDeviceReconnectedCallback(const DeviceReconnectedCallback &callback)
Registers a callback for signaling a reconnected device.
Definition peak_device_manager.hpp:1752
SystemFoundCallback * SystemFoundCallbackHandle
Definition peak_device_manager.hpp:100
DeviceManager(const DeviceManager &other)=delete
void UnregisterDeviceListChangedCallback(DeviceListChangedCallbackHandle callbackHandle)
Unregisters a device list change callback.
Definition peak_device_manager.hpp:1770
PEAK_COMMON_NO_DISCARD std::vector< std::shared_ptr< core::DeviceDescriptor > > FindDevices(Pred predicate) const
Finds all devices that match a custom condition.
void RemoveProducerLibrary(const std::string &ctiPath)
Removes the producer library matching the given CTI path.
Definition peak_device_manager.hpp:965
PEAK_COMMON_NO_DISCARD std::vector< std::shared_ptr< core::DeviceDescriptor > > Devices() const
Returns the found devices.
Definition peak_device_manager.hpp:1656
std::function< void(const std::string &lostDeviceKey)> DeviceLostCallback
Definition peak_device_manager.hpp:121
std::function< void(const std::shared_ptr< core::DeviceDescriptor > &reconnectedDevice, core::DeviceReconnectInformation reconnectInformation)> DeviceReconnectedCallback
Definition peak_device_manager.hpp:134
void AddProducerLibrary(const std::string &ctiPath)
Adds the given producer library (CTI).
Definition peak_device_manager.hpp:958
SystemFoundCallbackHandle RegisterSystemFoundCallback(const SystemFoundCallback &callback)
Registers a callback for signaling a found system.
Definition peak_device_manager.hpp:1685
InterfaceLostCallbackHandle RegisterInterfaceLostCallback(const InterfaceLostCallback &callback)
Registers a callback for signaling a lost interface.
Definition peak_device_manager.hpp:1707
PEAK_COMMON_NO_DISCARD std::vector< std::shared_ptr< core::DeviceDescriptor > > AvailableDevices(core::DeviceAccessType access) const
Retrieves a collection of all devices matching the specified access type.
Definition peak_device_manager.hpp:1673
DeviceDisconnectedCallbackHandle RegisterDeviceDisconnectedCallback(const DeviceDisconnectedCallback &callback)
Registers a callback for signaling a disconnected device.
Definition peak_device_manager.hpp:1740
InterfaceLostCallback * InterfaceLostCallbackHandle
Definition peak_device_manager.hpp:112
DeviceFoundCallbackHandle RegisterDeviceFoundCallback(const DeviceFoundCallback &callback)
Registers a callback for signaling a found device.
Definition peak_device_manager.hpp:1718
DeviceFoundCallback * DeviceFoundCallbackHandle
Definition peak_device_manager.hpp:118
void UnregisterDeviceReconnectedCallback(DeviceReconnectedCallbackHandle callbackHandle)
Unregisters a device reconnected callback.
Definition peak_device_manager.hpp:1758
DeviceListChangedCallbackHandle RegisterDeviceListChangedCallback(const DeviceListChangedCallback &callback)
Registers a callback for signaling a change in the device list.
Definition peak_device_manager.hpp:1764
DeviceListChangedCallback * DeviceListChangedCallbackHandle
Definition peak_device_manager.hpp:145
void UnregisterSystemFoundCallback(SystemFoundCallbackHandle callbackHandle)
Unregisters a system found callback.
Definition peak_device_manager.hpp:1691
void SetInterfaceUpdateTimeout(core::Timeout timeout_ms)
Sets the interface update timeout.
Definition peak_device_manager.hpp:1627
void SetDeviceUpdateTimeout(core::Timeout timeout_ms)
Sets the device update timeout.
Definition peak_device_manager.hpp:1637
DeviceLostCallbackHandle RegisterDeviceLostCallback(const DeviceLostCallback &callback)
Registers a callback for signaling a lost device.
Definition peak_device_manager.hpp:1729
PEAK_COMMON_NO_DISCARD std::vector< std::shared_ptr< const core::Interface > > Interfaces() const
Returns the found and opened interfaces.
Definition peak_device_manager.hpp:1649
DeviceLostCallback * DeviceLostCallbackHandle
Definition peak_device_manager.hpp:124
void UnregisterInterfaceFoundCallback(InterfaceFoundCallbackHandle callbackHandle)
Unregisters a interface found callback.
Definition peak_device_manager.hpp:1702
Definition reconnect_information.hpp:19
The base class for all exceptions thrown by the library.
Definition peak_exception.hpp:24
The exception thrown for signaling that a feature is not available in the device.
Definition peak_exception.hpp:181
The exception thrown for signaling a failed find operation.
Definition peak_exception.hpp:190
The exception thrown for signaling that the library was not initialized.
Definition peak_exception.hpp:212
static PEAK_COMMON_NO_DISCARD std::shared_ptr< ProducerLibrary > Open(const std::string &ctiPath)
Opens the given producer library (CTI).
Definition peak_producer_library.hpp:107
InterfaceFoundCallback * InterfaceFoundCallbackHandle
Definition peak_system.hpp:54
Represents a timeout value in milliseconds.
Definition peak_timeout.hpp:28
static PEAK_COMMON_NO_DISCARD std::vector< std::string > CollectCTIPaths()
Collects producer library paths found in the current environment.
Definition peak_environment_inspector.hpp:70
DeviceAccessType
Different modes to open the device with.
Definition peak_device_descriptor.hpp:37
The "peak" namespace directly contains convenience functionality like the DeviceManager as well as th...
Definition peak_buffer.hpp:29
#define PEAK_COMMON_NO_DISCARD
Definition peak_common_defines.h:89