-
Notifications
You must be signed in to change notification settings - Fork 265
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
Token class updates to accommodate new layout features #5104
base: develop
Are you sure you want to change the base?
Conversation
clean up some property names, e.g. isFlippedIso to flippedIso so that getter becomes isFlippedIso(). Unnecessary Token removed from property tokenOpacity. Now just opacity. Reordered to keep layout props together. Added new layout prop imageRotation Updated tokenLayoutProp macro functions
Yay, it runs, and I am reminded why methods should be properly named the first time. |
src/main/java/net/rptools/maptool/client/ui/token/dialog/edit/EditTokenDialog.java
Outdated
Show resolved
Hide resolved
src/main/java/net/rptools/maptool/client/ui/token/dialog/edit/TokenLayoutPanelHelper.java
Outdated
Show resolved
Hide resolved
src/main/java/net/rptools/maptool/client/ui/token/dialog/edit/TokenLayoutPanelHelper.java
Outdated
Show resolved
Hide resolved
…ented code. Commented code removed
Token drawing moved to TokenRenderer Facing-arrow painting moved to FacingArrowRenderer Some functionality moved to ImageUtils
Remove old layout panel
Icons embedded
import org.apache.logging.log4j.Logger; | ||
|
||
/* Utility class for useful mathematical methods */ | ||
public class MathUtil { |
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.
We can do without most of this class as the methods are either unused or can be simplified. I'll leave specific comments below.
private static final Logger log = LogManager.getLogger(MathUtil.class); | ||
|
||
/** | ||
* Faster version of absolute for integers |
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.
Any proof of this claim? Math.abs()
calls are always inlined with platform-specific instructions, so there's no branching concerns with it.
Anyways, this method isn't used and can be removed.
} | ||
|
||
/** | ||
* Faster version of absolute |
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 guarantee this is slower than Math.abs()
. Plus this method isn't used.
* @return the equivalent value of valueToMap in the target range | ||
* @param <T> | ||
*/ | ||
public static <T extends Number> T mapToRange( |
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 generics don't really gain us anything here since internally it has to check float
vs double
anyways. I.e., an overload would do just as well.
But it can also just be replaced with a purely double
version. The one caller that uses float
can cast the result.
((mapValue.doubleValue() - inMin.doubleValue()) | ||
* (outMax.doubleValue() - outMin.doubleValue()) | ||
/ (inMax.doubleValue() - inMin.doubleValue()) | ||
+ outMin.doubleValue()); |
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.
This kind of lerp implementation tends to be inaccurate when valueToMap == in_max
, due to floating point shenanigans. An alternative with accurate endpoints would be:
var t = (valueToMap - in_min) / (in_max - in_min);
result = (1 - t) * out_min + t * out_max;
* @param highBound | ||
* @return | ||
*/ | ||
public static int constrainInt(int value, int lowBound, int highBound) { |
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.
This method is the same as Math.clamp(long, int, int)
and can be removed in favour of that.
* @return | ||
* @param <T> | ||
*/ | ||
public static <T extends Number> T constrainNumber(T value, T lowBound, T highBound) { |
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.
This method is equivalent to Math.clamp(double, double, double)
and can be removed.
return d; | ||
} | ||
|
||
public static boolean isDouble(Object o) { |
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.
With the other proposed simplifications, isDouble()
, isFloat()
and isNumber()
are not needed.
* @return truncated double value | ||
*/ | ||
public static double doublePrecision(double value, int decimalPlaces) { | ||
double d = Double.parseDouble(String.format("%." + decimalPlaces + "f", value)); |
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.
This is fine for the UI usage, but outside of that will be a pretty slow implementation. Can use this instead:
double divisor = Math.pow(10, -decimalPlaces);
double d = divisor * Math.round(value / divisor);
|
||
private Integer visionOverlayColorValue; | ||
private transient Color visionOverlayColor; | ||
|
||
// Jamz: allow token alpha channel modification | ||
private @Nonnull Float tokenOpacity = 1.0f; | ||
private @Nonnull Float opacity = 1.0f; |
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.
Can't rename fields or token settings in existing campaigns will be lost (applies to opacity
, isFlippedX
, isFlippedY
, isFlippedIso
).
It's fine that the accessor methods or DTO fields are renamed, just the model fields need to remain the same.
Got partyway through reviewing. Will pick it up again later today. The feature is looking quite good. The new layout functionality feels very nice to use. |
String rotation = String.valueOf(token.getImageRotation()); | ||
String scaleX = String.valueOf(token.getScaleX()); | ||
String scaleY = String.valueOf(token.getScaleY()); | ||
String footprintScaleValue = |
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 should all be left as numeric values. Otherwise the JSON will contain a bunch of strings that will then require further parsing by the caller.
sb.append("scaleX=" + scaleX + delim); | ||
sb.append("scaleY=" + scaleY + delim); | ||
sb.append("footprintScale=" + footprintScaleValue); | ||
return sb.toString(); |
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.
Since you're using a StringBuilder
anyways, might as well avoid the (expensive) string concats and chain the appends. E.g.,
sb.append("scale=").append(scale).append(delim);
/* | ||
* setExtendedTokenLayoutProps(StrProp/JSON Object, token: currentToken(), mapName = current map) | ||
*/ | ||
if (functionName.equalsIgnoreCase("setExtendedTokenLayoutProps")) { |
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.
Anyway this could be folded into setTokenLayoutProps()
? The set of options parallels the output of getTokenLayoutProps()
and so would be easier for macro writers to discover.
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.
try { | ||
return ImageUtil.scaleBufferedImage(img, outputWidth, outputHeight); | ||
} catch (Exception e) { | ||
log.debug(e.getLocalizedMessage(), e); |
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.
Is there an actual error that we should be concerned about here? At a glance, I don't think the ResampleOp
will throw anything in our case.
If there is a worry, this should be a log.error()
, or at least a log.warn()
.
return ImageUtil.scaleBufferedImage( | ||
img, (int) Math.ceil(b.width * zoom), (int) Math.ceil(b.height * zoom)); | ||
} catch (Exception e) { | ||
log.debug(e.getLocalizedMessage(), e); |
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.
Same as above, either don't handle the error or make it log.error()
.
* @param token The token containing the flip-states | ||
* @return A modified image, or the original image if no processing performed. | ||
*/ | ||
public static BufferedImage flipTokenImage(BufferedImage image, Token token) { |
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.
This method isn't used.
return bytesToImage(dataStream.toByteArray(), image); | ||
} | ||
|
||
public static double getIsoFigureHeightOffset(Token token, Rectangle2D footprintBounds) { |
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.
getIsoFigureHeightOffset()
and getIsoFigureScaleFactor()
seem like they would be more natural in the Token
class as they don't really have to do with image manipulation even though they are fed into token image rendering.
resolves #5103
Progresses #5096
Progresses #3691
Includes most of #5097
Description of the Change
New property
New property macro functions
Refactoring
Possible Drawbacks
none
Documentation Notes
n/a
Release Notes
n/a
This change is