-
Notifications
You must be signed in to change notification settings - Fork 399
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
Issues 12447 (Standardized Sorting of UnitCategory) #12722
Conversation
AbstractUndoableMovesPanel.java -unitCategory sorting with gameData AvatarPanelFactory.java -passing territory -replace sorting by unitRenderingOrder with new generic sorting with territory and player BattleCalculatorPanel.java -rename method to getUnitCategories BattleDisplay.java (2x) BattleModel.java MapPanel.java OrderOfLossesInputPanel.java PlayerUnitsPanel.java SimpleUnitPanel.java UnitChooser.java -unitCategory sorting with gameData UnitScroller.java -passing territory UnitSeparator.java -core Comparator for sorting by UnitCategory: getComparatorUnitCategories -several overloaded methods getComparatorUnitCategories
AvatarPanelFactory.java -remove now unused method unitRenderingOrder
AbstractUndoableMovesPanel.java -Insert <> for ArrayList instantiation -fix format violations with game-app:game-headed:spotlessApply
AbstractUndoableMovesPanel.java -fix format violations with game-app:game-headed:spotlessApply
@@ -1,5 +1,7 @@ | |||
package games.strategy.triplea.odds.calculator; | |||
|
|||
import static games.strategy.triplea.util.UnitSeparator.getComparatorUnitCategories; |
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.
style nitpick, avoid static method imports unless in test code and importing things like assertions. The reasoning is that when inspecting the code, the method call looks like a call to a local method or to a super class.
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.
It might be even cleaner to have a static method in UnitSeparato
to do the sorting, rather than returning the comparator to then let the client code to the sorting. EG: UnitSeparator.sort( <unit-type-list> )
@@ -122,7 +124,8 @@ public void init(final GamePlayer gamePlayer, final List<Unit> units, final bool | |||
|
|||
GamePlayer previousPlayer = null; | |||
JPanel panel = null; | |||
for (final UnitCategory category : categories) { | |||
unitCategories.sort(getComparatorUnitCategories(data)); |
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.
There is a sort of unitCategories
higher up on line 69. Does this new sort call here, on line 127, overwrite the results of that previous sort?
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.
Good point. Another place where we can remove a "special" sorting with our generic one. Fix will be provided in commit #6.
if (unitCategories.isEmpty()) { | ||
return; | ||
} | ||
final GameData gameData = unitCategories.get(0).getUnitAttachment().getData(); |
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.
BattleDisplay:L95
has a reference to GameData
- can that be used?
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.
It cannot as the changed code is in private static class CasualtyNotificationPanel
for which I could not find GameData
.
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.
NP - please double check the nullability of unitAttachment#data
. I think grabbing gameData like this should be 'safe', but let's be sure.
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.
What should happen if unitAttachment = null
? For the sorting a different gameData source would be needed, e.g. from unitAttachment#unitType
? If all potential sources could be null, we cannot escape this what-if-question.
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 looked into this a bit further. You're good here W.R.T gameData
. I'll post some more followup in a bit. We can assume that gameData
will be non-null. I presume it is already guaranteed for unitAttachment
to be non-null as well.
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.
Correction.. tracing this down... Neutral units in 2.5 have null gameData
If you save a game that has neutral players with 2.5, then load that up with 2.6, then find a territory with only neutral units - in that case gameData
would seemingly be null.
Happily that nullity concern will go away kinda soon as how the neutral player is saved to disk was changed. Once we no longer need to load saves from 2.5, that gameData
would never be null.
@@ -120,7 +125,13 @@ public void setUnitsFromRepairRuleMap( | |||
*/ | |||
public void setUnitsFromCategories(final Collection<UnitCategory> categories) { | |||
removeAll(); | |||
for (final UnitCategory category : categories) { | |||
List<UnitCategory> unitCategories = new ArrayList(categories); | |||
if (unitCategories.isEmpty()) { |
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.
minor, seems like we can check if categories
is empty first & return sooner (ie: this line can be moved up by one, and check categories
instead of unitCategories
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.
Agree, I create a fix.
List<UnitCategory> unitCategories = new ArrayList(UnitSeparator.categorize(value)); | ||
unitCategories.sort(getComparatorUnitCategories(gameData)); |
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.
There is a little bit of a pattern here. Perhaps this can be cleaned up to be something like:
List<unitCategory> unitCategories = UnitSeparator.sortByUnitType(value)
Which in turn would do the list copy, categorize, and sorting.
FWIW, there is a bit of a feature envy code smell here where UnitSeparator is used to generate a return value, more data is obtained from UnitSeparator to then operate on that same data again. Resolving 'feature envy code smell' is usually done by moving the functionality entirely into UnitSeparator
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.
Agree, I create a fix to introduce another method UnitSeparator.getSortedUnitCategories
.
...-app/game-core/src/main/java/games/strategy/triplea/ui/unit/scroller/AvatarPanelFactory.java
Show resolved
Hide resolved
|
||
/** Returns <code>Comparator</code> for unit categories of a <code>Territory</code> */ | ||
private static Comparator<UnitCategory> getComparatorUnitCategories( | ||
final Territory t, final GameData gameData, final GamePlayer currentPlayer) { |
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 notice methods calling this one get GameData
from Territory
, any reason to not do that here and remove the GameData
parameter?
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 am going to create a fix to change Territory
to Optional<Territory>
.
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.
Cool, though - at a style level consider having multiple method signatures instead. Optional
is a "bad" type for a method parameter.
Though, maybe we can avoid the dependency on territory? Is the ordering change potentially that significant considering territory? Is that important? Second, it's an interesting question if it's more valuable to have a fully consistent ordering regardless of even territory. Thus, perhaps it's worthwhile to see if we can simplify the comparator to not depend on territory (while at it, maybe player too)
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 think we should enable the sorting to allow for some criteria to be optional that should still be considered and territory properties like owner or isWater seem plausble criteria as well as gamePlayer with whether its the same as the unit owner.
For me this comes as a cost of having a general sorting logic that it should incorporate several situations where some criteria might not be present.
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.
properties like owner or isWater seem plausble criteria as well as gamePlayer with whether its the same as the unit owner.
Are these plausible criteria or required? For either case, if you would, can you walk me through some scenarios you considering where player or territory would change the Unit-Category ordering?
Also to consider, we can have a method give a generic ordering of unit category, and then the places that do care about player or territory, they can do their one-off logic locally. That is to say, there is flexibility; just because the top-most level method is not super-flexible, doesn't mean we can't work that flexibility in where needed.
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.
Second thought: just please be sure to remove any method signatures that are not used if any.
Minimizing inputs is a way to have a more consistent sort ordering. We probably don't need to draw out the convo any further than there.
game-app/game-core/src/main/java/games/strategy/triplea/util/UnitSeparator.java
Outdated
Show resolved
Hide resolved
MapPanel.java - use new method UnitSeparator.getSortedUnitCategories SimpleUnitPanel.java - move isEmpty check upward UnitSeparator.java - introduce Optional<Territory> for getComparatorUnitCategories - new method etSortedUnitCategories(Collection<Unit>, GameData, MapData)
AbstractUndoableMovesPanel.java - use UnitSeparator.getSortedUnitCategories AvatarPanelFactory.java - use new method UnitSeparator.getSortedUnitCategories(units,territory,player) BattleCalculatorPanel.java - rename isLand to isLandBattle - pass parameter Territory location to PlayerUnitsPanel.init BattleDisplay.java - use getSortedUnitCategories instead of getComparatorUnitCategories - use new method UnitSeparator.sortUnitCategories BattleModel.java - use UnitSeparator.getSortedUnitCategories MapPanel.java - use UnitSeparator.getSortedUnitCategories OrderOfLossesInputPanel.java - use new method UnitSeparator.sortUnitCategories PlayerUnitsPanel.java - removed duplicated unitCategories.sort - introduce territory parameter to method init - rename isLand to isLandBattle SimpleUnitPanel.java - - use new method UnitSeparator.sortUnitCategories (later rework needed to replace setUnitsFromCategories(Collection<UnitCategory>)) with setUnitsFromCategories(Collection<Unit>)) - use UnitSeparator.getSortedUnitCategories UnitChooser.java - use UnitSeparator.getComparatorUnitCategories instead of import static method UnitSeparator.java - introduce getSortedUnitCategories for units and territory - introduce sortUnitCategories for a list of unit categories and gameData
PlayerUnitsPanel.java - reintroduce usage of getUnitTypes - introduce panel != null check in loop UnitSeparator.java - introduce methode ortUnitCategories(unitCategories, territory, currentPlayer) - comment fix for Javadoc parse error
This reverts commit ab48e6b.
…-game#12722)" (triplea-game#12762) This reverts commit e73fdec.
* Reapply "Issues 12447 (Standardized Sorting of UnitCategory) (#12722)" (#12762) This reverts commit e73fdec. * Issue_12447_Part2 #1 PlayerUnitsPanel.java - ensure uniqueness in returned list in method getAllUnitCategories - reduce complexity by use of new method getProducibleUnitTypes ProductionFrontier.java - new method getProducibleUnitTypes
Issue 12447 was mentioning the sorting of units being different in different UI areas.
This PR tries to unify the sorting (based on UnitCategory) used before adding UI components to ensure a standardized sorting.
Test was done with UnitChooser, TerritoryPanel, Battle Calculator and the UnitScoller for map 1941 Global Command Decision:
One thing I was not so sure about is the way gameData is selected in
UnitChooser.java
by picking the first entry of a list.Maybe there is a better way to do that which can be suggested by the reviewer.
The commit comment describes the changes:
PS: I will try next time to chop it into smaller pieces. It just grew somehow.