Skip to content

Conversation

@kwvanderlinde
Copy link
Collaborator

@kwvanderlinde kwvanderlinde commented Nov 8, 2025

Identify the Bug or Feature request

Resolves #5849

Description of the Change

Changes the interface of Scale so its properties can no longer be modified. The fields are not final so that serialization continues to work, but they are effectively immutable. As a proper value type, Scale now has #equals(Object) and #hashCode() methods. This also means Scale is no longer reponsible for pumping events when modified, so the PropertyChangeSupport has been removed.

Scale is now the only place that defines transformations between world and screen space. It provides general AffineTransforms in both directions via #toWorldTransform() and #toScreenTransform(). Also, most conversion methods on ScreenPoint have been removed in favour of using the Scale for conversions. Those conversion methods that remain in ScreenPoint are wrappers around the ones in Scale for specific circumstances, and they all accept a simple Scale rather than an entire ZoneRenderer.

The ZoneViewModel now manages the Scale for a Zone (used to be in ZoneRenderer). This is just one more step along the road of removing dependencies on ZoneRenderer, though for now most components still look up the view model from the renderer. ZoneRenderer now longer offers methods to directly change the current Scale, though it does offer a few convenience methods that may do so among other things.

A few Scale-related improvements as well:

  • The new RepaintZoneRequested event gives a way for any component to trigger a repaint via the event bus. For now only ZoneViewModel uses it when the Scale is changed, but there are plenty of other places that will benefit from this as well.
  • HexGrid#getOffV(ZoneRenderer) and HexGrid#getOffU(ZoneRenderer) now accept a Scale instead of a ZoneRenderer. Similarly, HexGrid#getRendererSizeV(ZoneRenderer) and HexGrid#getRendererSizeU(ZoneRenderer) are now HexGrid#getSizeV(Dimension2D) and HexGrid#getSizeU(Dimension2D).
  • DrawablePaint and DrawableNoise now accept a full Scale when getting the AWT paint. This isn't used much now, but will be more common with some upcoming rendering changes.

Possible Drawbacks

Some scaling operations are more verbose to write now, though that will improve as ZoneRenderer is pushed out of the limelight.

Documentation Notes

N/A

Release Notes

  • Refactored zone scale

This change is Reviewable

@kwvanderlinde kwvanderlinde self-assigned this Nov 8, 2025
@github-actions github-actions bot added the code-maintenance Adding/editing javadocs, unit tests, formatting. label Nov 8, 2025
@kwvanderlinde kwvanderlinde moved this from Todo to Awaiting-Review in MapTool 1.19 Nov 8, 2025
Add `Scale#toWorldTransform()` and `Scale#toScreenTransform()` to build `AffineTransform` for either direction.

Remove most conversion methods from `ScreenPoint`. The only ones left are conveniences for rounded conversions. These
remaining methods also accept a `Scale` rather than requiring a full `ZoneRenderer`.
The fields are still mutable for the sake of serialization. But there is no longer any way to modify a `Scale` by normal
means. Instead, new methods allow creating new `Scale` objects with altered properties.

This will allow better sharing of `Scale` between components and threads.
- `#getOffV(ZoneRenderer)` => `#getOffV(Scale)`
- `#getOffU(ZoneRenderer)` => `#getOffV(Scale)`
- `#getRendererSizeU(ZoneRenderer)` => `#getSizeU(Dimension2D)`
- `#getRendererSizeV(ZoneRenderer)` => `#getSizeV(Dimension2D)`
Rather than having to pass the x/y offsets and scale separate, we can now pass a full `Scale` to resolve
corresponding AWT paint.
All direct `Scale` mutators in `ZoneRenderer` have been removed, requiring callers to update the `ZoneViewModel`
directly via `#getZoneScale()` and `#setZoneScale(Scale)`. A few indirect mutators remain in `ZoneRenderer` in the form
of convenience methods that do other work in addition to modify the zone scale.
@kwvanderlinde kwvanderlinde force-pushed the maintenance/5849-read-only-scale branch from 969ab06 to 5bdfab5 Compare November 8, 2025 03:53
@github-project-automation github-project-automation bot moved this from Awaiting-Review to To-Be-Merged in MapTool 1.19 Nov 9, 2025
@cwisniew cwisniew added this pull request to the merge queue Nov 9, 2025
Merged via the queue into RPTools:develop with commit 1f3514f Nov 9, 2025
4 checks passed
@github-project-automation github-project-automation bot moved this from To-Be-Merged to Merged in MapTool 1.19 Nov 9, 2025
@sentry
Copy link

sentry bot commented Nov 9, 2025

Issues attributed to commits in this pull request

This pull request was merged and Sentry observed the following issues:

@Baaaaaz
Copy link
Contributor

Baaaaaz commented Nov 9, 2025

Was just going to raise a bug ticket to say that MapTool-nightly-20251109 is broken, as when trying to run the win exe I get the following error:

java.lang.NullPointerException: Cannot invoke "net.rptools.maptool.client.ui.Scale.equals(Object)" because "this.lastZoneScale" is null
	at net.rptools.maptool.client.ui.zone.renderer.ZoneRenderer.renderBoard(ZoneRenderer.java:1057)
	at net.rptools.maptool.client.ui.zone.renderer.ZoneRenderer.renderZone(ZoneRenderer.java:829)
	at net.rptools.maptool.client.ui.zone.renderer.ZoneRenderer.lambda$paintComponent$2(ZoneRenderer.java:679)
	at net.rptools.lib.CodeTimer.using(CodeTimer.java:50)
	at net.rptools.maptool.client.ui.zone.renderer.ZoneRenderer.paintComponent(ZoneRenderer.java:656)
	at java.desktop/javax.swing.JComponent.paint(Unknown Source)
	at java.desktop/javax.swing.JComponent.paintChildren(Unknown Source)
	at java.desktop/javax.swing.JComponent.paint(Unknown Source)
	...

@kwvanderlinde
Copy link
Collaborator Author

Whoops, I'll get this fixed up ASAP.

@kwvanderlinde kwvanderlinde deleted the maintenance/5849-read-only-scale branch November 9, 2025 08:59
@kwvanderlinde
Copy link
Collaborator Author

On the plus side, I think this is the first time sentry has correctly identified the source of a problem 😅

@cwisniew
Copy link
Member

cwisniew commented Nov 9, 2025

On the plus side, I think this is the first time sentry has correctly identified the source of a problem 😅

You know what they say about broken clocks :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

code-maintenance Adding/editing javadocs, unit tests, formatting.

Projects

Status: Merged

Development

Successfully merging this pull request may close these issues.

[Maintenance]: Read-only Scale

3 participants