1414 */
1515package net .rptools .maptool .client .swing .walls ;
1616
17- import com .google .common .collect .ImmutableMap ;
18- import com .google .common .collect .Maps ;
1917import java .beans .PropertyChangeEvent ;
2018import java .beans .PropertyChangeListener ;
2119import java .util .EnumMap ;
20+ import java .util .Map ;
21+ import java .util .Objects ;
2222import javax .annotation .Nonnull ;
23+ import javax .annotation .Nullable ;
2324import javax .swing .JComboBox ;
25+ import net .rptools .lib .CollectionUtil ;
2426import net .rptools .maptool .model .topology .VisibilityType ;
2527import net .rptools .maptool .model .topology .Wall ;
2628
2729public class WallConfigurationController {
30+ /**
31+ * Like Wall.Data, but mutable, observable, and nullable (in case of multiple selected walls not
32+ * agreeing).
33+ */
34+ public static final class WallData {
35+
36+ private final @ Nullable Wall .Direction direction ;
37+ private final @ Nullable Wall .MovementDirectionModifier movementModifier ;
38+ // DO NOT MODIFY `modifiers`!
39+ private final EnumMap <VisibilityType , Wall .DirectionModifier > modifiers ;
40+
41+ public WallData (
42+ @ Nullable Wall .Direction direction ,
43+ @ Nullable Wall .MovementDirectionModifier movementModifier ,
44+ Map <VisibilityType , Wall .DirectionModifier > modifiers ) {
45+ this .direction = direction ;
46+ this .movementModifier = movementModifier ;
47+ this .modifiers = new EnumMap <>(VisibilityType .class );
48+ this .modifiers .putAll (modifiers );
49+ }
50+
51+ public WallData (WallData other ) {
52+ this (other .direction , other .movementModifier , other .modifiers );
53+ }
54+
55+ public WallData (Wall .Data data ) {
56+ this (
57+ data .direction (),
58+ data .movementModifier (),
59+ CollectionUtil .newFilledEnumMap (VisibilityType .class , data ::directionModifier ));
60+ }
61+
62+ @ Override
63+ public boolean equals (Object obj ) {
64+ if (!(obj instanceof WallData other )) {
65+ return false ;
66+ }
67+
68+ return this .direction == other .direction
69+ && this .movementModifier == other .movementModifier
70+ && this .modifiers .equals (other .modifiers );
71+ }
72+
73+ public @ Nullable Wall .Direction direction () {
74+ return direction ;
75+ }
76+
77+ public WallData withDirection (@ Nullable Wall .Direction direction ) {
78+ return new WallData (direction , this .movementModifier , this .modifiers );
79+ }
80+
81+ public @ Nullable Wall .MovementDirectionModifier movementModifier () {
82+ return movementModifier ;
83+ }
84+
85+ public WallData withMovementModifier (
86+ @ Nullable Wall .MovementDirectionModifier movementModifier ) {
87+ return new WallData (this .direction , movementModifier , this .modifiers );
88+ }
89+
90+ public @ Nullable Wall .DirectionModifier directionModifier (VisibilityType visibilityType ) {
91+ return this .modifiers .get (visibilityType );
92+ }
93+
94+ public WallData withDirectionModifier (
95+ VisibilityType visibilityType , @ Nullable Wall .DirectionModifier modifier ) {
96+ var newModifiers = new EnumMap <>(this .modifiers );
97+ if (modifier == null ) {
98+ newModifiers .remove (visibilityType );
99+ } else {
100+ newModifiers .put (visibilityType , modifier );
101+ }
102+ return new WallData (this .direction , this .movementModifier , newModifiers );
103+ }
104+
105+ public Wall .Data toWallData () {
106+ return toWallData (new Wall .Data ());
107+ }
108+
109+ public Wall .Data toWallData (Wall .Data original ) {
110+ return new Wall .Data (
111+ Objects .requireNonNullElse (direction , original .direction ()),
112+ Objects .requireNonNullElse (movementModifier , original .movementModifier ()),
113+ CollectionUtil .newFilledEnumMap (
114+ VisibilityType .class ,
115+ type ->
116+ Objects .requireNonNullElseGet (
117+ modifiers .get (type ), () -> original .directionModifier (type ))));
118+ }
119+ }
120+
28121 private final WallConfigurationView view ;
29122 private final PropertyChangeListener changeListener ;
30- private @ Nonnull Wall . Data wallData = new Wall .Data ();
123+ private @ Nonnull WallData wallData = new WallData ( new Wall .Data () );
31124
32125 public WallConfigurationController (PropertyChangeListener changeListener ) {
33126 this .view = new WallConfigurationView ();
@@ -38,7 +131,7 @@ public WallConfigurationController(PropertyChangeListener changeListener) {
38131 e -> {
39132 var newDirection = directionSelect .getItemAt (directionSelect .getSelectedIndex ());
40133 if (newDirection != null ) {
41- updateWall (newDirection , wallData .movementModifier (), wallData . modifiers ( ));
134+ updateWall (wallData .withDirection ( newDirection ));
42135 }
43136 });
44137
@@ -48,7 +141,7 @@ public WallConfigurationController(PropertyChangeListener changeListener) {
48141 var modifier =
49142 movementModifierSelect .getItemAt (movementModifierSelect .getSelectedIndex ());
50143 if (modifier != null ) {
51- updateWall (wallData .direction (), modifier , wallData . modifiers ( ));
144+ updateWall (wallData .withMovementModifier ( modifier ));
52145 }
53146 });
54147
@@ -58,34 +151,19 @@ public WallConfigurationController(PropertyChangeListener changeListener) {
58151 e -> {
59152 var modifier = input .getItemAt (input .getSelectedIndex ());
60153 if (modifier != null ) {
61- var newModifiers =
62- new EnumMap <VisibilityType , Wall .DirectionModifier >(VisibilityType .class );
63- newModifiers .putAll (wallData .modifiers ());
64- newModifiers .put (visibilityType , modifier );
65-
66- updateWall (
67- wallData .direction (),
68- wallData .movementModifier (),
69- Maps .immutableEnumMap (newModifiers ));
154+ updateWall (wallData .withDirectionModifier (visibilityType , modifier ));
70155 }
71156 });
72157 }
73158 }
74159
75- private void updateWall (
76- Wall .Direction direction ,
77- Wall .MovementDirectionModifier movementModifier ,
78- ImmutableMap <VisibilityType , Wall .DirectionModifier > modifiers ) {
79- var newWallData = new Wall .Data (direction , movementModifier , modifiers );
80-
81- if (wallData .equals (newWallData )) {
82- return ;
160+ private void updateWall (WallData newWallData ) {
161+ if (!wallData .equals (newWallData )) {
162+ var oldWallData = wallData ;
163+ wallData = newWallData ;
164+ changeListener .propertyChange (
165+ new PropertyChangeEvent (this , "wallData" , oldWallData , wallData ));
83166 }
84-
85- var oldWallData = wallData ;
86- wallData = newWallData ;
87-
88- changeListener .propertyChange (new PropertyChangeEvent (this , "wallData" , oldWallData , wallData ));
89167 }
90168
91169 public WallConfigurationView getView () {
@@ -101,7 +179,11 @@ private JComboBox<Wall.DirectionModifier> getModifierInput(VisibilityType visibi
101179 }
102180
103181 public void bind (@ Nonnull Wall .Data model ) {
104- this .wallData = model ;
182+ bind (new WallData (model ));
183+ }
184+
185+ public void bind (@ Nonnull WallData model ) {
186+ this .wallData = new WallData (model );
105187
106188 this .view .getDirectionSelect ().setSelectedItem (this .wallData .direction ());
107189 this .view .getMovementModifier ().setSelectedItem (this .wallData .movementModifier ());
@@ -111,7 +193,7 @@ public void bind(@Nonnull Wall.Data model) {
111193 }
112194 }
113195
114- public @ Nonnull Wall . Data getModel () {
115- return wallData ;
196+ public @ Nonnull WallData getModel () {
197+ return new WallData ( wallData ) ;
116198 }
117199}
0 commit comments