Closed andrebrait closed 6 years ago
Legal, @andrebrait. Após a correção, você chegou a fazer testes extensivamente e não viu o bug ser reproduzido?
Testei extensivamente, e até vi ser reproduzido, mas com menos frequência. Estou analisando melhor ainda.
Reverti. Acabou que eu estava fazendo merda aqui e não vi.
Parece que se trata de um bug relacionado a uma condição de corrida com o objeto da classe AssetManager que usamos nos jogos.
Parece que havia uma condição de corrida entre as Threads "AsynchExecutor-Thread" e "LWJGL Application"
Criei um Proxy para AssetManager e substituí ele em BaseScreen. O Proxy redireciona todas as chamadas de métodos públicos para o AssetManager. Assim consegui ver quando threads acessavam o objeto.
Não entendi exatamente qual o biziu, mas acredito que colocando uma trava sobre o objeto no render resolveu o bug. Estou tentando reproduzir há um bom tempo sem sucesso com a trava.
EDIT: Aconteceu de novo. Vou ver o que consigo achar
Objeto acessado na Thread AsynchExecutor-Thread
Objeto acessado na Thread AsynchExecutor-Thread
Objeto acessado na Thread LWJGL Application
Objeto acessado na Thread LWJGL Application
Objeto acessado na Thread LWJGL Application
Objeto acessado na Thread LWJGL Application
Objeto acessado na Thread LWJGL Application
Objeto acessado na Thread LWJGL Application
Objeto acessado na Thread LWJGL Application
Objeto acessado na Thread LWJGL Application
Exception in thread "LWJGL Application" com.badlogic.gdx.utils.GdxRuntimeException: Asset not loaded: menu/menu-background.png
at com.badlogic.gdx.assets.AssetManager.get(AssetManager.java:148)
at br.cefetmg.games.screens.BaseScreen$AssetManagerProxy.get(BaseScreen.java:76)
at br.cefetmg.games.screens.MenuScreen.assetsLoaded(MenuScreen.java:107)
at br.cefetmg.games.screens.BaseScreen.render(BaseScreen.java:373)
at br.cefetmg.games.transition.FadeTransitionEffect.render(FadeTransitionEffect.java:36)
at br.cefetmg.games.transition.TransitionScreen.render(TransitionScreen.java:71)
at com.badlogic.gdx.Game.render(Game.java:46)
at br.cefetmg.games.MeowAuGame.render(MeowAuGame.java:36)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:225)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:126)
Acredito ter desvendado a treta agora!
Encontrei um "guru" de LibGDX comentando sobre esse problema
If you set a screen as the current screen before your assets are loaded, then it's normal. either you load the assets in the Render event of your screen, or you load your assets in the main Render event and, only once finished, you display your screen
Daí tentei descobrir e... eureka!!
Isto ocorre com MenuScreen
, RankingScreen
e PlayingGameScreen
porque elas têm o load em seu método show()
, ou seja, elas implementam diretamente o método appear()
, enquanto a PlayingGameScreen
utiliza um dos GameSequencer
para gerenciar que jogo irá carregar, já carregando todos os assets previamente (os jogos apenas recebem o BaseScreen criado). Assim, na PlayingGameScreen
(na hora de jogar) este erro nunca ocorre, enquanto que nela em outras situações e nestas outras telas ocorre este problema.
Como o método show()
é chamado assim que a tela é colocada como a principal no método setScreen
da classe Game
, este erro ocorre de forma intermitente!
Testei passar o método appear()
ao fim do construtor do BaseScreen
e... sucesso! Ele não deve ser chamado dentro do show()
, mas antes. Mas esse ( o construtor) não é um lugar muito feliz para um carinha desses estar. Assim, segui o conselho do camarada ali e incluí um passo no render()
do BaseScreen
(com um boolean para controlar a entrada nessa seção) para tentar carregar os assets, ou seja, chamar o appear()
.
Já estou há 30 minutos startando a aplicação e alternando entre as telas de Ranking e o Menu (que eram as mais afetadas) e não consegui mais reproduzir o Heisenbug.
Ufa! Melhor integrar essa mudança no seu projeto base no futuro.
Corrigido no #117
Estive enfrentando um bug intermitente aqui quando inicio a aplicação. Ocorre em +- metade das execuções.
A exceção a seguir é lançada:
Consegui arrumá-lo e estou testando a solução. Reportando aqui para constar.