Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Регистрация Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Блоги > Идиотизмы

Даже в определениях идиотизма встречается идиотизм.
Цитата:
Идиотизм — устаревшее название идиомы
Идиома в программировании — понятие близкое к понятию шаблона проектирования. Идиомы представляют собой шаблоны проектирования, учитывающие специфику конкретного языка программирования и потому не универсальные. Это хорошие решения проектирования для конкретного языка или программной платформы.
Оценить эту запись

Кто не успел - тот опоздал

Запись от BlooDHounD размещена 19.04.2011 в 14:09
Обновил(-а) BlooDHounD 19.04.2011 в 14:23

для понимания материала необходимы следующие знания:
getTimer


давно ничего не писал. сейчас буду ругать таймеры.

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

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

начали тестировать и проблема долго не наблюдалась, пока однажды во время тестов мы не свалили на обед, оставив игру запущенной. вернувшись мы таки увидели задержку на реакцию в ~4 секунды. оставив на ночь мы получили задержку почти в минуту.

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

с тех пор прошло года три, но проблема всё ещё актуальна.

для решения этого косяка мы начали использовать ( new Date() ).getTime(), придумав свой блэкджек
Код AS3:
package by.blooddy.core.utils.time {
 
	import flash.utils.getTimer;
 
	/**
	 * @author					BlooDHounD
	 * @version					1.0
	 * @playerversion			Flash 10
	 * @langversion				3.0
	 */
	public function getTimer():Number {
		return flash.utils.getTimer() + deltaTime;
	}
 
}
 
//======================================================================
//
//  Inner definitions
//
//======================================================================
 
import flash.utils.getTimer;
import flash.utils.setInterval;
 
/**
 * эта величина характеризует на сколько флэшовый таймер сбился
 * относительно системного времени
 */
internal var deltaTime:Number = 0;
 
/**
 * время старта таймера
 */
internal const startTime:Number = ( new Date() ).getTime() - getTimer();
 
/**
 * взводим таймер для периодической синхронизации
 */
setInterval( function():void {
	deltaTime = ( new Date() ).getTime() - startTime - getTimer();
}, 10e3 );
Всего комментариев 22

Комментарии

Старый 19.04.2011 15:02 incvizitor вне форума
incvizitor
 
Аватар для incvizitor
Спасибо, будем юзать)
Старый 19.04.2011 15:12 wvxvw вне форума
wvxvw
 
Аватар для wvxvw
Идея понятна, реализация не понятна. Зачем нужно было высчитывать разницу с getTimer, если известно, что он не точный? Можно было сохранить дату запуска приложения и на запрос к getTimer отдавать разницу между текущей датой и сохраненной. И интервалы не нужны... или это такая попытка сэкономить на создании дат?
Кроме того, надо уточнять, что проблема судя по всему платформо-зависимая, и, более того, может не зависеть от плеера - возможно какой-то сервис в системе, который обеспечивает информацию о текущем времени работает не правильно. В Линуксе такой проблемы не наблюдается, оставлял работать на несколько дней автономно и синхронизация не нарушалась.
Старый 19.04.2011 15:47 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
Цитата:
Сообщение от wvxvw
Идея понятна, реализация не понятна. Зачем нужно было высчитывать разницу с getTimer, если известно, что он не точный? Можно было сохранить дату запуска приложения и на запрос к getTimer отдавать разницу между текущей датой и сохраненной. И интервалы не нужны... или это такая попытка сэкономить на создании дат?
ну если сам додумался, зачем переспрашивать?
Цитата:
Сообщение от wvxvw
Кроме того, надо уточнять, что проблема судя по всему платформо-зависимая, и, более того, может не зависеть от плеера - возможно какой-то сервис в системе, который обеспечивает информацию о текущем времени работает не правильно. В Линуксе такой проблемы не наблюдается, оставлял работать на несколько дней автономно и синхронизация не нарушалась.
да. платформо-, процессорно- и плэйера-зависимо.
Старый 19.04.2011 15:48 petyar вне форума
petyar
А что будет, если во время игры произойдет синхронизация с тайм-сервером?
Старый 19.04.2011 16:14 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
@petyar, видимо конец всему.
Старый 19.04.2011 23:35 etc вне форума
etc
 
Аватар для etc
Олежка, время плавает чаще всего под виндами XP с не очень свежей версией FP, например.
Старый 20.04.2011 00:27 wvxvw вне форума
wvxvw
 
Аватар для wvxvw
Хз, есть вариант, что в Виндовсе в плеере использовали GetProcessTimes для getTimer - как-бы оно само по себе напрашивается. А как именно оно работает - я не знаю, есть такая же вероятность, что работает не [совсем] правильно даже просто в зависимости от того, кто создал процесс с плеером / что именно в Виндовсе считается временем занимаемым процессом (вполне возможно, что Виндовс не считает какое-то время, если какие-то условия не выполнялись), вобщем, не понятно Т.е. время работы процесса с точки зрения компутера может не совпадать с астрономическим, если например, компутер не считает, что процесс работал, когда он "спал"... хз.
Я думаю, для полноты эксперимента стоило бы запустить рядом таймер который бы показывал, что эта функция вернет.
Старый 20.04.2011 00:48 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
на маке дельта всегда равно 0 - Денис проверял.
на винде баг в те времена проявлялся на core2duo.
на линуке не помню. кажись проявлялся.
Старый 20.04.2011 01:27 wvxvw вне форума
wvxvw
 
Аватар для wvxvw
Не, я это говорю к тому, что есть вариант, что мы не правильно понимаем, что нам должен сообщать getTimer() - есть вариант, что он сообщает время, которое процессор потратил на наш процесс (и хотя, процесс флеша *никогда* не останавливался, это может не совпадать с астрономическим временем, которое выполнялась наша программа).
Старый 20.04.2011 03:32 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
wvxvw, мы понимаем только то, что нам пишут в справке. все остальные теории о том, что мы "как-то не так" понимаем не верны.
Старый 20.04.2011 11:31 wvxvw вне форума
wvxvw
 
Аватар для wvxvw
Так в справке, собственно, и не уточняется, какое именно время считается - написано "с момента запуска виртуальной машины". Я не думаю, что разработчики задумывались о том, что может быть разница, но, по факту, она может быть. В том же Лиспе по этой причине есть 2 разные функции: get-internal-real-time и get-internal-run-time, первая сообщает время работы процесса опираясь на астрономическое время, вторая - на процессорное время.
Старый 20.04.2011 13:45 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
ты сейчас хочешь приплести квантовую механику, что бы оказаться правым? время в миллисекундах - это не время в тика или чём-то ещё ( я точно уверен, что мой комп не двигается со скоростью близкой к скорости света ).
Старый 20.04.2011 15:37 arkadattx вне форума
arkadattx
А на каких версиях ФП это тестилось?
Старый 20.04.2011 16:18 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
arkadattx на всех. начиная с 9.0.115
Старый 20.04.2011 18:38 wvxvw вне форума
wvxvw
 
Аватар для wvxvw
Правым в чем? Я ничего не утверждаю. Это предположение: может быть getTimer считает процессорное время а не астрономическое. Было бы интересно проверить, если придумать как именно это сделать. Возможно предположение верное, а может и нет. Написал я это думая, что это может быть кому-то интересно и у кого-то будет идея, как это можно проверить.
Старый 20.04.2011 19:14 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
да не важно совершенно что он считает ) известно, что он должен считать.
Старый 21.04.2011 08:54 alexcon314 вне форума
alexcon314
В getTimer() не используется GetProcessTimes(), хоть оно и напрашивается. Вызов getTimer() связан с QueryPerformanceCounter() (возможно и с QueryPerformanceFrequency() и используется какой-то алгоритм обработки данных обоих счетчиков, не проверял, ибо лень). Ну, а тут есть варианты, например: QueryPerformanceCounter - бомба замедленного действия.
У MS всегда были проблемы со временем). Странно, что плеер не использует здесь банальный GetTickCount().
Старый 21.04.2011 16:00 dimarik вне форума
dimarik
 
Аватар для dimarik
А существует ли API-метод, возвращающий время, которое в BIOS видно?
Старый 21.04.2011 17:42 alexcon314 вне форума
alexcon314
Вопрос, конечно, интересный. Максимум, что можно выжать из API - загрузить сырые байтики.
В виндах - GetSystemFirmwareTable() и EnumSystemFirmwareTables(). А потом по спецификации вприпрыжку).
Но, вроде, кто-то-где-то-чего-то выкладывал в виде отдельных фреймворков, кажись..
Да, еще WMI есть, но это как-то не очень...
Старый 07.06.2012 09:34 alexcon314 вне форума
alexcon314
Интересный топик попался на глаза. Безотносительно к флешу, но по сути проблема очень похожая. Это по поводу плавающего времени в виндах и QueryPerformanceCounter() вот люди тоже косяки ловят http://forum.sources.ru/index.php?showtopic=358370
Не ругайтесь за некропостинг).
Старый 27.07.2012 23:04 Котяра вне форума
Котяра
 
Аватар для Котяра
не будем)
Старый 27.07.2012 23:22 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
не надо?
 

 


Часовой пояс GMT +4, время: 14:38.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2017, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.