В моем приложении QML есть бэкэнд для получения сообщений (в формате: id + data), и я показываю его QML как Q_PROPERTIES.
Проблема в том, что после увеличения количества MyMsg с 10 до ~ 200 я получил много нечистоты и безумно сложный в обслуживании код.
Я нашел способ использовать препроцессор и очистил его, но все еще есть возможности для улучшения (я думаю), но я не могу этого понять. Текущий код (максимально упрощенный):
typedef enum
{
Msg1 = 1,
SomeMsg = 12,
SomeOtherMsg = 123,
moreOfThose = 9999
} MyMsg;
#define AUTO_PROPERTY(TYPE, NAME) \
Q_PROPERTY( \
TYPE NAME READ get_##NAME WRITE set_##NAME NOTIFY notify_##NAME) \
public: \
TYPE get_##NAME() const \
{ \
return a_##NAME; \
} \
void set_##NAME(const TYPE &value) \
{ \
if (a_##NAME == value) \
return; \
a_##NAME = value; \
emit notify_##NAME(value); \
} \
Q_SIGNAL void notify_##NAME(TYPE value); \
\
private: \
TYPE a_##NAME;
#define CASE_PROPERTY(NAME, PARAM) \
case NAME: \
set_##NAME(PARAM); \
break;
class Backend {
AUTO_PROPERTY(QString, Msg1)
AUTO_PROPERTY(QString, SomeMsg)
AUTO_PROPERTY(QString, SomeOtherMsg)
AUTO_PROPERTY(QString, moreOfThose)
public:
Backend(){};
private:
void parse(MyMsg msg, int value)
{
switch (msg)
{
CASE_PROPERTY(Msg1, value);
CASE_PROPERTY(SomeMsg, value);
CASE_PROPERTY(SomeOtherMsg, value);
CASE_PROPERTY(moreOfThose, value);
}
}
}
Я бы хотел увидеть что-то вроде:
class Backend {
AUTO_PROPERTIES(MyMsg)
public:
Backend(){};
private:
void parse(MyMsg msg, int value)
{
switch (msg)
{
CASE_PROPERTIES(MyMsg)
}
}
}
Примечание: файл с перечислением является внешним (общим) заголовком. Можно улучшить, но в целом его не следует изменять.
Примечание 2: чтобы разрешить двунаправленную связь в QML, он уже заключен в оболочку, хотя, кажется, не имеет отношения к случаю
namespace ABC {
Q_NAMESPACE
#include "../common/mymsg.hpp"
Q_ENUM_NS(MyMsg)
} // namespace ABC
Любой подсказка, чтобы помочь мне разобраться?