From 7125b38fd59bbb37d8ede0f40d365d4cab0e1739 Mon Sep 17 00:00:00 2001 From: RePixelatedMC <107539181+RePixelatedMC@users.noreply.github.com> Date: Thu, 29 Aug 2024 15:46:16 +0200 Subject: [PATCH] Sync! --- .../engine/service/EngineMobHandlerSVC.java | 200 ++++++++++++++---- .../volmit/iris/util/mobs/HistoryManager.java | 47 ---- .../iris/util/mobs/IrisMobDataHandler.java | 5 +- 3 files changed, 161 insertions(+), 91 deletions(-) delete mode 100644 core/src/main/java/com/volmit/iris/util/mobs/HistoryManager.java diff --git a/core/src/main/java/com/volmit/iris/engine/service/EngineMobHandlerSVC.java b/core/src/main/java/com/volmit/iris/engine/service/EngineMobHandlerSVC.java index ce101278e..6bba16ddb 100644 --- a/core/src/main/java/com/volmit/iris/engine/service/EngineMobHandlerSVC.java +++ b/core/src/main/java/com/volmit/iris/engine/service/EngineMobHandlerSVC.java @@ -4,13 +4,15 @@ import com.volmit.iris.Iris; import com.volmit.iris.core.nms.INMS; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.IrisEngineService; -import com.volmit.iris.util.data.KCache; import com.volmit.iris.util.format.Form; -import com.volmit.iris.util.mobs.HistoryManager; import com.volmit.iris.util.mobs.IrisMobDataHandler; import com.volmit.iris.util.mobs.IrisMobPiece; import com.volmit.iris.util.scheduling.Looper; import com.volmit.iris.util.scheduling.PrecisionStopwatch; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.RequiredArgsConstructor; import org.bukkit.Chunk; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; @@ -19,24 +21,28 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.player.PlayerChangedWorldEvent; -import javax.xml.crypto.Data; import java.util.*; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.CountDownLatch; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; -import java.util.function.Supplier; import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; public class EngineMobHandlerSVC extends IrisEngineService implements IrisMobDataHandler { - private HistoryManager history; + private HashSet history; + + private Function>, LinkedHashMap>> sortMapFunction; + + private Function, LinkedHashMap> sortMapSimpleFunction; private int id; public int energyMax; public int energy; - private long irritation = 0; + private long iteration = 0; // 1 every second private HashSet loadedChunks; private HashMap bukkitLimits; private Function entityType; @@ -48,13 +54,58 @@ public class EngineMobHandlerSVC extends IrisEngineService implements IrisMobDat @Override public void onEnable(boolean hotload) { - this.id = engine.getCacheID(); - this.history = new HistoryManager<>(Long.MAX_VALUE); this.pieces = new ConcurrentLinkedQueue<>(); + this.history = new HashSet<>(); this.entityType = (entityType) -> Types.valueOf(INMS.get().getMobCategory(entityType)); this.loadedChunks = new HashSet<>(); this.bukkitLimits = getBukkitLimits(); + this.sortMapFunction = + new Function<>() { + private Map> lastMap; + private LinkedHashMap> cachedSortedMap; + + @Override + public LinkedHashMap> apply(Map> inputMap) { + if (cachedSortedMap == null || !inputMap.equals(lastMap)) { + cachedSortedMap = inputMap.entrySet() + .stream() + .sorted(Map.Entry.>comparingByValue( + Comparator.comparingInt(list -> list.stream().mapToInt(Integer::intValue).sum()) + ).reversed()) + .collect(Collectors.toMap( + Map.Entry::getKey, + Map.Entry::getValue, + (e1, e2) -> e1, + LinkedHashMap::new + )); + lastMap = new HashMap<>(inputMap); + } + return cachedSortedMap; + } + }; + + this.sortMapSimpleFunction = new Function<>() { + private Map lastMap; + private LinkedHashMap cachedSortedMap; + + @Override + public LinkedHashMap apply(Map inputMap) { + if (cachedSortedMap == null || !inputMap.equals(lastMap)) { + cachedSortedMap = inputMap.entrySet() + .stream() + .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())) + .collect(Collectors.toMap( + Map.Entry::getKey, + Map.Entry::getValue, + (e1, e2) -> e1, + LinkedHashMap::new + )); + lastMap = new HashMap<>(inputMap); + } + return cachedSortedMap; + } + }; new Ticker(); } @@ -77,7 +128,7 @@ public class EngineMobHandlerSVC extends IrisEngineService implements IrisMobDat protected long loop() { long wait = -1; try { - irritation++; + iteration++; if (engine.isClosed() || engine.getCacheID() != id) { interrupt(); } @@ -120,44 +171,81 @@ public class EngineMobHandlerSVC extends IrisEngineService implements IrisMobDat } } + + private LinkedHashMap test(LinkedHashMap> req) { + LinkedHashMap res = new LinkedHashMap<>(); + for (IrisMobPiece piece : req.keySet()) { + res.put(piece, null); + } + return res; + } + /** - * @param map Data to do calculations with + * @param req Data to do calculations with. List> = Requested energy + future * @return returns the energy distribution for each piece */ - private LinkedHashMap assignEnergyToPieces(LinkedHashMap> map) { - Supplier>> sortedMapSupplier = new Supplier<>() { - private LinkedHashMap> cachedMap; - - @Override - public LinkedHashMap> get() { - if (cachedMap == null) { - cachedMap = map.entrySet() - .stream() - .sorted(Map.Entry.>comparingByValue( - Comparator.comparingInt(list -> list.stream().mapToInt(Integer::intValue).sum()) - ).reversed()) - .collect(Collectors.toMap( - Map.Entry::getKey, - Map.Entry::getValue, - (e1, e2) -> e1, - LinkedHashMap::new - )); - } - return cachedMap; - } - }; + private LinkedHashMap assignEnergyToPieces(LinkedHashMap> req) { // Might need caching? - Function viewHistory = (history) -> - map.values().stream() - .mapToInt(list -> list.isEmpty() ? 0 : list.get(history)) - .sum(); + int futureView = 60; + int energy = calculateNewEnergy(); + + LinkedHashMap finalMap = req.keySet().stream() + .collect(Collectors.toMap( + piece -> piece, + piece -> null, + (existing, replacement) -> existing, + LinkedHashMap::new + )); + + Function> viewSingleFuture = (future) -> + req.values().stream() + .mapToInt(list -> list.isEmpty() ? 0 : list.get(future)).boxed(); + + Function>> viewFuture = (rangeMin) -> (rangeMax) -> + IntStream.range(rangeMin, rangeMax) + .boxed() + .flatMap(viewSingleFuture); + + Function viewFutureMedian = (value) -> viewFuture.apply(value).apply(futureView) + .sorted() + .collect(Collectors.collectingAndThen(Collectors.toList(), + list -> { + int size = list.size(); + if (size % 2 == 0) { + return (list.get(size / 2 - 1) + list.get(size / 2)) / 2.0; + } else { + return list.get(size / 2).doubleValue(); + } + })); + + // Logic + + if ((predictEnergy(futureView) / viewFutureMedian.apply(0)) > 1.25 && (energy / viewSingleFuture.apply(0).mapToInt(Integer::intValue).sum() > 1)) { + + finalMap = req.entrySet().stream() + .collect(Collectors.toMap( + Map.Entry::getKey, + e -> e.getValue().isEmpty() ? 0 : e.getValue().get(0), + (v1, v2) -> v1, + LinkedHashMap::new + )); + } else if ((energy / viewSingleFuture.apply(0).mapToInt(Integer::intValue).sum() > 1)) { + // hard part - int i = calculateNewEnergy(); + } else if ((energy / viewSingleFuture.apply(0).mapToInt(Integer::intValue).sum() < 1)) { + double scale = 1; + while ((double) energy / viewSingleFuture.apply(0).mapToInt(Integer::intValue).sum() >= scale) { + scale -= 0.1; + } + double finalScale = scale + 0.1; + LinkedHashMap finalMap1 = finalMap; + req.forEach((key, value) -> finalMap1.put(key, (int) (value.get(0) * finalScale))); + } - return null; + return finalMap; } @@ -200,17 +288,37 @@ public class EngineMobHandlerSVC extends IrisEngineService implements IrisMobDat private void updateMaxEnergy() { var e = (int) engine.getDimension().getEnergy().evaluateMax("max", null, engine.getData(), (double) energy); - history.addEntry(DataType.ENERGY_MAX, e, irritation); + history.add(new HistoryData(DataType.ENERGY_MAX, e, iteration)); energyMax = e; } private int calculateNewEnergy() { - return (int) engine.getDimension().getEnergy().evaluateMax("cur",null, engine.getData(), (double) energy); + var e = engine.getDimension().getEnergy().evaluateMax("cur",null, engine.getData(), (double) energy); + history.add(new HistoryData(DataType.ENERGY_ADDITION, (int) e, iteration)); + return (int) e; + } + + /** + * + * @param it How many iterations it should get to predict: 1 = second + * @return The Iterations/cost + */ + private Integer predictEnergy(int it) { + List list = new ArrayList<>(); + history.stream() + .filter(data -> data.getDataType() == DataType.ENERGY_ADDITION) // Filter by target DataType + .forEach(data -> { + if (data.getIteration() > iteration - it) { + list.add((Integer) data.getValue()); + } + }); + + return (int) list.stream().sorted().skip((list.size() - 1) / 2).limit(2 - list.size() % 2).mapToInt(Integer::intValue).average().orElse(Double.NaN); } @Override - public long getIrritation() { - return irritation; + public long getIteration() { + return iteration; } @Override @@ -238,4 +346,12 @@ public class EngineMobHandlerSVC extends IrisEngineService implements IrisMobDat updateMaxEnergy(); return energy; } + + @Data + @AllArgsConstructor + private class HistoryData { + private DataType dataType; + private T value; + private long iteration; + } } \ No newline at end of file diff --git a/core/src/main/java/com/volmit/iris/util/mobs/HistoryManager.java b/core/src/main/java/com/volmit/iris/util/mobs/HistoryManager.java deleted file mode 100644 index 24fb00e99..000000000 --- a/core/src/main/java/com/volmit/iris/util/mobs/HistoryManager.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.volmit.iris.util.mobs; - -import lombok.Data; - -import java.util.Deque; -import java.util.concurrent.ConcurrentLinkedDeque; - -public class HistoryManager { - private final Deque> history = new ConcurrentLinkedDeque<>(); - private final long maxSize; - - public HistoryManager(long maxSize) { - this.maxSize = maxSize; - } - - public void addEntry(K key, V value, I irritation) { - history.addFirst(new HistoryEntry<>(key, value, irritation)); - if (history.size() > maxSize) { - history.removeLast(); - } - } - - public HistoryEntry getEntry(int index) { - return history.stream().skip(index).findFirst().orElse(null); - } - - public I get3rd() { - return history.stream() - .skip(2) - .findFirst() - .map(HistoryEntry::getExtra) - .orElse(null); - } - - @Data - public static class HistoryEntry { - private final K key; - private final V value; - private final I extra; - - public HistoryEntry(K key, V value, I extra) { - this.key = key; - this.value = value; - this.extra = extra; - } - } -} \ No newline at end of file diff --git a/core/src/main/java/com/volmit/iris/util/mobs/IrisMobDataHandler.java b/core/src/main/java/com/volmit/iris/util/mobs/IrisMobDataHandler.java index edce0ade1..acaf22384 100644 --- a/core/src/main/java/com/volmit/iris/util/mobs/IrisMobDataHandler.java +++ b/core/src/main/java/com/volmit/iris/util/mobs/IrisMobDataHandler.java @@ -26,11 +26,12 @@ public interface IrisMobDataHandler { enum DataType { ENERGY_MAX, - ENERGY_CONSUMPTION + ENERGY_CONSUMPTION, + ENERGY_ADDITION } - long getIrritation(); + long getIteration(); Function getMobType();