IDS Peak comfortSDK, genericSDK, IPL, and AFL developer manuals are external documents. Please contact us if you need them.
  
	•Using events
•Implementing the worker class
•Creating and starting the worker thread in main program
•Alternative solution in C++ with a standard thread
Using events
Before you can receive an event from the camera, you must enable it in the camera, e.g. the start of the exposure ("ExposureStart").
| genericC++ | 
| nodemapRemoteDevice->FindNode<peak::core::nodes::EnumerationNode>("EventSelector")->SetCurrentEntry("ExposureStart");
 // Enable continuous notification
 nodemapRemoteDevice->FindNode<peak::core::nodes::EnumerationNode>("EventNotification")->SetCurrentEntry("On");
 
 // Enable one time notification
 nodemapRemoteDevice->FindNode<peak::core::nodes::EnumerationNode>("EventNotification")->SetCurrentEntry("Once");
 
 // Disable notification
 nodemapRemoteDevice->FindNode<peak::core::nodes::EnumerationNode>("EventNotification")->SetCurrentEntry("Off");
 | 
Receiving camera events on the host PC works similarly to waiting for images. It should be done in a separate thread. Here, a thread is used under Qt and first a worker class is defined (see also Receiving images).
Additionally, the camera object (std::shared_ptr<peak::core::Device>) and the EventController are required.
| genericC++ | 
| class EventWorker : public QObject{
 Q_OBJECT
 
 public:
 
 EventWorker(std::shared_ptr<peak::core::Device> device, QObject parent);
 ~EventWorker();
 
 private:
 
 std::shared_ptr<peak::core::Device> m_device;
 std::unique_ptr<peak::core::EventController> m_eventController;
 std::shared_ptr<peak::core::NodeMap> m_nodemapRemoteDevice;
 bool m_running;
 
 public slots:
 
 void Start();
 };
 | 
Implementing the worker class
| genericC++ | 
| EventWorker::EventWorker(std::shared_ptr<peak::core::Device> device, QObject parent) : QObject(parent){
 m_device = device;
 m_eventController = nullptr;
 m_nodemapRemoteDevice = m_device->RemoteDevice()->NodeMaps().at(0);
 m_running = false;
 }
 
 EventWorker::~EventWorker()
 {
 }
 
 void EventWorker::Start()
 {
 try
 {
 // Enable events from the camera (RemoteDevice)
 m_eventController = m_device->EnableEvents(EventType::RemoteDevice);
 if (!m_eventController)
 {
 // ...
 return;
 }
 }
 catch (std::exception& e)
 {
 // ...
 return;
 }
 
 m_running = true;
 
 while (m_running)
 {
 try
 {
 // Wait an infinite time for events
 auto event = m_eventController->WaitForEvent(peak::core::Timeout::INFINITE_TIMEOUT);
 
 // Insert event into tree
 m_nodemapRemoteDevice->UpdateEventNodes(event);
 
 auto type = peak::core::ToString(event->Type());
 
 if (peak::core::EventType::RemoteDevice == event->Type())
 {
 // Get unique identifier of the exposure start event and check if the received event has the same id
 uint64_t exposureStartID = static_cast<uint64_t>(m_camera->GetNodemapRemoteDevice()->FindNode<peak::core::nodes::IntegerNode>("EventExposureStart")->Value());
 if (event->ID() == exposureStartID)
 {
 // ...
 }
 }
 }
 catch (std::exception& e)
 {
 // ...
 }
 }
 }
 | 
Creating and starting the worker thread in main program
| genericC++ | 
| void mainProgram(){
 // ...
 
 // Create worker thread
 EventWorker* m_eventWorker = new EventWorker();
 QThread m_eventThread;
 
 // Move the worker to a new thread
 m_eventWorker ->moveToThread(&m_eventThread);
 
 // Call Start() slot of the worker when QThread starts
 connect(&m_eventThread, SIGNAL(started()), m_eventWorker , SLOT(Start()));
 
 // Start QThread
 m_eventThread.start();
 }
 | 
Alternative solution in C++ with a standard thread
| genericC++ | 
| class EventWorker{
 public:
 
 EventWorker(const std::shared_ptr<peak::core::Device>& device);
 ~EventWorker();
 
 EventWorker(const EventWorker& o) = delete;
 EventWorker& operator=(const EventWorker& o) = delete;
 EventWorker(EventWorker&& o) = default;
 EventWorker& operator=(EventWorker&& o) = default;
 
 
 private:
 void run();
 
 std::shared_ptr<peak::core::Device> m_device;
 std::unique_ptr<peak::core::EventController> m_eventController;
 std::shared_ptr<peak::core::NodeMap> m_nodemapRemoteDevice;
 
 std::atomic_bool m_running{ false };
 std::thread m_listenerThread;
 };
 | 
| genericC++ | 
| EventWorker::EventWorker(const std::shared_ptr<peak::core::Device>& device): m_device(device)
 {
 // Enable events from the camera (RemoteDevice)
 m_eventController = std::move(m_device->EnableEvents(peak::core::EventType::RemoteDevice));
 m_nodemapRemoteDevice = m_device->RemoteDevice()->NodeMaps().at(0);
 
 // Enable "ExposureStart" event on the camera
 m_nodemapRemoteDevice->FindNode<peak::core::nodes::EnumerationNode>("EventSelector")
 ->SetCurrentEntry("ExposureStart");
 m_nodemapRemoteDevice->FindNode<peak::core::nodes::EnumerationNode>("EventNotification")
 ->SetCurrentEntry("On");
 
 // Enable additional events
 // ...
 
 // Start the event listener thread
 m_listenerThread = std::thread([this]() {
 run();
 });
 }
 
 EventWorker::~EventWorker()
 {
 // Stop the event listener thread
 m_running = false;
 if (m_listenerThread.joinable()) {
 try {
 // Stop the current WaitForEvent()
 m_eventController->KillWait();
 }
 catch (const peak::core::Exception&) {
 // ignore
 }
 m_listenerThread.join();
 }
 }
 
 void EventWorker::run()
 {
 m_running = true;
 while (m_running) {
 try {
 auto event = m_eventController->WaitForEvent(
 peak::core::Timeout::INFINITE_TIMEOUT);
 
 if (event->Type() != peak::core::EventType::RemoteDevice)
 {
 // error ...
 }
 
 m_nodemapRemoteDevice->UpdateEventNodes(event);
 
 // Get unique identifier of the exposure start event and check if the received event has the same id
 uint64_t exposureStartID = static_cast<uint64_t>(m_nodemapRemoteDevice->FindNode<peak::core::nodes::IntegerNode>("EventExposureStart")->Value());
 if (event->ID() == exposureStartID)
 {
 // Handle event ...
 }
 // Handle additional events
 // ...
 }
 catch (const peak::core::Exception& e) {
 // ...
 }
 }
 }
 | 
| genericC++ | 
| void mainProgram() {// ...
 
 // Create worker thread
 EventWorker eventWorker(device);
 }
 |