NodeMapPolling#

/***********************************************************************************
 *
 * Itala API - Copyright (C) 2022 Opto Engineering
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY SUFFERED BY LICENSE AS
 * A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
 *
 ***********************************************************************************/

/**
 * @example NodeMapPolling.cpp
 *
 * @brief "NodeMapPolling" example shows how user-defined callbacks are
 * executed by GenApi when the node they're registered to changes due
 * to a polling operation. Every "pollable" feature has a specific
 * polling time defined by the manufacturer. When the Poll function is
 * called on the nodemap by the client code, the time elapsed since the
 * last poll must be specified. All features with a polling time shorter
 * than the elapsed time are automatically read and updated by GenApi.
 *
 * @see NodeCallback.cpp
 * @see Events.cpp
 */

// Include Itala API
#include "ItalaApi/Itala.h"

// Include the GenICam library
#include <chrono>
#include <thread>
#include "GenICam.h"

#define INDENT "\t"
#define TEMPERATURE_READS 10
#define POLL_FREQ_MS 750

// Callback function called on DeviceTemperature node change.
void OnDeviceTemperatureChanged(GenApi::INode* node) {
  GenApi::CFloatPtr pDeviceTemperature = node;
  std::cout << INDENT << "OnDeviceTemperatureChanged function called." << std::endl;
  std::cout << INDENT << "Device temperature node changed. New value is "
            << pDeviceTemperature->GetValue() << " C\370." << std::endl
            << std::endl;
}

void NodeMapPolling_Sample() {
  std::cout << "***** NodeMapPolling example started. *****" << std::endl << std::endl;

  Itala::ISystem* pSystem = Itala::CreateSystem();
  Itala::DeviceInfoList deviceInfos = pSystem->EnumerateDevices(700);

  if (deviceInfos.size() == 0) throw GENERIC_EXCEPTION("No devices found. Example canceled.");

  if (deviceInfos[0].AccessStatus() != Itala::DeviceAccessStatus::AvailableReadWrite)
    throw GENERIC_EXCEPTION("Target device is unaccessible in RW mode. Example canceled.");

  Itala::IDevice* pDevice = pSystem->CreateDevice(deviceInfos[0]);

  std::cout << "First device initialized." << std::endl;

  GenApi::CFloatPtr pDeviceTemperature = pDevice->GetNodeMap().GetNode("DeviceTemperature");
  if (!IsReadable(pDeviceTemperature))
    throw GENERIC_EXCEPTION("DeviceTemperature feature not available. Aborting.");

  // Register the OnDeviceTemperatureChanged callback to the DeviceTemperature node
  GenApi::CallbackHandleType hCallback =
      GenApi::Register(pDeviceTemperature->GetNode(), OnDeviceTemperatureChanged);
  std::cout << "OnDeviceTemperatureChanged registered to DeviceTemperature node." << std::endl
            << std::endl;

  for (int i = 0; i < TEMPERATURE_READS; i++) {
    // Sleep for a bit..
    std::this_thread::sleep_for(std::chrono::milliseconds(POLL_FREQ_MS));
    std::cout << INDENT << "Polling temperature.." << std::endl;

    // And then poll nodes of the map. At this point, all nodes with a polling time
    // shorter than the elapsed time are updated and their callback executed, if any.
    pDevice->GetNodeMap().Poll(POLL_FREQ_MS);
  }

  GenApi::Deregister(hCallback);

  pDevice->Dispose();
  pDevice = nullptr;
  std::cout << "Device instance disposed." << std::endl;

  pSystem->Dispose();
  pSystem = nullptr;
  std::cout << "System instance disposed." << std::endl;
}

int main(int /*argc*/, char** /*argv*/) {
  try {
    NodeMapPolling_Sample();
  } catch (GenICam::GenericException& e) {
    std::cout << e.what() << std::endl;
  }
}