Task #3756
openГенерация C++ кода для модели сообщений
0%
Description
Небходимо разработать метод генерации C++ кода для модели сообщений.
На вход методу подается несколько объектов класса Adapter. В виде какой структуры данных эти "несколько" будут подаваться - на твое усмотрение. Например, можно взять ту же, что использовалась
в инструменте signalsGrouper для хранения набора накликанных "интерфейсов".
Т.к. все адаптеры между собой различны и полных совпадений между ними быть не должно, то из самых общих соображений могу предложить использовать java.util.Set.
Суть метода такова: проходим по всем адаптерам и извлекаем из них объекты MessageType и помещаем их в промежуточное хранилище (возможно, тот же Set). При этом необходимо проверять, что в хранилище ещё нет такого же типа сообщений (а при разработке адаптеров для разных интерфейсов вполне реально, что они будут использовать сообщения одного типа)- делать такую проверку лучше всего посредством разработки метода сравнения equals в классе MessageType.
Шаблон для *.h-файла
#pragma once #include <hw/message.hpp> namespace имя_пространства_имен {Про извлечение название пространства имен смотри #3755
Для каждого типа сообщений далее генерируем следующий код:
MESSAGE(имя_типа_сообщений) { public: имя_типа_сообщений(); virtual ~имя_типа_сообщений(); SUPPORT_CLONE(имя_типа_сообщений);
Далее для всех полей сообщения данного типа генерируем вызов соответствующего макроса. Макросы бывают следующие:
1) Если размер поля больше 64 бит, то нужно использовать
- CPPTESK_DECLARE_FIELD_ARRAY(имя_поля, размер_массива, размер_поля); - если маска не задана
- CPPTESK_DECLARE_MASKED_FIELD_ARRAY(имя_поля, размер_массива, размер_поля, маска_поля); - если маска задана
В силу особенностей реализации параметр размер_поля делаем равным 64, а параметр размер_массива делаем таким, чтобы удовлетворялось следующее неравенство:
capacity <= размер_поля*размер_массива
где capacity - одноименное поле соответствующего экземпляра класса MessageField.
2) Если размер поля меньше, или равен 64 бит, то нужно использовать
- CPPTESK_DECLARE_FIELD(имя_поля, размер_поля);
- CPPTESK_DECLARE_MASKED_FIELD(имя_поля, размер_поля, маска_поля);
- CPPTESK_DECLARE_BIT(имя_поля); - если размер поля равен 1
}; }
Заголовочный файл называем имя_пространства_имен_msg.h
Шаблон для .cpp файла
include <имя_пространства_имен_msg.h> namespace имя_пространства_имен {
Для каждого из типов сообщений генерируем следующий код конструктора и деструктора
имя_типа_сообщений::имя_типа_сообщений(void) {
Для всех полей сообщения, у которых incomparable равно false (см. #3754):
ADD_FIELD(имя_типа_сообщений::имя_поля);
Для всех полей сообщения, у которых incomparable равно true (см. #3754):
ADD_INCOMPARABLE_FIELD(имя_типа_сообщений::имя_поля);
Рандомизируем значения полей - только если оно соответствует входному интерфейсу!
RANDOMIZE_MESSAGE(*this); } имя_типа_сообщений::~имя_типа_сообщений(void) {} }
Рекомендация - данную задачу стоить решать посредством разработки нескольких относительно простых методов в соответствующих классах, а не одного сложного.