-
Notifications
You must be signed in to change notification settings - Fork 386
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add new resource attribute isDisplayFor #3015
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,13 @@ | ||
package games.strategy.engine.data; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public class Resource extends NamedAttachable { | ||
private static final long serialVersionUID = 7471431759007499935L; | ||
|
||
private List<PlayerID> players = new ArrayList<>(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this field can now be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point. Updated. |
||
|
||
/** | ||
* Creates new Resource. | ||
* | ||
|
@@ -12,6 +17,17 @@ public class Resource extends NamedAttachable { | |
* game data | ||
*/ | ||
public Resource(final String name, final GameData data) { | ||
this(name, data, new ArrayList<>()); | ||
} | ||
|
||
public Resource(final String name, final GameData data, final List<PlayerID> players) { | ||
super(name, data); | ||
this.players = players; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We probably should be making a defensive copy of the incoming list. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So I think most of the data objects make a copy if they have a getter to return a copy. I'll have to look to see what similar classes do when taking in a list. |
||
} | ||
|
||
public boolean isDisplayedFor(final PlayerID player) { | ||
// TODO: remove null check on incompatible release | ||
return players == null || players.contains(player); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,7 +12,6 @@ | |
import games.strategy.engine.data.PlayerID; | ||
import games.strategy.engine.data.Resource; | ||
import games.strategy.engine.data.events.GameDataChangeListener; | ||
import games.strategy.engine.stats.IStat; | ||
import games.strategy.triplea.Constants; | ||
|
||
/** | ||
|
@@ -22,7 +21,7 @@ public class ResourceBar extends AbstractStatPanel implements GameDataChangeList | |
private static final long serialVersionUID = -7713792841831042952L; | ||
|
||
private final UiContext uiContext; | ||
private final List<IStat> resources = new ArrayList<>(); | ||
private final List<ResourceStat> resourceStats = new ArrayList<>(); | ||
private final List<JLabel> labels = new ArrayList<>(); | ||
|
||
public ResourceBar(final GameData data, final UiContext uiContext) { | ||
|
@@ -51,7 +50,7 @@ private void setResources() { | |
if (resource.getName().equals(Constants.VPS)) { | ||
continue; | ||
} | ||
resources.add(new ResourceStat(resource)); | ||
resourceStats.add(new ResourceStat(resource)); | ||
final JLabel label = new JLabel(); | ||
label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 20)); | ||
labels.add(label); | ||
|
@@ -64,15 +63,18 @@ public void gameDataChanged(final Change change) { | |
try { | ||
final PlayerID player = gameData.getSequence().getStep().getPlayerId(); | ||
if (player != null) { | ||
for (int i = 0; i < resources.size(); i++) { | ||
final String quantity = resources.get(i).getFormatter().format(resources.get(i).getValue(player, gameData)); | ||
for (int i = 0; i < resourceStats.size(); i++) { | ||
final ResourceStat resourceStat = resourceStats.get(i); | ||
final Resource resource = resourceStat.resource; | ||
final JLabel label = labels.get(i); | ||
final String quantity = resourceStat.getFormatter().format(resourceStat.getValue(player, gameData)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You would think that this could be as simple as:
There is some extra complexity in this block. I recommend adding some commentary, or even better making it a bit more self documenting and extracting to well named helper methods. Ultimately I think some API updates are in order, but I could agree to that being saved for another day. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree it is a bit long but didn't want to update the API for IStat at this point. |
||
label.setVisible(resource.isDisplayedFor(player)); | ||
try { | ||
labels.get(i).setIcon(uiContext.getResourceImageFactory() | ||
.getIcon(gameData.getResourceList().getResource(resources.get(i).getName()), true)); | ||
labels.get(i).setText(quantity); | ||
labels.get(i).setToolTipText(resources.get(i).getName()); | ||
label.setIcon(uiContext.getResourceImageFactory().getIcon(resource, true)); | ||
label.setText(quantity); | ||
label.setToolTipText(resourceStat.getName()); | ||
} catch (final IllegalStateException e) { | ||
labels.get(i).setText(resources.get(i).getName() + " " + quantity); | ||
label.setText(resourceStat.getName() + " " + quantity); | ||
} | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: unnecessary
data
access here. This is only neededfinal List<PlayerID> players = data.getPlayerList().getPlayers();
if the boolean conditional is false.This block could be made a bit simpler. I see a problem that
players
is initialized before it is needed. Thinking about flow, we grab XMLisDisplayedData
, we grab players list from game data, then we checkisDisplayedData
and if none then we clear the player list we just grabbed : )So to be specific the two problems I see are:
players
variable is initialized before it is needed, outside of the scope of if blockplayers
variable is re-used for a second purpose (SRP violation). That would be fixed by removing theplayers.clear
calls and simply creating new lists as needed.Combining the above with some other suggestions I had along the way, this block can be simplified to at least the following:
Personally, I'd like to see it go a bit further even, that such logic is moved and fully contained to a new class (strategy pattern). In this way we could test the new logic much more readily, even if we can't yet test all of GameParser.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really think that is much harder to read and maintain than the original.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original, it's hard to tell where
final List<PlayerID> players = data.getPlayerList().getPlayers();
is used. In the updated version it's clear it's in the else block. Another iteration can probably go further and do it all as one block. Regardless, there is the concern that the original and updated are hard to maintain and lacking tests.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are still problems if you sue streaming notation or not:
That woudl fix SRP and make it a bit less direct. The single void call at the end I don't think is a good thing, it requires tracing the 'players' object through the above if/else/for block, it's not very direct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can see what you are getting at just isn't that easy to make it much simpler. I refactored it to instead not re-use players list across if conditions. I'd say its about the same in complexity/readability but it essentially comes down to if avoiding the re-use and clearing of players list is worth having an extra if and 3 calls instead of 1 to addResource. Its probably more explicit this way.