Неактивная вкладка браузера Haxe полностью останавливается

Я разрабатываю браузерную игру с haxe. Пока у меня есть вкладка браузера в качестве активной вкладки, все работает так, как задумано, и плавно, но как только я переключаю вкладку (независимо от того, использую ли я Chrome или Firefox), она полностью перестает работать и не отправляет никаких сообщений. сердцебиение вообще на мой сервер.

Я знаю, что неактивные вкладки замедляют работу, и я также знаю, что неактивные вкладки не могут загружать ресурсы. (Моя игра этого не делает).

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

Есть ли способ, которым я могу обеспечить это?

Я использую Kha и Haxe, я пробовал родной планировщик haxe для сердцебиения и планировщик kha, оба они не работают, будучи неактивными.


person Rafael Kress    schedule 31.08.2017    source источник
comment
Хорошо, я попробовал сердцебиение с нетипизированным __js__(setTimeout)(heartbeat, 1250); который работал. эта командная строка работает по назначению даже на неактивной вкладке   -  person Rafael Kress    schedule 01.09.2017
comment
Обновление: хорошо, теперь я понял: haxe.delay или kha.scheduler вызывают метку времени, которая вызывает setTimeout только в том случае, если requestanimationframe имеет значение null, что, похоже, не так, просто не активно   -  person Rafael Kress    schedule 01.09.2017


Ответы (2)


Вы уже нашли его, но я думаю, что window.Top должно быть window.top.

Такая вещь выдавала бы ошибку, если бы вы не использовали :Dynamic. Окно — это типизированный объект, и вы получаете приятные ошибки, что является одним из преимуществ строго типизированного языка. requestAnimationFrame — это глобальная функция для окна, поэтому этот фрагмент работает без динамической аннотации.

var window = Browser.window;
if (window.requestAnimationFrame == null || window.top != window.self) window.setTimeout(animate, 1000.0 / 60.0);
else window.requestAnimationFrame(animate);

Вы также упоминаете, что проверка window.top != window.self проверяет, активно ли окно. Это неправда, он проверяет, работает ли окно в (i) фрейме. Кроме того, вы используете эту проверку только один раз (и только тогда, когда requestAnimationFrame не поддерживается, поэтому, если это не так в первый раз, вы никогда не будете получать обновления.

Вы можете использовать свойство !Browser.document.hidden, которое очень хорошо поддерживается https://caniuse.com/#search=hidden< /а>

var window = Browser.window;
if (window.requestAnimationFrame == null) window.setTimeout(animate, 1000.0 / 60.0);
else window.requestAnimationFrame(animate);

Я бы предложил использовать этот фрагмент. И используйте if (Browser.document.hidden) return в функции анимации

person Mark Knol    schedule 04.09.2017
comment
Спасибо за Объяснение :), старался как можно меньше менять из исходников, так как это не моя библиотека (это ха), поэтому старался максимально придерживаться исходного кода - person Rafael Kress; 04.09.2017
comment
Почему-то не могу отредактировать свой комментарий: условие проверяется каждый кадр/тик. если быть более точным: function animate(timestamp) { var window = Browser.window; if (requestAnimationFrame == null || || window.top != window.self) window.setTimeout(animate, 1000.0/60.0); иначе запросAnimationFrame(анимировать); ... } Это функция внутри библиотеки kha - person Rafael Kress; 04.09.2017
comment
Я протестировал это решение, но, к сожалению, оно не работает. Во-первых, кажется, что скрытый документ чем-то отличается от несфокусированного. Во-вторых, мне пришлось указать, что setTimeout вызывается, когда окно становится неактивным, даже если функция анимации уже находится в очереди requestAnimationFrame. - person Rafael Kress; 04.09.2017

Хорошо, я нашел решение. SystemImpl от kha запрашивает requestAnimationFrame и проверяет, является ли он нулевым для каждой временной метки.

var window: Dynamic = Browser.window;    
if (requestAnimationFrame == null) window.setTimeout(animate, 1000.0 / 60.0);
else requestAnimationFrame(animate);

Во время неактивной вкладки requestAnimationFrame не равен нулю, но не вызывает функцию анимации. Я добавил статическое логическое значение isFocused, которое изменяется каждый раз, когда браузер закрывает или открывает это окно.

Чтобы исправить это, я временно изменил этот небольшой фрагмент на:

var window = Browser.window;
window.onfocus = function(){isFocused = true;}
window.onblur = function()
{
    window.setTimeout(animate, 1000.0 / 60.0); 
    isFocused = false; 
}           
if (requestAnimationFrame == null || !isFocused) window.setTimeout(animate, 1000.0 / 60.0);
else requestAnimationFrame(animate);

Таким образом я проверяю, является ли текущее окно активным окном, и использую гораздо более плавный requestAnimationFrame, а если нет, то использую setTimeout. Методы обратного вызова устанавливают фокусное значение. Значение Blur Callback также гарантирует, что функция анимации всегда вызывается при размытии.

Я собираюсь представить это решение в ближайшие 1 или 2 недели, чтобы ограбить, может быть, он рассматривает реализацию

person Rafael Kress    schedule 01.09.2017