Передача входных данных в конечный автомат (c #)
-
04-07-2019 - |
Вопрос
Я постараюсь объяснить свой сценарий как можно лучше;
При каждом применении тикать Я запрашиваю текущее состояние клавиатуры и мыши и объединяю их в отдельные классы и структуры данных.Для клавиатуры это массив моих Ключи enum (по одному элементу для каждой из нажатых в данный момент клавиш), а для мыши это класс, содержащий дельта-координаты и bools для каждой нажатой кнопки.
У меня также есть рудиментарный конечный автомат, управляемый через класс state manager, который поддерживает стек и маршалирует состояния.
Все, что я хочу знать, это как лучше всего передать входные данные (моментальные снимки) отдельным состояниям, в которых мое приложение может находиться в любой момент времени?
Я хотел бы обработать как можно больше входных данных вдали от отдельных состояний, чтобы уменьшить повторяющуюся логику внутри состояний.
Или было бы лучше сохранить входные снимки как можно более чистыми и передать их состояниям, чтобы они могли скрывать логику, специфичную для ввода?
Примечание
Эта структура похожа на то, как я представляю себе работу игры, и хотя это приложение не является игрой, его необходимо обработать как можно быстрее.
Решение
Почему вы запрашиваете состояние клавиатуры и мыши при каждом нажатии?Гораздо лучшим и традиционным решением было бы фиксировать события, запускаемые с клавиатуры и мыши.Таким образом, вам нужно обновлять состояние только тогда, когда это необходимо.
Другие советы
Если вы просто будете запрашивать клавиатуру и мышь при каждом нажатии, я могу гарантировать, что вы столкнетесь с проблемами.Когда вы запрашиваете каждый тик, вы обнаружите, что пропускаете входные данные, которые происходят быстро (во временной области одного тика).Представьте ситуацию, когда пользователь нажимает и отпускает клавишу / button между двумя нажатиями (это будет происходить чаще, чем вы думаете) - вы полностью пропустите ввод.
Особенно в C #, который является полностью ориентированный на входные события, подобные этому, вы должны использовать events.
В XNA они делают это, делая класс keyboard статичным.
KeyboardState state = Keyboard.GetState();
затем вы можете получить доступ к текущему состоянию ключа с помощью приведенной выше строки кода.
Вы должны запускать события и фиксировать аргументы.Это был бы самый простой и эффективный способ справиться с этой проблемой.
class YourClass
{
//data members ...
public void OnKeyboardPress(object sender, EventArgs args)
{
//handle your logic capturing the state here
}
}
//elsewhere
someControl.KeyPress += new KeyPressDelegate(yourClassInstance.OnKeyboardPress);