package tc.oc.pgm.structure; import java.util.Comparator; import java.util.PriorityQueue; import javax.inject.Inject; import tc.oc.pgm.features.FeatureDefinitionContext; import tc.oc.pgm.match.Match; import tc.oc.pgm.match.MatchScope; /** * We need this to make sure that dynamics are placed and cleared in definition order, * and that clears happen before placements. */ public class DynamicScheduler { private final Match match; private final PriorityQueue<Dynamic> clearQueue; private final PriorityQueue<Dynamic> placeQueue; @Inject DynamicScheduler(Match match, FeatureDefinitionContext fdc) { this.match = match; // Process dynamics in lexical order final Comparator<Dynamic> order = Comparator.comparing(Dynamic::getDefinition, fdc); this.clearQueue = new PriorityQueue<>(order); this.placeQueue = new PriorityQueue<>(order); } void queuePlace(Dynamic dynamic) { clearQueue.remove(dynamic); placeQueue.add(dynamic); schedule(); } void queueClear(Dynamic dynamic) { placeQueue.remove(dynamic); clearQueue.add(dynamic); schedule(); } private void schedule() { match.getScheduler(MatchScope.LOADED) .debounceTask(this::process); } public void process(){ for(;;) { final Dynamic dynamic = clearQueue.poll(); if(dynamic == null) break; dynamic.clear(); } for(;;) { Dynamic dynamic = placeQueue.poll(); if(dynamic == null) break; dynamic.place(); } } }