Rx:SSSsssss...(Так звучат Reactive Extensions, Windows Phone 7 и змея...)
Reactive Extensions – это нечто, о чем я писал не много (хм…совсем… хм). Reactive Extensions (Rx) – это вид, сорт, не совсем так, но один из способов представления этого – "LINQ для событий".
Вот краткое описание из статьи MSDN «Reactive Extensions для .NET. Обзор для Windows Phone»:
Reactive Extensions для .NET Framework – это управляемая библиотека, обеспечивающая API для написания реагирующих приложений. Реагирующие приложения управляются своим окружением. В модели реагирования потоки данных, асинхронные запросы и события представляются наблюдаемыми последовательностями. Приложение может подписаться на эти наблюдаемые последовательности для получения асинхронных сообщений при поступлении новых данных. Reactive Extensions позволяют приложению комбинировать эти последовательности с помощью операторов запросов.
Если приложение взаимодействует со множественными источниками данных, такими как события пользовательского ввода, запросы веб-сервисов и системные предупреждения, обычным способом управления является реализация раздельных обработчиков для каждого из этих потоков данных. Внутри каждого обработчика требуется создать код для координации взаимодействия между всеми различными потоками данных и их обработки в пригодную форму. Reactive Extensions позволяют создать запрос, объединяющий все потоки данных в единый поток, запускающий единый обработчик. Работу по фильтрации, синхронизации и преобразованию данных выполняет запрос Reactive Extensions, так что обработчик должен только реагировать на получаемые данные и что-то делать с ними.
...
Итак где же удовольствие? Как будет выглядеть простая игра, использующая Rx? Скажем игра на Windows Phone 7?
Андреа Бошин (Andrea Boschin), Реактивная змея для Windows Phone 7
Продолжая свои эксперименты с Reactive Extension, я собрал небольшой пример, демонстрирующий альтернативное использование библиотеки для создания небольшой игры. Игра известна под названием «Змея», в нее играли многие из нас на телефонах Nokia, когда она была единственной игрой в устаревших моделях. Пожалуйста, отметьте, что игра, которую я написал, не закончена, так как она, прежде всего, – пример использования технологии и того, как можно упростить разработку слегка усложненной логики, вроде той, что стоит за данной игрой.
Ядро игры основано на двух раздельных использованиях Reactive Extensions. С одной стороны есть главный цикл, базирующийся на частых таймаутах, которые в полной версии игры должны использоваться для изменения скорости игры. В этой версии таймаут установлен в 75 мсек. Каждый раз когда истекает таймаут я передвигаю змею на одну позицию вперед, сохраненную в переменных XDirection и YDirection. Эти переменные принимают значения 1 или -1, если змея движется в этом направлении и 0, если она движется перпендикулярно.
...
Цель игры (заметьте, как сказал Андреа, это не завершенная игра, с меню, историей и т.п.) – управлять змеей так, чтобы она двигалась к обозначаемым местам экрана. Вы управляете змеей, которая постоянно двигается, путем касаний разных частей экрана, которые изменяют направление движения змеи.
Звучит просто, но это действительно проблема.
Итак, что же вызывает восхищение? Количество кода, который вы не должны писать. Объем кода в игре удивительно мал. 95% относится к установке, снесению и инфраструктурному коду. Ядро, главная логика, имеющая дело с движением змеи и обработкой взаимодействия с пользователем содержит удивительно мало кода.
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
this.Pulse.Begin();
this.RandomizeGem();
// GESTIONE DEL TOUCH DELLO SCHERMO
Observable.FromEvent<ManipulationStartedEventArgs>(
ev => this.ManipulationStarted += ev,
ev => this.ManipulationStarted -= ev)
.Select(
o =>
{
return new
{
X = Math.Sign(o.EventArgs.ManipulationOrigin.X - 240),
Y = Math.Sign(o.EventArgs.ManipulationOrigin.Y - 400)
};
})
.Subscribe(
o =>
{
if (this.XDirection != 0 && this.YDirection == 0)
{
this.XDirection = 0;
this.YDirection = o.Y != 0 ? o.Y : this.YDirection;
}
else if (this.XDirection == 0 && this.YDirection != 0)
{
this.XDirection = o.X != 0 ? o.X : this.XDirection;
this.YDirection = 0;
}
});
// GESTIONE DELLO SNAKE
Observable.GenerateWithTime(
new Point(0, 0),
p => this.IsRunning,
p => p,
p => TimeSpan.FromMilliseconds(75),
p => this.NewPoint(p))
.ObserveOnDispatcher()
.TrailWhile(o => o > this.Lenght)
.Subscribe(this.EvaluateAndDrawSnake);
}
Это действительно вся главная логика игры. Конечно, есть еще методы рисования, и несколько вспомогательных блоков, но весь рабочий код можно видеть на фрагменте выше.
В настоящий момент Rx мало используются, недооценены и отсутствуют в поле зрения большинства разработчиков. Но если вы что-то делаете с событиями, будь то пользовательские воздействия, внешние события, аппаратные прерывания и т. д. и т. д. (и не большинство программ?), то Rx стоит посмотреть.
Несколько ссылок, которые могут быть интересны:
- Цент разработки Data Developer Center - Обучение - Reactive Extensions
- Reactive Extensions для .NET. Обзор для Windows Phone
- Windows Phone Geek – Игра «Реактивная змея» для WP7 с полным исходным кодом
- “Исследования Reactive Extensions”
- Reactive Extensions | Tags | Channel 9 – Видео на канале Channel 9: ...