Реализация Get и Set поддержки свойств конкретного устройства

После подключения к устройству через адаптер пользователи могут захотеть просмотреть или изменить значения свойств устройства. Для примера пользователь может настроить значение Brightness свойство или извлечь текущее значение Temperature свойство. (Для получения информации о том, как определить свойства, которые вы хотите предоставить пользователям, см. раздел «Создание свойств устройства».)

Чтобы получить уведомление от механизма, когда пользователь хочет просмотреть или изменить свойство, связайте объект listener со свойством. Тулбокс задает два типа классов прослушивателя: get прослушивателей, которые отвечают на get команды и set прослушиватели, которые отвечают на set команды.

Чтобы обеспечить поддержку для получения и настройки значений свойств, выполните следующую процедуру:

  1. Задайте класс прослушивателя соответствующего типа. Тулбокс задает два абстрактных классов, один для прослушивателей get и один для слушателей set, из которых вы выводите свой класс.

  2. Реализуйте виртуальную функцию, необходимую для класса.

  3. Связать образец класса прослушивателя со свойством.

В следующих разделах описывается, как настроить получение прослушивателей и задать прослушиватели и в вашем адаптере.

Настройка Get Listeners в вашем адаптере

Чтобы получить уведомление от механизма, когда пользователь запрашивает текущее значение свойства, использующего get команда:

  1. Задайте класс прослушиватель, выведя его из IPropCustomGetFcn абстрактный класс - см. Определение класса Прослушиватель.

  2. Реализуйте getValue() виртуальная функция в классе прослушивателя - см. Создание функции getValue () для вашего класса .

  3. Связать образец класса прослушивателя со свойством - см. Раздел «Связывание прослушивателей со свойствами».

Определение класса Прослушиватель

Создайте класс прослушиватель, выведя его из абстрактного класса IPropCustomGetFcn, как показано в следующем примере.

В этом примере конструктор принимает указатель на IAdaptor объект. Поскольку тулбокс устанавливает прослушиватели на основе экземпляров, передача этого указателя может быть полезной, но это не является обязательным.

The IPropCustomGetFcn класс задает одну виртуальную функцию: getValue() функции представителя. В этой функции вы задаете, как ваш адаптер реагирует, когда пользователь запрашивает текущее значение свойства. Для получения дополнительной информации о getValue() , см. Создание функции getValue () для вашего класса.

#include "mwadaptorimaq.h" 
#include "MyDeviceImaq.h" // For this example

class MyDevicePropGetListener : public IPropCustomGetFcn
{
public: 

   // Constructor/Destructor
	MyDevicePropGetListener(MyDeviceAdaptor* parent):
                               _parent(parent) {}

  virtual ~MyDevicePropGetListener() {};

  virtual void getValue(imaqkit::IPropInfo* propertyInfo,
                                      void* value);

private:

   // Declare handle to parent as member data.
   MyDeviceAdaptor* _parent;

};

Создание функции getValue () для вашего класса

Когда пользователь запрашивает текущее значение свойства, механизм вызывает getValue() функция класса прослушиватель, связанная со свойством.

Ваши getValue() функция должна принимать два параметра:

void getValue(IPropInfo* propertyInfo, void* value)
  • propertyInfo является указателем на IPropInfo объект. - The IPropInfo класс - интерфейс, позволяющий получить информацию о свойстве. Для примера используйте IPropInfo вы можете получить имя свойства, его тип хранилища и значение по умолчанию. Эта информация полезна, если у вас есть общий класс прослушивателя, который обрабатывает несколько свойств.

  • value - указатель на местоположение в памяти, где ваш адаптер хранит требуемое значение свойства. - Механизм передает это значение как void*. Ваши getValue() функция должна привести значение к соответствующему типу данных C++. В следующей таблице описывается тип данных C++ для всех типов свойств, поддерживаемых набором адаптеров.

    imaqkit:: PropertyTypes

    Тип данных C++

    CHARACTER_VECTOR

    char**

    DOUBLE

    double*

    INT

    int*

    DOUBLE_ARRAY

    imaqkit::PropertyTypes::NDoubles*

    INT_ARRAY

    imaqkit::PropertyTypes::NInts*

    Для нескалярных типов данных, векторов символов, двойных массивов и целочисленных массивов ваш класс прослушивателя должен выделить достаточное количество памяти для текущего значения свойства, используя new[] оператор. Механизм удаляет эту память, вызывая delete[]. Примером, использующим свойство вектора символов, является:

    char** returnStr = reinterpret_cast<char**>(value);
    *returnStr = imaqkit::imaqmalloc(sizeof(char) * (stringLength));
    strcpy(*returnStr, currentPropertyValueString);
    

Предложенный алгоритм для функции getValue ( ). Проект getValue() функция зависит от потребностей вашего устройства и возможностей, предлагаемых его SDK. Например, можно создать один класс прослушиватель, который обрабатывает запросы значений для всех свойств в конкретном контейнере свойств (общем или конкретном устройстве). В этом случае getValue() функция включает оператор switch со случаями, которые обрабатывают каждое отдельное свойство.

Кроме того, задайте отдельный класс прослушиватель для каждого свойства или каждого типа хранилища свойств. Затем механизм вызывает конкретный прослушиватель для заданного свойства.

Можно также задать классы прослушиватель, которые соответствуют тому, как SDK устройства организует строение свойства. Для примера, если SDK предоставляет одну функцию для настройки всех свойств устройства, можно задать класс get прослушивателя для этих свойств.

Пример.  Этот пример показывает реализацию getValue() функция для целых типов:

void MyDevicePropGetListener::getValue(IPropInfo* propertyInfo,
                                            void* value)
{
    
   // Get property name from the IPropInfo object.
   const char* propname = propertyInfo->getPropertyName();

   // Get the value using whatever facility your device's SDK provides.
   *reinterpret_cast<const int*>(value) = sdk_function_get();

   // For debug purposes only.
   imaqkit::adaptorWarn("In listener. Property name is %s\n",propname);
}

Связь прослушивателей с свойствами

Чтобы настроить прослушиватель для свойства, вы связываете объект слушателя со свойством в контейнере свойств. В следующем примере показано, как добавить прослушиватели для всех свойств конкретного устройства в контейнер свойств адаптера. Адаптер средств записи обычно настраивает прослушиватели свойств в их конструкторе класса адаптера - см. «Реализация конструктора класса адаптера».

  1. Получите указатель на соответствующий объект контейнера свойств.

    The IEngine объект имеет две функции представителя, которые возвращают указатели в контейнеры свойств (IPropContainer объекты). Пример вызывает IEngine классы getAdaptorPropContainer() Представитель функцию, чтобы получить контейнер свойств конкретного устройства:

    imaqkit::IPropContainer* adaptorPropContainer =
                             getEngine()->getAdaptorPropContainer();
    
  2. Добавьте прослушиватель get к свойству в контейнере, используя IPropContainer setCustomGetFcn() объекта функция. В качестве аргументов задайте имя свойства и указатель на объект прослушивателя.

    Примечание

    Поскольку тулбокс удаляет каждый образец объекта прослушивателя, когда пользователь удаляет объект входа видео, ассоциируйте новый образец объекта прослушивателя с каждым свойством.

    В следующем примере выполняется итерация всех свойств в контейнере свойств адаптера, связывая объект прослушиватель с каждым из них.

    void MyDeviceAdaptor::MyDeviceAdaptor()
    {
        // get a handle to the property container
        IPropContainer* propContainer = 
                           getEngine()->getAdaptorPropContainer();
    
        // Determine the number of properties in the container.
        int numDeviceProps = propContainer->getNumberProps();
    
        // Retrieve the names of all the properties in the container
        const char **devicePropNames = new const
                           char*[numDeviceProps];
        propContainer->getPropNames(devicePropNames);
    
        // Create a variable to point to a property get listener object.
        MyDevicePropGetListener* getListener;
    
        // For each property in the container...
        for (int i = 0; i < numDeviceProps; i++){
    
            // Create a get listener object...
            getListener = new MyDevicePropGetListener(this);
    
            // and associate it with a specific property.
            propContainer->setCustomGetFcn(devicePropNames[i], getListener);
        }
    
        // clean up the array of property names.
    
        delete [] devicePropNames;
        
    }
    

Настройка Set Listeners в вашем адаптере

Чтобы получить уведомление от механизма, когда пользователь изменяет значение свойства, используя set команда:

  1. Задайте класс прослушивателя набора, выведя его из IPropPostSetListener абстрактный класс - см. Определение класса Прослушиватель.

  2. Реализуйте notify() виртуальная функция в классе прослушивателя набора - см. Создание функции notify () для вашего класса .

  3. Связать образец класса прослушивателя набора со свойством - см. Раздел «Связь прослушивателей набора со свойствами».

Определение класса Прослушиватель

Создайте класс прослушиватель, выведя его из абстрактного класса IPropPostSetListener, как показано в следующем примере. (Имя класса включает слово Post поскольку тулбокс уведомляет прослушиватели после обновления значения свойства, хранящегося в контейнере.)

В этом примере конструктор принимает указатель на IAdaptor объект. Поскольку тулбокс устанавливает прослушиватели на основе экземпляров, передача этого указателя может быть полезной, но это не является обязательным.

The IPropPostSetListener класс задает одну виртуальную функцию: notify() функции представителя. В этой функции вы задаете, как ваш адаптер реагирует, когда пользователь изменяет значение свойства. Для получения дополнительной информации смотрите Создание функции notify () для вашего класса.

#include "mwadaptorimaq.h" 
#include "MyDeviceImaq.h" // For this example

class MyDevicePropSetListener : public IPropPostSetListener
{
public: 

   // Constructor/Destructor
	MyDevicePropSetListener(MyDeviceAdaptor* parent):
                               _parent(parent) {}

  virtual ~MyDevicePropSetListener() {};

  virtual void notify(imaqkit::IEnginePropInfo* propertyInfo,
                       void* newValue);

private:

   // Declare handle to parent as member data
   MyDeviceAdaptor* _parent;

   // Property Information object.
   imaqkit::IPropInfo* _propInfo;

   // The new value for integer properties.
   int _lastIntValue;

   // The new value for double properties.
   double _lastDoubleValue;

   // The new value for character vector properties.
   char* _lastStrValue;

};

Создание функции notify () для вашего класса

Когда пользователь вызывает set команда, чтобы изменить значение свойства, двигатель вызывает notify() функция класса прослушивателя набора, связанная со свойством.

Класс прослушивателя набора notify() функция должна принимать два параметра:

void notify(IPropInfo* propertyInfo, void* newValue)
  • propertyInfo является указателем на IPropInfo объект - The IPropInfo класс - интерфейс, позволяющий получить информацию о свойстве. Для примера используйте IPropInfo вы можете получить имя свойства, его тип хранилища и значение по умолчанию.

  • newValue является указателем на новое значение свойства - Этот механизм передает это значение как void*. Ваши notify() функция должна привести значение к соответствующему типу данных C++. В следующей таблице описывается тип данных C++ для всех типов свойств, поддерживаемых набором адаптеров.

    imaqkit:: PropertyTypes

    Тип данных C++

    CHARACTER_VECTOR

    char*

    DOUBLE

    double*

    INT

    int*

    DOUBLE_ARRAY

    imaqkit::PropertyTypes::NDoubles*

    INT_ARRAY

    imaqkit::PropertyTypes::NInts*

Предложенный алгоритм для функции notify ( ). Проект notify() функция зависит от потребностей вашего устройства и возможностей, предлагаемых его SDK. Например, можно создать один класс прослушивателя набора, который обрабатывает все изменения значений для всех свойств в конкретном контейнере свойств (общем или конкретном устройстве). В этом случае notify() функция включает оператор switch со случаями, которые обрабатывают каждое отдельное свойство.

Кроме того, можно задать отдельный класс прослушивателя набора для каждого свойства или каждого типа хранилища свойств. Затем механизм вызывает конкретный прослушиватель для заданного свойства.

Можно также задать классы прослушивателя, которые соответствуют тому, как SDK организует строение свойства. Для примера, если SDK предоставляет одну функцию для настройки всех свойств устройства, можно задать класс прослушивателя набора для этих свойств.

Пример.  Этот пример показывает реализацию notify() функция для целых типов:

void MyDevicePropSetListener::notify(IPropInfo* propertyInfo,
                                         void* newValue)
{
    
   // Get property name from the IPropInfo object.
   const char* propname = propertyInfo->getPropertyName();

   // Cast newValue to the proper type
   newVal = *reinterpret_cast<const int*>(newValue);

   // *****************************************************
   // Insert calls to device SDK to apply value to hardware.
   // *****************************************************

   // For debug purposes only.
   imaqkit::adaptorWarn("In listener. Property name is %s\n",propname);

}

Связь прослушивателей набора со свойствами

Чтобы настроить прослушиватель для свойства, вы связываете объект слушателя со свойством в контейнере свойств. В следующем примере показано, как добавить прослушиватели набора для всех свойств конкретного устройства в контейнере свойств адаптера. Адаптер средств записи обычно настраивает прослушиватели свойств в их конструкторе класса адаптера - см. «Реализация конструктора класса адаптера».

  1. Получите указатель на соответствующий объект контейнера свойств.

    The IEngine объект имеет две функции представителя, которые возвращают указатели в контейнеры свойств (IPropContainer объекты). Пример вызывает IEngine классы getAdaptorPropContainer() Представитель функцию, чтобы получить контейнер свойств конкретного устройства:

    imaqkit::IPropContainer* adaptorPropContainer =
                             getEngine()->getAdaptorPropContainer();
    
  2. Добавьте прослушиватель набора к свойству в контейнере, используя IPropContainer addListener() объекта функция. В качестве аргументов задайте имя свойства и указатель на объект прослушивателя.

    Примечание

    Поскольку тулбокс удаляет каждый образец объекта прослушивателя, когда пользователь удаляет объект входа видео, ассоциируйте новый образец объекта прослушивателя с каждым свойством.

    Следующий пример повторяет все свойства в контейнере свойств адаптера, связывая объект прослушивателя набора с каждым свойством:

    void MyDeviceAdaptor::MyDeviceAdaptor()
    {
        // get a handle to the property container
        IPropContainer* propContainer = 
                           getEngine()->getAdaptorPropContainer();
    
        // Determine the number of properties in the container.
        int numDeviceProps = propContainer->getNumberProps();
    
        // Retrieve the names of all the properties in the container
        const char **devicePropNames = new const
                           char*[numDeviceProps];
        propContainer->getPropNames(devicePropNames);
    
        // Create a variable to point to a property listener object.
        MyDevicePropSetListener* setListener;
    
        // For each property in the container...
        for (int i = 0; i < numDeviceProps; i++){
    
            // Create a set listener object...
            setListener = new MyDevicePropSetListener(this);
    
            // and associate it with a specific property.
            propContainer->addListener(devicePropNames[i], setListener);
        }
    
        // clean up the array of property names.
    
        delete [] devicePropNames;
        
    }