После подключения к устройству через адаптер пользователи могут захотеть просмотреть или изменить значения свойств устройства. Например, пользователь может настроить значение Brightness или получить текущее значение Temperature собственность. (Сведения об определении свойств, которые требуется предоставить пользователям, см. в разделе Создание свойств устройства.)
Чтобы получить уведомление от обработчика, когда пользователь хочет просмотреть или изменить свойство, свяжите объект прослушивателя со свойством. Панель инструментов определяет два типа классов прослушивателей: получить прослушиватели, которые отвечают на get команды и установка прослушивателей, которые отвечают на set команды.
Чтобы обеспечить поддержку получения и установки значений свойств, выполните следующие действия.
Определите класс прослушивателя соответствующего типа. Панель инструментов определяет два абстрактных класса: один для получения прослушивателей и один для набора прослушивателей, из которых вы извлекаете класс.
Реализуйте виртуальную функцию, требуемую для класса.
Свяжите экземпляр класса прослушивателя со свойством.
В следующих разделах описывается, как настроить получение прослушивателей и установку прослушивателей в адаптере.
Получение уведомления от обработчика при запросе пользователем текущего значения свойства с помощью get команда:
Определите класс get listener, извлекая его из IPropCustomGetFcn абстрактный класс - см. Определение класса Get Listener.
Реализация getValue() виртуальная функция в классе прослушивателя - см. раздел Создание функции getValue () для вашего класса .
Связать экземпляр класса прослушивателей со свойством - см. раздел Связывание прослушивателей Get со свойствами.
Создание класса get listener, производного от абстрактного класса IPropCustomGetFcn, как показано в следующем примере.
В этом примере конструктор принимает дескриптор к IAdaptor объект. Поскольку панель инструментов устанавливает прослушиватели для каждого экземпляра, передача этого дескриптора может быть полезной, но это не является обязательным требованием.
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() функция класса get listener, связанного со свойством.
Ваш getValue() функция должна принимать два параметра:
void getValue(IPropInfo* propertyInfo, void* value)
propertyInfo является дескриптором для IPropInfo объект. - IPropInfo - это интерфейс, позволяющий получить информацию о свойстве. Например, использование IPropInfo можно получить имя свойства, тип его склада и значение по умолчанию. Эта информация полезна при наличии общего класса прослушивателей, который обрабатывает несколько свойств.
value является указателем на расположение в памяти, где адаптер сохраняет запрошенное значение свойства. - Обработчик передает это значение как void*. Ваш getValue() функция должна привести значение к соответствующему типу данных C++. В следующей таблице указывается тип данных C++ для всех типов свойств, поддерживаемых набором адаптеров.
imaqkit:: PropertyTypes | Тип данных C++ |
|---|---|
|
|
|
|
|
|
|
|
|
|
Для нескалярных типов данных, символьных векторов, двойных массивов и целых массивов класс прослушивателя должен выделить достаточный объем памяти для текущего значения свойства с помощью new[] оператор. Модуль удаляет эту память, вызывая delete[]. Пример использования свойства символьного вектора:
char** returnStr = reinterpret_cast<char**>(value); *returnStr = imaqkit::imaqmalloc(sizeof(char) * (stringLength)); strcpy(*returnStr, currentPropertyValueString);
Предлагаемый алгоритм для функции getValue ( ). Конструкция getValue() функция зависит от потребностей вашего устройства и возможностей, предлагаемых его SDK. Например, можно создать один класс прослушивателя get, который обрабатывает запросы значений для всех свойств в определенном контейнере свойств (общем или зависящем от устройства). В этом случае getValue() функция включает инструкцию switch с кейсами, обрабатывающими каждое отдельное свойство.
Либо определите отдельный класс прослушивателя get для каждого свойства или каждого типа хранения свойств. Затем обработчик вызывает определенный прослушиватель для указанного свойства.
Можно также определить классы получения прослушивателя, которые соответствуют способу организации конфигурации свойств 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);
}
Чтобы настроить прослушиватель для свойства, необходимо связать объект прослушивателя со свойством в контейнере свойств. В следующем примере показано, как добавить прослушиватели get для всех специфичных для устройства свойств в контейнере свойств адаптера. Составители адаптеров обычно настраивают прослушиватели свойств в конструкторе класса адаптеров - см. раздел Реализация конструктора класса адаптеров.
Получить дескриптор соответствующего объекта контейнера свойств.
IEngine объект имеет две функции-члена, возвращающие дескрипторы в контейнеры свойств (IPropContainer объекты). Пример вызывает IEngine класс getAdaptorPropContainer() функция-член для получения контейнера свойств, специфичных для устройства:
imaqkit::IPropContainer* adaptorPropContainer =
getEngine()->getAdaptorPropContainer();
Добавление прослушивателя get к свойству в контейнере с помощью IPropContainer объект setCustomGetFcn() функция. В качестве аргументов укажите имя свойства и дескриптор объекта прослушивателя.
Примечание
Поскольку панель инструментов удаляет каждый экземпляр объекта-прослушивателя, когда пользователь удаляет объект ввода видео, свяжите новый экземпляр объекта-прослушивателя с каждым свойством.
В следующем примере выполняется итерация всех свойств в контейнере свойств адаптера, связывающая объект get listener с каждым из них.
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 команда:
Определите класс прослушивателя аппарата, извлекая его из IPropPostSetListener абстрактный класс - см. Определение класса прослушивателя набора.
Реализация notify() виртуальная функция в классе прослушивателя аппарата - см. Создание функции notify () для вашего класса .
Связать экземпляр класса прослушивателя набора со свойством - см. раздел Связывание прослушивателей набора со свойствами.
Создание класса прослушивателя набора, производного от абстрактного класса IPropPostSetListener, как показано в следующем примере. (Имя класса включает слово Post потому что панель инструментов уведомляет прослушивателей после обновления значения свойства, сохраненного в контейнере.)
В этом примере конструктор принимает дескриптор к IAdaptor объект. Поскольку панель инструментов устанавливает прослушиватели для каждого экземпляра, передача этого дескриптора может быть полезной, но это не является обязательным требованием.
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;
};
Когда пользователь вызывает set для изменения значения свойства модуль вызывает notify() функция класса прослушивателя аппарата, связанного со свойством.
Класс прослушивателя набора notify() функция должна принимать два параметра:
void notify(IPropInfo* propertyInfo, void* newValue)
propertyInfo является дескриптором для IPropInfo объект - IPropInfo - это интерфейс, позволяющий получить информацию о свойстве. Например, использование IPropInfo можно получить имя свойства, тип его склада и значение по умолчанию.
newValue является указателем на новое значение свойства - этот обработчик передает это значение как void*. Ваш notify() функция должна привести значение к соответствующему типу данных C++. В следующей таблице указывается тип данных C++ для всех типов свойств, поддерживаемых набором адаптеров.
imaqkit:: PropertyTypes | Тип данных C++ |
|---|---|
|
|
|
|
|
|
|
|
|
|
Предлагаемый алгоритм для функции 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);
}
Чтобы настроить прослушиватель для свойства, необходимо связать объект прослушивателя со свойством в контейнере свойств. В следующем примере показано, как добавить прослушиватели набора для всех свойств устройства в контейнере свойств адаптера. Составители адаптеров обычно настраивают прослушиватели свойств в конструкторе класса адаптеров - см. раздел Реализация конструктора класса адаптеров.
Получить дескриптор соответствующего объекта контейнера свойств.
IEngine объект имеет две функции-члена, возвращающие дескрипторы в контейнеры свойств (IPropContainer объекты). Пример вызывает IEngine класс getAdaptorPropContainer() функция-член для получения контейнера свойств, специфичных для устройства:
imaqkit::IPropContainer* adaptorPropContainer =
getEngine()->getAdaptorPropContainer();
Добавление прослушивателя набора к свойству в контейнере с помощью 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;
}