Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/update-addon-version.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ jobs:
git config user.name "$GIT_USERNAME"
git config user.email "$GIT_EMAIL"
git add config.yaml
git commit -m "Update add-on $ADDONS_DIR version to $VERSION" || {
git commit -m "Update add-on $ADDON_DIR version to $VERSION" || {
echo "No changes to commit"
exit 0
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,21 +169,94 @@ static Boolean equalServiceStates(final ColorState colorStateA, final ColorState
final HSBColor hsbColorA = colorStateA.getColor().getHsbColor();
final HSBColor hsbColorB = colorStateB.getColor().getHsbColor();

// Helper: compare hues with wrap-around (0 == 360)
// margin in degrees
final double HUE_MARGIN = 1.0;
final double SATURATION_MARGIN = 0.01;
final double BRIGHTNESS_MARGIN = 0.01;

boolean hueEquals = true;
boolean saturationEquals = true;
boolean brightnessEquals = true;
// normalize angle to [0,360)
java.util.function.DoubleUnaryOperator normalize = (v) -> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we import DoubleUnaryOperator?

double r = v % 360.0;
if (r < 0) r += 360.0;
return r;
};

if(hsbColorA.hasHue() && hsbColorB.hasHue()) {
hueEquals = OperationService.equals(hsbColorA.getHue(), hsbColorB.getHue(), 1.0);
java.util.function.BiPredicate<Double, Double> hueEqualsWithWrap = (ha, hb) -> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here as well

double aNorm = normalize.applyAsDouble(ha);
double bNorm = normalize.applyAsDouble(hb);
double diff = Math.abs(aNorm - bNorm);
if (diff > 180.0) {
diff = 360.0 - diff; // shortest distance on circle
}
return diff <= HUE_MARGIN;
};

boolean hueEquals;
if (hsbColorA.hasHue() && hsbColorB.hasHue()) {
hueEquals = hueEqualsWithWrap.test(hsbColorA.getHue(), hsbColorB.getHue());
} else if (!hsbColorA.hasHue() && !hsbColorB.hasHue()) {
// both undefined -> treat as equal
hueEquals = true;
} else {
// one missing: if the present color is 'neutral' (saturation == 0 or brightness == 0 or both undefined) the hue is irrelevant
final HSBColor present = hsbColorA.hasHue() ? hsbColorA : hsbColorB;
boolean presentIsNeutral = false;
// If both saturation and brightness are missing, treat as neutral (no chroma information)
if (!present.hasSaturation() && !present.hasBrightness()) {
presentIsNeutral = true;
}
// If saturation is present and effectively 0 -> neutral
if (!presentIsNeutral && present.hasSaturation()) {
presentIsNeutral = OperationService.equals(present.getSaturation(), 0d, SATURATION_MARGIN);
}
// If not neutral yet and brightness is present and effectively 0 -> neutral
if (!presentIsNeutral && present.hasBrightness()) {
presentIsNeutral = OperationService.equals(present.getBrightness(), 0d, BRIGHTNESS_MARGIN);
}
hueEquals = presentIsNeutral;
}

if(hsbColorA.hasSaturation() && hsbColorB.hasSaturation()) {
saturationEquals = OperationService.equals(hsbColorA.getSaturation(), hsbColorB.getSaturation(), 0.01);
boolean saturationEquals;
if (hsbColorA.hasSaturation() && hsbColorB.hasSaturation()) {
saturationEquals = OperationService.equals(hsbColorA.getSaturation(), hsbColorB.getSaturation(), SATURATION_MARGIN);
} else if (!hsbColorA.hasSaturation() && !hsbColorB.hasSaturation()) {
saturationEquals = true;
} else {
// one missing: consider equal if the present saturation is effectively 0 (neutral)
// or if the present has no saturation but brightness is present and 0 -> neutral
final HSBColor present = hsbColorA.hasSaturation() ? hsbColorA : hsbColorB;
boolean presentIsNeutral = false;
if (present.hasSaturation()) {
presentIsNeutral = OperationService.equals(present.getSaturation(), 0d, SATURATION_MARGIN);
} else if (present.hasBrightness()) {
presentIsNeutral = OperationService.equals(present.getBrightness(), 0d, BRIGHTNESS_MARGIN);
} else {
// no saturation and no brightness information -> treat as neutral
presentIsNeutral = true;
}
saturationEquals = presentIsNeutral;
}

if(hsbColorA.hasBrightness() && hsbColorB.hasBrightness()) {
brightnessEquals = OperationService.equals(hsbColorA.getBrightness(), hsbColorB.getBrightness(), 0.01);
boolean brightnessEquals;
if (hsbColorA.hasBrightness() && hsbColorB.hasBrightness()) {
brightnessEquals = OperationService.equals(hsbColorA.getBrightness(), hsbColorB.getBrightness(), BRIGHTNESS_MARGIN);
} else if (!hsbColorA.hasBrightness() && !hsbColorB.hasBrightness()) {
brightnessEquals = true;
} else {
// one missing: consider equal if the present brightness is effectively 0 (off/neutral)
// or if the present has no brightness but saturation is present and 0 -> neutral
final HSBColor present = hsbColorA.hasBrightness() ? hsbColorA : hsbColorB;
boolean presentIsNeutral = false;
if (present.hasBrightness()) {
presentIsNeutral = OperationService.equals(present.getBrightness(), 0d, BRIGHTNESS_MARGIN);
} else if (present.hasSaturation()) {
presentIsNeutral = OperationService.equals(present.getSaturation(), 0d, SATURATION_MARGIN);
} else {
// no brightness and no saturation information -> treat as neutral
presentIsNeutral = true;
}
brightnessEquals = presentIsNeutral;
}

return hueEquals && saturationEquals && brightnessEquals;
Expand Down

This file was deleted.

Loading
Loading