2009-07-07 5 views
2

Я разрабатываю симуляцию полета на рабочем столе Java. Мне нужно записать все пилотные действия, которые происходят в кабине, такие как управление дроссельной заслонкой, рулевое управление, развертывание оружия и т. Д., Чтобы я мог просматривать эти события позже (или транслировать их в прямом эфире).Как перематывать состояние приложения?

Я хотел бы добавить функцию воспроизведения изображений при воспроизведении событий, чтобы я мог визуально видеть кокпит, когда я двигаюсь вперед и назад во времени. Нет проблем с воспроизведением, пока я воспроизвожу событие в хронологическом порядке, но перемотка немного сложнее.

Как бы вы реализовали функцию перемотки?

ответ

2

Вы можете использовать вариант Command Pattern, и каждый из ваших пилотных действий выполняет операцию отмены.

Например, если ваш пилот сделал рулевое управление слева (просто, я знаю), его обратное будет направлено справа.

public interface IPilotAction { 
    void doAction(CockpitState state); 
    void undoAction(CockpitState state); 
} 

public class ThrottleControl implement IPilotAction { 

    private boolean increase; 
    private int speedAmount; 

    public ThrottleControl(boolean increase, int speedAmount) { 
     this.increase = increase; 
     this.speedAmount = speedAmount; 
    } 

    public void doAction(CockpitState state) { 
     if (increase) { 
      state.speed += speedAmount; 
     } else { 
      state.speed -= speedAmount; 
     } 
    } 

    public void undoAction(CockpitState state) { 
     if (increase { 
      state.speed -= speedAmount; 
     } else { 
      state.speed += speedAmount; 
     } 
} 
3

Я бы использовал модифицированный Memento pattern.

Разница заключалась бы в том, что у меня был бы объект объектов Memento, содержащий список всех пилотных действий.

Шаблон Memento обычно используется для откат (отмена), однако в вашем случае я мог видеть его применение также. Вам нужно будет также, чтобы пилотные действия были состояниями, поддерживающими хранилище.

+0

Будет ли этот подход приемлемым для полета сима? Например, если я воспроизвожу события в течение 20 минут, а затем решаю перейти на 2 минуты, мне придется отменить 18-минутные события. Там может быть сотни событий для отмены. – 2009-07-07 13:57:11

+0

Всё зависит. Чем больше данных вы храните в каждом отдельном действии, тем больший ответ вы получите за счет памяти.Вы можете сохранить временной интервал, в котором произошло каждое действие, а также ВСЕ данные, которые вам понадобятся для события, а затем просмотреть список в хронологическом порядке, пока не найдете состояние, в котором вы были в этот период времени. Затем вам придется загрузить все те переменные, которые хранятся. Это займет немного памяти, но это сэкономит на производительности. – AlbertoPL

1

То, что вы ищете, на самом деле представляет собой смесь моделей Command и Memento. Каждое пилотное действие должно быть командой, которую вы можете зарегистрировать. Каждая зарегистрированная команда имеет, если req'd, запись в память любого дополнительного состояния, в котором (A) не находится в команде, и (B) не может быть надежно восстановлена. «B» важен, некоторые из этих состояний находятся в практически любой нетривиальной области. Его необходимо сохранить для точной реконструкции.

Если вы объедините эти понятия, по существу прикрепляя память к каждой команде, у вас будет полностью зарегистрированная серия детерминированных событий.

Я обсуждал это более подробно в different answer. Не бойтесь существенно адаптировать шаблоны проектирования к вашим конкретным потребностям. :)

RE Обеспокоенность Производительности:

Если вы планируете прыжки несколько минут, чтобы быть частым случай, и после реализации вы показываете, что это неосуществимое узкое место производительности, я хотел бы предложить реализацию случайный «снимка» по с механизмом каротажа. По существу, сохраняйте состояние всего приложения каждые несколько минут, чтобы свести к минимуму количество логарифмической перемотки, которое необходимо выполнить. Затем вы можете получить желаемый таймфрейм из ближайшего сохраненного состояния. Это аналогично key frames в анимации и мультимедиа.

+0

Итак, вы должны реализовать функцию отката (memento/command) и функцию моментального снимка? Будет ли система моментальных снимков с интервалом в 10 секунд не отказываться от отката? – 2009-07-07 14:15:58

+0

Снимки собираются, неявно, намного больше, чем журнал изменений (смешение/командная смесь). Если вам нужен мгновенный ход, и у вас есть память, чтобы записать, вы можете сделать это таким образом, но это компромисс, не так ли? Время против памяти. Вы единственный человек, который знает, сколько из них приемлемо для записи. (Хотя получение полного апплетатного снимка каждые 10 секунд кажется вероятным исчерпывающим ресурсом * очень быстро). Я предлагаю избегать преждевременной оптимизации. Сделайте это шаг за шагом. Получите либо appstate snapshots или logging working, затем перейдите к другому, а затем балансируйте между ними по мере необходимости. –

0

Не прямой ответ, но ознакомьтесь с обсуждением внедрения отмены. В основном это будут текстовые редакторы, но должны применяться те же принципы.

Это помогает, если вы предпочитаете неизменность. Отменить сложные изменения сложно. Даже автоматизированные системы имеют проблемы с производительностью (Software Transaction Memory, STM).

0

Убедитесь, что вы внедрили симуляцию таким образом, что «состояние» моделирования является функцией. То есть, функция времени.

Учитывая начальное состояние в момент времени T0, вы должны иметь возможность построить рамку моделирования в момент времени Tn для любого n. Например, начальное стационарное состояние и никакие события (пока) не могут совпадать с идентификационной функцией, поэтому Tn == Tn+1.

Для получения какого-либо экспериментального действия в момент времени Ta вы сможете построить кадр Ta+n для любого n. Таким образом, вы думаете о событиях как о модификации функции, которая принимает значение времени в качестве аргумента и возвращает кадр моделирования за это время.

Я бы использовал историю событий как Zipper из (времени, функции) пар, представляющих состояние управления имитацией. «Текущее» состояние будет в центре внимания, со списком будущих состояний справа и прошлыми состояниями слева. Как так:

([past], present, [future]) 

Каждый раз, когда изменяется состояние моделирования, записать новую функцию состояния в future. Запуск моделирования затем становится вопросом выбора функций из списка future и передачи текущего времени в них. Запуск его назад точно такой же, за исключением того, что вы выбираете события из списка past.

Так что, если вы во время Tn, и вы хотите, чтобы перемотать время Tn-1, заглянуть в past список для последнего состояния которого time атрибут меньше n-1. Передайте n-1 в свой атрибут function, и у вас есть состояние моделирования в момент времени Tn-1.

I've implemented a Zipper datastructure in Java, here.

0

вы можете просто хранить состояние в каждом конкретном случае. 1kb для состояния (скорость ветра, скорость объекта + ориентация/управляющие входные состояния, x 30fps x 20 min ~ 36megs. 1kb состояния позволят вам записать около 16 объектов (pos/speed/угловая скорость/ориентация/и 5 оси управления/Эффект)

Это может быть слишком много для вас, но это будет проще всего реализовать. Для воссоздания состояния (мгновенного acecss) не будет никакой работы, и вы можете легко интерполировать между состояниями (для более быстрое/медленное воспроизведение) .Есть дисковое пространство вы можете просто закрепить на нем, и это можно сделать во время записи, поэтому во время воспроизведения этой памяти невозможно зацепить.

Быстрый способ сэкономить место будет состоять в том, чтобы разбивать файл записи , и сжимать каждый бит отдельно, т. е. один поток zip для каждой минуты. Таким образом, вам нужно будет только сжимать текущий бит, сохраняя связку в памяти, но это зависит от того, насколько хорошо ваши данные состояния застегнуты.

записи команд и наличие файлов классов для реализации нескольких направлений воспроизведения потребует много отладочной работы. замедление/ускорение воспроизведения также будет более интенсивным с точки зрения вычислительной мощности. и единственное, что вы сохраняете, - это пространство.

если это премиум, есть и другие способы сэкономить на этом.