Я пытаюсь реализовать гибкий, удобный для пользователя интерфейс для игры 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).
Так что либо я не смогу кодировать интерфейсы, либо мне придется добавить целый набор переменных класса, которые могут или не могут быть использованы.
Может быть, я пытаюсь использовать неправильный шаблон. Что бы вы посоветовали для решения этой проблемы?
Спасибо!