From 76dd7b263c8598b8cff3480e3e2d4801afb32af0 Mon Sep 17 00:00:00 2001 From: Matthias Wilke Date: Sun, 8 Dec 2024 17:55:27 +0100 Subject: [PATCH] Document attribute modifier listeners and events --- .../litiengine/attributes/Attribute.java | 13 +- .../attributes/AttributeModifier.java | 36 ++++-- .../attributes/AttributeModifierListener.java | 7 ++ .../attributes/AttributeValueListener.java | 11 ++ .../litiengine/attributes/RangeAttribute.java | 113 +++++++++++++++++- .../de/gurkenlabs/litiengine/input/Mouse.java | 85 ++++++------- 6 files changed, 210 insertions(+), 55 deletions(-) diff --git a/litiengine/src/main/java/de/gurkenlabs/litiengine/attributes/Attribute.java b/litiengine/src/main/java/de/gurkenlabs/litiengine/attributes/Attribute.java index 77c0bdc1c..5ebd3c4c4 100644 --- a/litiengine/src/main/java/de/gurkenlabs/litiengine/attributes/Attribute.java +++ b/litiengine/src/main/java/de/gurkenlabs/litiengine/attributes/Attribute.java @@ -145,6 +145,10 @@ public void setBaseValue(final T baseValue) { this.evaluateValue(); } + /** + * Evaluates the current value of the attribute by applying all registered modifiers to the base value. + * If the new value differs from the previous value, it triggers the value changed event. + */ protected void evaluateValue() { final T previousValue = this.value; this.value = this.applyModifiers(this.getBase()); @@ -155,10 +159,10 @@ protected void evaluateValue() { } /** - * Apply modifiers. + * Applies all registered modifiers to the given base value. * - * @param baseValue the base value - * @return the t + * @param baseValue The base value to which the modifiers will be applied. + * @return The modified value after applying all modifiers. */ protected T applyModifiers(final T baseValue) { T currentValue = baseValue; @@ -169,6 +173,9 @@ protected T applyModifiers(final T baseValue) { return currentValue; } + /** + * Fires the value changed event to all registered listeners. + */ private void fireValueChangedEvent() { for (var listener : this.listeners) { listener.valueChanged(); diff --git a/litiengine/src/main/java/de/gurkenlabs/litiengine/attributes/AttributeModifier.java b/litiengine/src/main/java/de/gurkenlabs/litiengine/attributes/AttributeModifier.java index 3f09c5127..33afda7b7 100644 --- a/litiengine/src/main/java/de/gurkenlabs/litiengine/attributes/AttributeModifier.java +++ b/litiengine/src/main/java/de/gurkenlabs/litiengine/attributes/AttributeModifier.java @@ -7,7 +7,8 @@ /** * An attribute modifier allows to modify attributes by the specified Modification and modify value. * - * @param the generic type + * @param + * the generic type * @see Attribute#addModifier(AttributeModifier) * @see Attribute#modifyBaseValue(AttributeModifier) */ @@ -20,8 +21,10 @@ public class AttributeModifier implements Comparable otherModifier) { /** * Checks if this attribute modifier is equal to another object. * - * @param obj The object to compare with. + * @param obj + * The object to compare with. * @return True if the objects are equal, false otherwise. */ @Override @@ -55,10 +60,22 @@ public boolean equals(Object obj) { return super.equals(obj); } + /** + * Adds a listener that will be notified when the attribute modifier changes. + * + * @param listener + * The listener to be added. + */ public void onChanged(AttributeModifierListener listener) { this.listeners.add(listener); } + /** + * Removes a listener so that it will no longer be notified when the attribute modifier changes. + * + * @param listener + * The listener to be removed. + */ public void removeListener(AttributeModifierListener listener) { this.listeners.add(listener); } @@ -93,7 +110,8 @@ public boolean isActive() { /** * Modifies the provided value based on the modification type and modify value of this attribute modifier. * - * @param modvalue The original value to be modified. + * @param modvalue + * The original value to be modified. * @return The modified value. */ public T modify(final T modvalue) { @@ -114,7 +132,8 @@ public T modify(final T modvalue) { /** * Sets the modify value for this attribute modifier. * - * @param value The new modify value. + * @param value + * The new modify value. */ public void setModifyValue(double value) { var previous = this.modifyValue; @@ -128,7 +147,8 @@ public void setModifyValue(double value) { /** * Sets the active status of this attribute modifier. * - * @param active True to activate, false to deactivate. + * @param active + * True to activate, false to deactivate. */ public void setActive(boolean active) { var previous = this.active; diff --git a/litiengine/src/main/java/de/gurkenlabs/litiengine/attributes/AttributeModifierListener.java b/litiengine/src/main/java/de/gurkenlabs/litiengine/attributes/AttributeModifierListener.java index aa6793b98..9750fad17 100644 --- a/litiengine/src/main/java/de/gurkenlabs/litiengine/attributes/AttributeModifierListener.java +++ b/litiengine/src/main/java/de/gurkenlabs/litiengine/attributes/AttributeModifierListener.java @@ -2,7 +2,14 @@ import java.util.EventListener; +/** + * An interface for listening to changes in attribute modifiers. Classes that implement this interface can be used to handle events when an attribute + * modifier changes. + */ @FunctionalInterface public interface AttributeModifierListener extends EventListener { + /** + * This method is called when an attribute modifier changes. + */ void modifierChanged(); } diff --git a/litiengine/src/main/java/de/gurkenlabs/litiengine/attributes/AttributeValueListener.java b/litiengine/src/main/java/de/gurkenlabs/litiengine/attributes/AttributeValueListener.java index a120d561e..e5e1e219e 100644 --- a/litiengine/src/main/java/de/gurkenlabs/litiengine/attributes/AttributeValueListener.java +++ b/litiengine/src/main/java/de/gurkenlabs/litiengine/attributes/AttributeValueListener.java @@ -2,7 +2,18 @@ import java.util.EventListener; +/** + * A listener interface for receiving attribute value change events. + * The class that is interested in processing an attribute value change event + * implements this interface, and the object created with that class is registered + * with a component using the component's `addAttributeValueListener` method. + * When the attribute value change event occurs, that object's `valueChanged` method + * is invoked. + */ @FunctionalInterface public interface AttributeValueListener extends EventListener { + /** + * Invoked when the value of an attribute has changed. + */ void valueChanged(); } diff --git a/litiengine/src/main/java/de/gurkenlabs/litiengine/attributes/RangeAttribute.java b/litiengine/src/main/java/de/gurkenlabs/litiengine/attributes/RangeAttribute.java index 56821c9ff..8bd82d0ef 100644 --- a/litiengine/src/main/java/de/gurkenlabs/litiengine/attributes/RangeAttribute.java +++ b/litiengine/src/main/java/de/gurkenlabs/litiengine/attributes/RangeAttribute.java @@ -4,6 +4,13 @@ import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +/** + * Represents an attribute with a range of values, including minimum and maximum values. This class extends the {@code Attribute} class and provides + * additional functionality for handling minimum and maximum value modifiers. + * + * @param + * The type of the attribute value, which must extend {@code Number}. + */ public class RangeAttribute extends Attribute { private final List> minModifiers; private final List> maxModifiers; @@ -16,11 +23,11 @@ public class RangeAttribute extends Attribute { * Initializes a new instance of the {@code RangeAttribute} class. * * @param maxValue - * The max value of this attribute. + * The max value of this attribute. * @param minValue - * The min value of this attribute + * The min value of this attribute * @param baseValue - * The base (initial) value of this attribute + * The base (initial) value of this attribute */ public RangeAttribute(final T maxValue, final T minValue, final T baseValue) { super(baseValue); @@ -32,6 +39,13 @@ public RangeAttribute(final T maxValue, final T minValue, final T baseValue) { this.evaluateValue(); } + /** + * Adds a modifier to the minimum value of the attribute. If the modifier is already present, it does nothing. After adding the modifier, it sorts + * the modifiers and re-evaluates the attribute value. + * + * @param modifier + * The modifier to be added. + */ public void addMinModifier(final AttributeModifier modifier) { if (this.getMinModifiers().contains(modifier)) { return; @@ -42,6 +56,13 @@ public void addMinModifier(final AttributeModifier modifier) { this.evaluateValue(); } + /** + * Adds a modifier to the maximum value of the attribute. If the modifier is already present, it does nothing. After adding the modifier, it sorts + * the modifiers and re-evaluates the attribute value. + * + * @param modifier + * The modifier to be added. + */ public void addMaxModifier(final AttributeModifier modifier) { if (this.getMaxModifiers().contains(modifier)) { return; @@ -52,60 +73,128 @@ public void addMaxModifier(final AttributeModifier modifier) { this.evaluateValue(); } + /** + * Gets the current value of the attribute, ensuring it is within the defined range. + * + * @return The current value of the attribute. + */ @Override public T get() { return this.valueInRange(super.get()); } + /** + * Gets the minimum value of the attribute after applying all modifiers. + * + * @return The minimum value of the attribute. + */ public T getMin() { return this.minValue; } + /** + * Gets the maximum value of the attribute after applying all modifiers. + * + * @return The maximum value of the attribute. + */ public T getMax() { return this.maxValue; } + /** + * Gets the relative current value of the attribute as a float. This is calculated as the current value divided by the maximum value. + * + * @return The relative current value of the attribute. + */ public float getRelativeCurrentValue() { return this.get().floatValue() / this.getMax().floatValue(); } + /** + * Modifies the base value of the attribute using the provided modifier. Ensures the new base value is within the defined range and re-evaluates the + * attribute value. + * + * @param modifier + * The modifier to be applied to the base value. + */ @Override public void modifyBaseValue(final AttributeModifier modifier) { this.setBaseValue(this.valueInRange(modifier.modify(this.getBase()))); this.evaluateValue(); } + /** + * Modifies the maximum base value of the attribute using the provided modifier. Re-evaluates the attribute value after modification. + * + * @param modifier + * The modifier to be applied to the maximum base value. + */ public void modifyMaxBaseValue(final AttributeModifier modifier) { this.maxBaseValue = modifier.modify(this.maxBaseValue); this.evaluateValue(); } + /** + * Sets the base value of the attribute to the minimum value. + */ public void setToMin() { this.setBaseValue(this.getMin()); } + /** + * Sets the base value of the attribute to the maximum value. + */ public void setToMax() { this.setBaseValue(this.getMax()); } + /** + * Sets the maximum base value of the attribute. Re-evaluates the attribute value after setting the new maximum base value. + * + * @param maxValue + * The new maximum base value to be set. + */ public void setMaxBaseValue(final T maxValue) { this.maxBaseValue = maxValue; this.evaluateValue(); } + /** + * Sets the minimum base value of the attribute. Re-evaluates the attribute value after setting the new minimum base value. + * + * @param minValue + * The new minimum base value to be set. + */ public void setMinBaseValue(final T minValue) { this.minBaseValue = minValue; this.evaluateValue(); } + /** + * Gets the list of modifiers applied to the minimum value of the attribute. + * + * @return The list of minimum value modifiers. + */ protected List> getMinModifiers() { return this.minModifiers; } + /** + * Gets the list of modifiers applied to the maximum value of the attribute. + * + * @return The list of maximum value modifiers. + */ protected List> getMaxModifiers() { return this.maxModifiers; } + /** + * Applies all minimum value modifiers to the given value. + * + * @param maxValue + * The value to which the minimum value modifiers will be applied. + * @return The modified value after applying all minimum value modifiers. + */ protected T applyMinModifiers(final T maxValue) { T currentValue = maxValue; for (final AttributeModifier modifier : this.getMinModifiers()) { @@ -115,6 +204,13 @@ protected T applyMinModifiers(final T maxValue) { return currentValue; } + /** + * Applies all maximum value modifiers to the given value. + * + * @param maxValue + * The value to which the maximum value modifiers will be applied. + * @return The modified value after applying all maximum value modifiers. + */ protected T applyMaxModifiers(final T maxValue) { T currentValue = maxValue; for (final AttributeModifier modifier : this.getMaxModifiers()) { @@ -124,6 +220,10 @@ protected T applyMaxModifiers(final T maxValue) { return currentValue; } + /** + * Evaluates the current value of the attribute by applying all registered modifiers to the base, minimum, and maximum values. Ensures the attribute + * value is within the defined range. + */ @Override protected void evaluateValue() { super.evaluateValue(); @@ -131,6 +231,13 @@ protected void evaluateValue() { this.maxValue = this.applyMaxModifiers(this.maxBaseValue); } + /** + * Ensures the given value is within the defined range of minimum and maximum values. + * + * @param value + * The value to be checked. + * @return The value if it is within the range, otherwise the nearest boundary value. + */ private T valueInRange(final T value) { if (value.doubleValue() < this.getMin().doubleValue()) { return this.getMin(); diff --git a/litiengine/src/main/java/de/gurkenlabs/litiengine/input/Mouse.java b/litiengine/src/main/java/de/gurkenlabs/litiengine/input/Mouse.java index e7909d535..f4ea58e4c 100644 --- a/litiengine/src/main/java/de/gurkenlabs/litiengine/input/Mouse.java +++ b/litiengine/src/main/java/de/gurkenlabs/litiengine/input/Mouse.java @@ -4,6 +4,7 @@ import de.gurkenlabs.litiengine.IUpdateable; import de.gurkenlabs.litiengine.environment.tilemap.MapUtilities; import de.gurkenlabs.litiengine.util.MathUtilities; + import java.awt.AWTException; import java.awt.Point; import java.awt.Robot; @@ -21,24 +22,24 @@ /** This implementation provides information about the mouse input in the LITIENGINE. */ public final class Mouse - implements MouseListener, MouseMotionListener, MouseWheelListener, IMouse, IUpdateable { + implements MouseListener, MouseMotionListener, MouseWheelListener, IMouse, IUpdateable { private static final Logger log = Logger.getLogger(Mouse.class.getName()); private final Collection mouseClickedListeners = - ConcurrentHashMap.newKeySet(); + ConcurrentHashMap.newKeySet(); private final Collection mouseDraggedListeners = - ConcurrentHashMap.newKeySet(); + ConcurrentHashMap.newKeySet(); private final Collection mouseMovedListeners = ConcurrentHashMap.newKeySet(); private final Collection mousePressedListeners = - ConcurrentHashMap.newKeySet(); + ConcurrentHashMap.newKeySet(); private final Collection mousePressingListeners = - ConcurrentHashMap.newKeySet(); + ConcurrentHashMap.newKeySet(); private final Collection mouseReleasedListeners = - ConcurrentHashMap.newKeySet(); + ConcurrentHashMap.newKeySet(); private final Collection mouseListeners = ConcurrentHashMap.newKeySet(); private final Collection mouseMotionListeners = - ConcurrentHashMap.newKeySet(); + ConcurrentHashMap.newKeySet(); private final Collection mouseWheelListeners = ConcurrentHashMap.newKeySet(); private final Robot robot; @@ -60,7 +61,7 @@ public final class Mouse * Instantiates a new mouse. * * @throws AWTException - * In case the {@link Robot} class could not be initialized. + * In case the {@link Robot} class could not be initialized. */ Mouse() throws AWTException { try { @@ -72,9 +73,9 @@ public final class Mouse } this.location = - new Point2D.Double( - Game.world().camera().getViewport().getCenterX(), - Game.world().camera().getViewport().getCenterY()); + new Point2D.Double( + Game.world().camera().getViewport().getCenterX(), + Game.world().camera().getViewport().getCenterY()); this.lastLocation = this.location; this.sensitivity = Game.config().input().getMouseSensitivity(); this.grabMouse = false; @@ -105,12 +106,15 @@ public Point2D getLocation() { @Override public Point2D getMapLocation() { + if (Game.world().camera() == null) { + return null; + } return Game.world() - .camera() - .getMapLocation( - new Point2D.Double( - this.getLocation().getX() / Game.world().camera().getRenderScale(), - this.getLocation().getY() / Game.world().camera().getRenderScale())); + .camera() + .getMapLocation( + new Point2D.Double( + this.getLocation().getX() / Game.world().camera().getRenderScale(), + this.getLocation().getY() / Game.world().camera().getRenderScale())); } @Override @@ -375,16 +379,16 @@ public void setLocation(final Point2D adjustMouse) { this.lastLocation = adjustMouse; final MouseEvent mouseEvent = - new MouseEvent( - Game.window().getRenderComponent(), - MouseEvent.MOUSE_MOVED, - 0, - 0, - (int) this.getLocation().getX(), - (int) this.getLocation().getY(), - 0, - false, - MouseEvent.NOBUTTON); + new MouseEvent( + Game.window().getRenderComponent(), + MouseEvent.MOUSE_MOVED, + 0, + 0, + (int) this.getLocation().getX(), + (int) this.getLocation().getY(), + 0, + false, + MouseEvent.NOBUTTON); final MouseEvent wrappedEvent = this.createEvent(mouseEvent); for (final MouseMovedListener listener : this.mouseMovedListeners) { listener.mouseMoved(wrappedEvent); @@ -398,25 +402,24 @@ public void setLocation(double x, double y) { private MouseEvent createEvent(final MouseEvent original) { return new MouseEvent( - original.getComponent(), - original.getID(), - original.getWhen(), - original.getModifiers(), - (int) this.getLocation().getX(), - (int) this.getLocation().getY(), - original.getXOnScreen(), - original.getYOnScreen(), - original.getClickCount(), - original.isPopupTrigger(), - original.getButton()); + original.getComponent(), + original.getID(), + original.getWhen(), + original.getModifiers(), + (int) this.getLocation().getX(), + (int) this.getLocation().getY(), + original.getXOnScreen(), + original.getYOnScreen(), + original.getClickCount(), + original.isPopupTrigger(), + original.getButton()); } /** - * Calculates the location of the ingame mouse by the position diff and locks the original mouse to the center of the - * screen. + * Calculates the location of the ingame mouse by the position diff and locks the original mouse to the center of the screen. * * @param e - * The event containing information about the original mouse. + * The event containing information about the original mouse. */ private void setLocation(final MouseEvent e) { if (this.grabMouse && !Game.window().isFocusOwner()) { @@ -459,7 +462,7 @@ private void setLocation(final MouseEvent e) { * Sets the pressed. * * @param pressed - * the new pressed + * the new pressed */ private void setPressed(final boolean pressed) { this.pressed = pressed;