NodeCallback#

/***********************************************************************************
 *
 * 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 NodeCallback.cpp
 *
 * @brief "NodeCallback" example shows how user-defined callbacks are
 * executed by GenApi when the node they're registered to changes. In this
 * case, the PayloadSize node is used: it changes automatically
 * when a image-format related feature changes, e.g. PixelFormat.
 *
 * @see NodeMapPolling
 * @see Events
 */

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

// Include the GenICam library
#include "GenICam.h"

#define INDENT "\t"

// Define a callback function which can be registered to a node with GenApi.
// When the target node value changes, the callback is executed.
void OnPayloadSizeChanged(GenApi::INode* node) {
  GenApi::CIntegerPtr pPayloadSize = node;
  std::cout << INDENT << "OnPayloadSizeChanged function called." << std::endl;
  std::cout << INDENT << "PayloadSize node changed. New value is " << pPayloadSize->GetValue()
            << std::endl
            << std::endl;
}

void NodeCallback_Sample() {
  std::cout << "***** NodeCallback 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;

  // Get the PixelFormat node and set its value to Mono8 for example
  // purposes. The original value is saved and then restored at the end of
  // the program.
  GenApi::CEnumerationPtr pPixelFormat = pDevice->GetNodeMap().GetNode("PixelFormat");
  if (!IsWritable(pPixelFormat))
    throw GENERIC_EXCEPTION("Unable to configure the pixel format. Aborting.");
  uint64_t originalPixelFormat = pPixelFormat->GetIntValue();
  pPixelFormat->FromString("Mono8");

  // Get the PayloadSize node.
  GenApi::CIntegerPtr pPayloadSize = pDevice->GetNodeMap().GetNode("PayloadSize");
  if (!IsReadable(pPayloadSize))
    throw GENERIC_EXCEPTION("Unable to get the image payload size. Aborting.");
  std::cout << std::endl
            << "The payload size is " << pPayloadSize->GetValue() << " with Mono8 format."
            << std::endl;

  // Register the callback to the PayloadSize node so that when a
  // change in its value occurs, the function is executed.
  GenApi::CallbackHandleType hCallback =
      GenApi::Register(pPayloadSize->GetNode(), OnPayloadSizeChanged);
  std::cout << "OnPayloadSizeChanged function registered to PayloadSize node." << std::endl
            << std::endl;

  std::cout << "Setting pixel format to Mono12p.." << std::endl;

  // Set the pixel format to Mono12p. At this point, the callback gets
  // automatically executed by GenApi since the PayloadSize feature
  // is changed after the new PixelFormat.
  pPixelFormat->FromString("Mono12p");

  // Deregister the callback function when done.
  GenApi::Deregister(hCallback);

  // Restore the original pixel format value.
  pPixelFormat->SetIntValue(originalPixelFormat);

  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 {
    NodeCallback_Sample();
  } catch (GenICam::GenericException& e) {
    std::cout << e.what() << std::endl;
  }
}