vjurenka / BWMirror

BWMirror API source files
Other
54 stars 13 forks source link

Unit hashCode #30

Open Miglecz opened 7 years ago

Miglecz commented 7 years ago

onUnitCreate(Unit unit) unit different object than querying self.getUnits() in onFrame() method what is not a problem, but putting them in the same collection/map is wrong due to the fact that Unit class equals and hashcode methods are not implemented. I suggest implementing them by comparing unit ids! Please also check all other classes (Player also) and implement these methods, as this is a Java lib. Thanks in advance!

Ravaelles commented 7 years ago

I agree. Lack of compareTo, hashCode and equals methods is definitely THE WORST THING ABOUT BWMIRROR. In my project https://github.com/Ravaelles/Atlantis I've suffered greatly to override this functionality, but in my opinion it would be enormously helpful for newcomers if BwMirror had this functionality for its classes by default. What's worst, some constructors are private and that makes it impossible to use many objects in HashMaps!

dgant commented 7 years ago

@Ravaelles @Miglecz Here's a (yes, gnarly) solution for equals. The trick is that although BWMirror gives you distinct, uncomparable Java proxies to the same object, those objects both hold the same pointer field. The catch is that the pointer field is private. But the (aforementionedly gnarly) workaround is to bypass the privacy of the field to get at the sweet, juicy pointer contained within.

This technique is taken from https://stackoverflow.com/questions/1196192/how-do-i-read-a-private-field-in-java

boolean areTheseTilesInTheSameBWTARegion(TilePosition myTilePosition1, TilePosition myTilePosition2) {
Region region1 = BWTA.getRegion(myTilePosition1);
Region region2 = BWTA.getRegion(myTilePosition2);
if (region1 == null) { return region2 == null; }
if (region2 == null) { return false; }
Field pointerField = region1.getClass().getDeclaredField("pointer");
pointerField.setAccessible(true); // Pretty please? With a cherry on top?
return pointerField.get(region1) == pointerField.get(region2);
}
dgant commented 7 years ago

As a follow-up: It turns out that even this method isn't reliable, because in at least some cases the underlying pointer is different.