Обратные вызовы в C++ - [50]
>using ControlPointer = std::unique_ptr
>thread_local ControlPointer g_SensorControl(sensor::ISensorControl::createControl());
6.3.5. Настройка драйвера
В исходной реализации в начале работы мы создавали необходимый класс драйвера, который затем передавали интерфейсному классу (Листинг 107). Но в интерфейсах системных API мы классы использовать не можем, как поступить в этом случае? Можно предложить следующее решение: класс драйвера создавать внутри API, а в функцию настройки передавать идентификатор, в соответствии с которым будет создан соответствующий драйвер (Листинг 108).
>ISensorControl sensorControl = ISensorControl::createControl;
>DriverPointer driver = IDriver::createDriver(DRIVER_SIMULATION);
>driver->initialize();
>sensorControl->assignDriver(driver);
>
>thread_local sensor::DriverPointer g_DriverSimulation; // (1)
>
>thread_local sensor::DriverPointer g_DriverUSB; // (2)
>
>thread_local sensor::DriverPointer g_DriverEthernet; // (3)
>
>void CreateDriver(sensor::DriverType driverType, sensor::DriverPointer& driverPointer) // (4)
>
>{
>
> if (!driverPointer)
>
> {
>
> driverPointer = sensor::IDriver::createDriver(driverType);
>
> driverPointer->initialize();
>
> }
>
> g_SensorControl->assignDriver(driverPointer);
>
>}
>
>ErrorCode assignDriver(DriverType driverType) // (5)
>
>{
>
> ErrorCode error = ERROR_NO;
>
> try
>
> {
>
> EnumConverter
>
> conv.convert (driverType,
>
>{sensor::DriverType::Simulation, sensor::DriverType::Usb, sensor::DriverType::Ethernet}); // (6)
>
> if (conv.error())
>
> {
>
> return ERROR_INVALID_ARGUMENT;
>
> }
>
> switch (conv.result()) // (7)
>
> {
>
> case sensor::DriverType::Simulation:
>
> {
>
> CreateDriver(sensor::DriverType::Simulation, g_DriverSimulation);
>
> }
>
> break;
>
> case sensor::DriverType::Usb:
>
> {
>
> CreateDriver(sensor::DriverType::Usb, g_DriverUSB);
>
> }
>
> break;
>
> case sensor::DriverType::Ethernet:
>
> {
>
> CreateDriver(sensor::DriverType::Ethernet, g_DriverEthernet);
>
> }
>
> break;
>
> }
>
> }
>
> catch (sensor::sensor_exception& e)
>
> {
>
> error = static_cast
>
> }
>
> return error;
>
>
>}
В строках 1–3 объявляются указатели для хранения классов всех возможных типов драйверов. В строке 4 объявлена вспомогательная функция для создания драйвера. Эта функция проверяет, создан ли драйвер соответствующего типа, при необходимости создает, инициализирует и передает его в интерфейсный класс.
В строке 5 приведена реализация интерфейсной функции для настройки драйвера. В строке 6 конвертируется переданное числовое значение в перечисление C++ (будет рассмотрено ниже). В строке 7 объявлен оператор switch, в котором анализируется полученное значение перечисления, и вызывается вспомогательная функция с соответствующими параметрами.
В функции API для задания типа драйвера используются числовые значения, а в интерфейсном классе используются перечисления C++. Для того, чтобы сконвертировать числовое значение в перечисление, используется вспомогательный класс EnumConverter (Листинг 109)
>template
>class EnumConverter
>{
>public:
> template
> void convert(ConvValueType value, std::initializer_list
> {
> isError_ = true;
> for (Enum item : list) // (4)
> {
> if (static_cast
> {
> result_ = item; // (6)
> isError_ = false;
> break;
> }
> }
> };
> bool error() const { return isError_; }
> Enum result() const { return result_; }
>private:
> bool isError_;
> Enum result_;
>};
В строке 1 объявлен шаблонный класс, параметром которого является тип перечисления. Конвертация происходит в функции 2, которая объявлена в виде шаблона, параметром шаблона является тип числового значения для конвертации. Функция принимает число, которое должно быть сконвертировано, а также список значений перечисления (строка 3). Реализация пробегает по всем элементам списка (строка 4) и, если какой-то из элементов списка перечисления равен переданному значению, запоминает это значение перечисления в качестве результата (строки 5,6).
6.3.6. Обратные вызовы
Касательно обратных вызовов мы имеем следующую ситуацию. В системном API контекст вызова передается с помощью указателей на данные, по-другому организация передачи контекста здесь невозможна (см. п. 2.1.2). В интерфейсном классе указатель на данные не используется, поскольку в C++ имеется множество гораздо более изящных способов передачи контекста. Вот тут-то нам и понадобится перенаправление вызовов (см. п. 4.6.2). Реализация одной из интерфейсных функций API, использующей перенаправление вызовов, приведена в Листинг 110.
Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.
Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.