Enumeration#

/***********************************************************************************
 *
 * 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 Enumeration.cpp
 *
 * @brief "Enumeration" is the simplest example available and the best starting
 * point to be up and running with ItalaSDK. Device enumeration is the process by
 * which connected devices are discovered and identified by the host. It also
 * represents the last known state of the cameras. The enumeration must be performed
 * by the user code. Once a device is known and reachable, it can be accessed and
 * via its interface to acquire images or configure its parameters.
 *
 * @see AdvancedEnumeration.cpp
 * @see DeviceConfiguration.cpp
 * @see Grab.cpp
 */

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

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

#define INDENT "\t"

void Enumeration_Sample() {
  std::cout << "***** Enumeration example started. *****" << std::endl << std::endl;

  // Initialize the system instance to enables the usage of the entire API.
  // It is the root of Itala and only one system object can exist at a time. If
  // two systems are created simultaneously, an error occurs. When the system
  // instance is no longer needed (e.g. on application exit) it MUST be released
  // by calling its dedicated function Dispose().
  Itala::ISystem* pSystem = Itala::CreateSystem();

  // Look for available devices across all network interfaces on the host and
  // retrieve a list of DeviceInfo objects, with a limit of 700ms to show up.
  // Each info object uniquely identifies a detected device and provides a set
  // of useful information about it. DeviceInfo objects are nothing more than
  // information containers with no effects on the device state.
  Itala::DeviceInfoList deviceInfos = pSystem->EnumerateDevices(700);

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

  // Let's print some data..
  std::cout << deviceInfos.size() << " devices discovered." << std::endl << std::endl;

  // For every device found some information is printed. Note that some devices
  // may be in a misconfigured state (e.g. a different subnet) thus impossible
  // to be reached or used, as eventually reported by DeviceInfo.
  for (size_t i = 0; i < deviceInfos.size(); i++) {
    Itala::DeviceInfo currentInfo = deviceInfos[i];
    std::cout << "Device " << i << " is " << currentInfo.SerialNumber() << std::endl;
    std::cout << INDENT << "Display name: " << currentInfo.DisplayName() << std::endl;
    std::cout << INDENT << "MAC Address: " << Itala::MacAddressToString(currentInfo.MacAddress())
              << std::endl;
    std::cout << INDENT << "IP Address: " << Itala::AddressToString(currentInfo.IpAddress())
              << std::endl;
    std::cout << INDENT << "Model: " << currentInfo.Model() << std::endl;
    std::cout << INDENT
              << "Access status: " << Itala::AccessStatusToString(currentInfo.AccessStatus())
              << std::endl;
    std::cout << std::endl;
  }

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

  // Create and initialize the device identified by the first DeviceInfo object.
  Itala::IDevice* pDevice = pSystem->CreateDevice(deviceInfos[0]);
  std::cout << deviceInfos[0].SerialNumber() << " device instance created." << std::endl;

  // Do something with the device..

  // Never forget to dispose the used device when done! It's strongly suggested
  // to null the released pointer to avoid violations. The Dispose() method
  // and the "delete" operator (which is not available here) are the exact same
  // thing hence they must be used the same way.
  pDevice->Dispose();
  pDevice = nullptr;
  std::cout << deviceInfos[0].SerialNumber() << " device instance disposed." << std::endl;

  // Never forget to dispose the system when done! It's strongly suggested
  // to null the released pointer to avoid violations. The Dispose() method
  // and the "delete" operator (which is not available here) are the exact same
  // thing hence they must be used the same way.
  pSystem->Dispose();
  pSystem = nullptr;
  std::cout << "System instance disposed." << std::endl;
}

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