Шаблон проектирования для обработки команд пользовательского интерфейса - PullRequest
0 голосов
/ 07 января 2019

Я пытаюсь реализовать гибкий, удобный для пользователя интерфейс для игры UE4.

Интерфейс пользователя состоит из множества виджетов и класса HUD, который действует как посредник между остальной частью игры и самим интерфейсом. Связь между игрой, HUD и виджетами осуществляется через события.

У меня проблемы с определением правильного шаблона и / или реализации для обработки событий, передаваемых с помощью кнопок пользовательского интерфейса.

В начале у меня были кнопки с очень специфическими командами, такими как «приостановить игру». Я написал класс для представления универсальной команды, а затем создал подкласс для каждого желаемого поведения. Затем я использовал шаблон Visitor для обработки события, не зная, что это конкретно.

Пример установки псевдокода:

button.onClicked(...)
{
    ...
    commandObject.broadcast();
    ...
}

commandObject.broadcast()
{
    ...
    eventInstance.broadcast(this); // hud listens for this call
    ...
}

hudInstance.visit(Command * command)
{
    ...
    command.acceptVisitor(this);
    ...
}

eventInstance.acceptVisitor(HUD * hud)
{
    ...
    hud.doSomething();
    ...
}

Затем мне пришлось добавить кнопки с более динамическими командами, такими как «открыть контекстное меню для целевого объекта». Поэтому мне пришлось вернуться и реализовать интерфейс IHasUITarget с методами get / set для UI Target. Итак, теперь я сохраняю указатель на цель (которую я беру из объекта IHasUITarget, такого как виджет) в объекте TargetedCommand (который является потомком Command), а затем передаю цель при приеме посетителя HUD.

button.onClicked(...)
{
    ...
    commandObject.broadcast();
    ...
}

commandObject.broadcast()
{
    ...
    eventInstance.broadcast(this); // hud listens for this call
    ...
}

hudInstance.visit(Command * command)
{
    ...
    command.acceptVisitor(this);
    ...
}

eventInstance.acceptVisitor(HUD * hud)
{
    ...
    hud.doSomethingWithTarget(target); // got it using getUITarget() when initializing the command properties
    ...
}

Теперь я должен добавить поддержку таких команд, как «назначить задачу x целевому объекту». Что означает добавление другого параметра, интерфейса и т. Д.

У меня проблемы с этим, главным образом, потому что я чувствую, что могу нарисовать себя в углу в будущем, а также потому, что я хотел бы применить правильный выбор команды, когда дизайнер добавляет кнопку в виджет и выбирает команду с ним связано: интерфейс конструктора, используемый для выбора требуемых фильтров команд по классам, а класс определяется внутри заголовка объекта, который его содержит (в данном случае кнопка). Если я хочу ограничить приемлемые команды, мне придется создавать разные типы кнопок: один принимает объекты Command, другой принимает CommandChildA, другой принимает CommandChildB и т. Д. С другой стороны, если я не ограничиваю команды, мне нужно проверить, что объект Command, которому дизайнер назначил событие контекстного меню, действительно реализует IHasUITarget, прежде чем вызывать для него getUITarget. Точно так же, если бы я хотел инициализировать свойства Command, мне пришлось бы проверить, реализует ли Command соответствующий интерфейс, прежде чем делать вызов, такой как commandObject.setSomeProperty (Something * s). Так что либо я не смогу кодировать интерфейсы, либо мне придется добавить целый набор переменных класса, которые могут или не могут быть использованы.

Может быть, я пытаюсь использовать неправильный шаблон. Что бы вы посоветовали для решения этой проблемы?

Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...