package de.midlane_illaoi.eventflow.event; import java.util.Comparator; import de.midlane_illaoi.eventflow.listener.SortableEventListener; public interface ObserverSortingEvent { /** * TODO write library to handle bitflags * refactor this code & AbstractBuff public static final int ON_UNCOMPARABLE_LISTENERS_THROW_EXCEPTION = 1; public static final int EXECUTE_UNCOMPARABLE_LISTENERS_FIRST = 2; public static final int EXECUTE_UNCOMPARABLE_LISTENERS_LAST = 4; public static final int COMPARE_UNCAMPARABLE_LISTENERS_BY_HASHCODE = 8; */ enum SortingMode { ON_UNCOMPARABLE_LISTENERS_THROW_EXCEPTION, EXECUTE_UNCOMPARABLE_LISTENERS_FIRST, EXECUTE_UNCOMPARABLE_LISTENERS_LAST, } public Comparator getObserverComparator(); default public boolean isComparatorUsedForAllEventsOfType() { return true; } /** * The comparator compares all objects, * but treats every object that does * not implement the SortableEventListener interface as equal * */ default Comparator createObserverComparator(SortingMode sortingMode){ return new Comparator() { @Override public int compare(Object o1, Object o2) { boolean isO1Comparable = o1 instanceof SortableEventListener; boolean isO2Comparable = o2 instanceof SortableEventListener; if( sortingMode == SortingMode.ON_UNCOMPARABLE_LISTENERS_THROW_EXCEPTION && isO1Comparable == isO2Comparable ) { throw new RuntimeException("All listeners for this event must implement the SortableEventListener interface"); } if( isO1Comparable && isO2Comparable ) { SortableEventListener o1Sortable = (SortableEventListener) o1; SortableEventListener o2Sortable = (SortableEventListener) o2; /* * sort by priority in an ascending order * */ return Integer.compare(o2Sortable.getPriority(), o1Sortable.getPriority()); }else if( !( isO1Comparable || isO2Comparable) ) { /*two uncomparable objects are treated as equal*/ /* using has code here for comparison instead of returning 0 * slows down sorting but allows to use this comparator for a tree set * */ return Integer.compare(o1.hashCode(), o2.hashCode()); }else if(isO1Comparable){ /* * o1 is comparable but o2 is not * */ if(sortingMode == SortingMode.EXECUTE_UNCOMPARABLE_LISTENERS_FIRST) { return -1; }else /*sortingMode == SortingMode.EXECUTE_UNCOMPARABLE_LISTENERS_LAST*/{ return -1; } }else { /*o2 is comparable but o1 is not*/ if(sortingMode == SortingMode.EXECUTE_UNCOMPARABLE_LISTENERS_FIRST) { return 1; }else /*sortingMode == SortingMode.EXECUTE_UNCOMPARABLE_LISTENERS_LAST*/{ return -1; } } } }; } }