Changeset 17762 in josm for trunk/src


Ignore:
Timestamp:
2021-04-12T22:43:33+02:00 (3 years ago)
Author:
simon04
Message:

see #20744 - Evaluate MapCSS pseudo classes without array creation

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ConditionFactory.java

    r17745 r17762  
    22package org.openstreetmap.josm.gui.mappaint.mapcss;
    33
    4 import java.lang.reflect.Method;
    54import java.text.MessageFormat;
    6 import java.util.Arrays;
    75import java.util.EnumSet;
     6import java.util.HashMap;
     7import java.util.Locale;
     8import java.util.Map;
    89import java.util.Objects;
    910import java.util.Set;
     
    3334import org.openstreetmap.josm.gui.mappaint.mapcss.Condition.TagCondition;
    3435import org.openstreetmap.josm.tools.CheckParameterUtil;
    35 import org.openstreetmap.josm.tools.JosmRuntimeException;
    3636import org.openstreetmap.josm.tools.Utils;
    3737
     
    883883    public static class PseudoClassCondition implements Condition {
    884884
    885         final Method method;
    886         final boolean not;
    887 
    888         protected PseudoClassCondition(Method method, boolean not) {
    889             this.method = method;
    890             this.not = not;
     885        static final Map<String, PseudoClassCondition> CONDITION_MAP = new HashMap<>();
     886
     887        static {
     888            PseudoClassCondition.register("anticlockwise", PseudoClasses::anticlockwise);
     889            PseudoClassCondition.register("areaStyle", PseudoClasses::areaStyle);
     890            PseudoClassCondition.register("clockwise", PseudoClasses::clockwise);
     891            PseudoClassCondition.register("closed", PseudoClasses::closed);
     892            PseudoClassCondition.register("closed2", PseudoClasses::closed2);
     893            PseudoClassCondition.register("completely_downloaded", PseudoClasses::completely_downloaded);
     894            PseudoClassCondition.register("connection", PseudoClasses::connection);
     895            PseudoClassCondition.register("inDownloadedArea", PseudoClasses::inDownloadedArea);
     896            PseudoClassCondition.register("modified", PseudoClasses::modified);
     897            PseudoClassCondition.register("new", PseudoClasses::_new);
     898            PseudoClassCondition.register("righthandtraffic", PseudoClasses::righthandtraffic);
     899            PseudoClassCondition.register("sameTags", PseudoClasses::sameTags);
     900            PseudoClassCondition.register("selected", PseudoClasses::selected);
     901            PseudoClassCondition.register("tagged", PseudoClasses::tagged);
     902            PseudoClassCondition.register("unclosed_multipolygon", PseudoClasses::unclosed_multipolygon);
     903            PseudoClassCondition.register("unconnected", PseudoClasses::unconnected);
     904        }
     905
     906        private static void register(String name, Predicate<Environment> predicate) {
     907            CONDITION_MAP.put(clean(name), new PseudoClassCondition(":" + name, predicate));
     908            CONDITION_MAP.put("!" + clean(name), new PseudoClassCondition("!:" + name, predicate.negate()));
     909        }
     910
     911        private final String name;
     912        private final Predicate<Environment> predicate;
     913
     914        protected PseudoClassCondition(String name, Predicate<Environment> predicate) {
     915            this.name = name;
     916            this.predicate = predicate;
    891917        }
    892918
     
    903929                return new OpenEndPseudoClassCondition(not);
    904930            }
    905             final Method method = getMethod(id);
    906             if (method != null) {
    907                 return new PseudoClassCondition(method, not);
     931            String cleanId = not ? clean("!" + id) : clean(id);
     932            PseudoClassCondition condition = CONDITION_MAP.get(cleanId);
     933            if (condition != null) {
     934                return condition;
    908935            }
    909936            throw new MapCSSException("Invalid pseudo class specified: " + id);
    910         }
    911 
    912         protected static Method getMethod(String id) {
    913             String cleanId = clean(id);
    914             return Arrays.stream(PseudoClasses.class.getDeclaredMethods())
    915                     .filter(method -> clean(method.getName()).equalsIgnoreCase(cleanId))
    916                     .findFirst().orElse(null);
    917937        }
    918938
    919939        private static String clean(String id) {
    920940            // for backwards compatibility, consider :sameTags == :same-tags == :same_tags (#11150)
    921             return id.replaceAll("[-_]", "");
     941            return id.toLowerCase(Locale.ROOT).replaceAll("[-_]", "");
    922942        }
    923943
    924944        @Override
    925945        public boolean applies(Environment e) {
    926             try {
    927                 return not ^ (Boolean) method.invoke(null, e);
    928             } catch (ReflectiveOperationException ex) {
    929                 throw new JosmRuntimeException(ex);
    930             }
     946            return predicate.test(e);
    931947        }
    932948
    933949        @Override
    934950        public String toString() {
    935             return (not ? "!" : "") + ':' + method.getName();
     951            return name;
    936952        }
    937953    }
     
    941957     */
    942958    public static class OpenEndPseudoClassCondition extends PseudoClassCondition {
     959        final boolean not;
    943960        /**
    944961         * Constructs a new {@code OpenEndPseudoClassCondition}.
     
    946963         */
    947964        public OpenEndPseudoClassCondition(boolean not) {
    948             super(null, not);
     965            super("open_end", null);
     966            this.not = not;
    949967        }
    950968
    951969        @Override
    952970        public boolean applies(Environment e) {
    953             return true;
     971            return !not;
    954972        }
    955973    }
Note: See TracChangeset for help on using the changeset viewer.