Skip to content

[Bug]: GDX renderer buffers all ZoneActivated events until it is enabled. #5502

@kwvanderlinde

Description

@kwvanderlinde

Describe the Bug

When loading new zones, a ZoneActivated event is emitted. The GdxRenderer handles this, but has to queue a task on the GDX loop. However, if LibGDX has never been activated, the loop does not run. Once LibGDX is activated, all the pending tasks execute, even if no longer valid (e.g., they apply to campaigns that have since been unloaded).

This mainly results in NPEs as the GDX renderer attempts to get the ZoneRenderer for maps that no longer exist.

To Reproduce

  1. Start a new campaign.
  2. Start another new campaign.
  3. Enable the LibGDX renderer.
  4. Notice the error in the logs.

Expected Behaviour

The GDX renderer should only handle events if it is active.

Screenshots

No response

MapTool Info

develop (45a4ddb)

Desktop

Linux Mint 22.1

Additional Context

Example stack trace:

java.lang.reflect.InvocationTargetException
	at java.desktop/java.awt.EventQueue.invokeAndWait(EventQueue.java:1371)
	at java.desktop/java.awt.EventQueue.invokeAndWait(EventQueue.java:1346)
	at java.desktop/javax.swing.SwingUtilities.invokeAndWait(SwingUtilities.java:1480)
	at com.jogamp.opengl.util.AWTAnimatorImpl.display(AWTAnimatorImpl.java:98)
	at com.jogamp.opengl.util.AnimatorBase.display(AnimatorBase.java:471)
	at com.jogamp.opengl.util.Animator$MainLoop.run(Animator.java:259)
	at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: com.jogamp.opengl.GLException: Caught NullPointerException: Cannot invoke "net.rptools.maptool.client.ui.zone.renderer.ZoneRenderer.getViewModel()" because the return value of "net.rptools.maptool.client.ui.zone.gdx.ZoneCache.getZoneRenderer()" is null on thread AWT-EventQueue-0
	at com.jogamp.opengl.GLException.newGLException(GLException.java:76)
	at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1327)
	at jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:1147)
	at com.jogamp.opengl.awt.GLJPanel$OffscreenBackend.doPaintComponent(GLJPanel.java:2127)
	at com.jogamp.opengl.awt.GLJPanel.paintComponent(GLJPanel.java:587)
	at java.desktop/javax.swing.JComponent.paint(JComponent.java:1128)
	at java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:961)
	at java.desktop/javax.swing.JComponent.paint(JComponent.java:1137)
	at java.desktop/javax.swing.JComponent.paintToOffscreen(JComponent.java:5318)
	at java.desktop/javax.swing.RepaintManager$PaintManager.paintDoubleBufferedImpl(RepaintManager.java:1656)
	at java.desktop/javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1631)
	at java.desktop/javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1569)
	at java.desktop/javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:262)
	at java.desktop/javax.swing.RepaintManager.paint(RepaintManager.java:1336)
	at java.desktop/javax.swing.JComponent._paintImmediately(JComponent.java:5266)
	at java.desktop/javax.swing.JComponent.paintImmediately(JComponent.java:5076)
	at java.desktop/javax.swing.RepaintManager$4.run(RepaintManager.java:878)
	at java.desktop/javax.swing.RepaintManager$4.run(RepaintManager.java:861)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
	at java.desktop/javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:861)
	at java.desktop/javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:834)
	at com.jogamp.opengl.util.AWTAnimatorImpl$1.run(AWTAnimatorImpl.java:170)
	at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:308)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
	at net.rptools.maptool.client.swing.MapToolEventQueue.dispatchEvent(MapToolEventQueue.java:63)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Caused by: java.lang.NullPointerException: Cannot invoke "net.rptools.maptool.client.ui.zone.renderer.ZoneRenderer.getViewModel()" because the return value of "net.rptools.maptool.client.ui.zone.gdx.ZoneCache.getZoneRenderer()" is null
	at net.rptools.maptool.client.ui.zone.gdx.GdxRenderer.lambda$onZoneActivated$0(GdxRenderer.java:2308)
	at com.badlogic.gdx.backends.jogamp.JoglApplicationBase.executeRunnables(JoglApplicationBase.java:183)
	at com.badlogic.gdx.backends.jogamp.JoglGraphicsBase.display(JoglGraphicsBase.java:178)
	at jogamp.opengl.GLDrawableHelper.displayImpl(GLDrawableHelper.java:692)
	at jogamp.opengl.GLDrawableHelper.display(GLDrawableHelper.java:674)
	at com.jogamp.opengl.awt.GLJPanel$Updater.display(GLJPanel.java:1478)
	at com.jogamp.opengl.awt.GLJPanel$9.run(GLJPanel.java:1553)
	at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1293)
	... 35 more

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions