This commit is contained in:
RePixelatedMC
2024-08-29 15:46:16 +02:00
parent b1e87afc93
commit 7125b38fd5
3 changed files with 161 additions and 91 deletions

View File

@@ -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<DataType, Integer, Long> history;
private HashSet<HistoryData> history;
private Function<Map<IrisMobPiece, List<Integer>>, LinkedHashMap<IrisMobPiece, List<Integer>>> sortMapFunction;
private Function<Map<IrisMobPiece, Integer>, LinkedHashMap<IrisMobPiece, Integer>> sortMapSimpleFunction;
private int id;
public int energyMax;
public int energy;
private long irritation = 0;
private long iteration = 0; // 1 every second
private HashSet<Chunk> loadedChunks;
private HashMap<Types, Integer> bukkitLimits;
private Function<EntityType, Types> 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<IrisMobPiece, List<Integer>> lastMap;
private LinkedHashMap<IrisMobPiece, List<Integer>> cachedSortedMap;
@Override
public LinkedHashMap<IrisMobPiece, List<Integer>> apply(Map<IrisMobPiece, List<Integer>> inputMap) {
if (cachedSortedMap == null || !inputMap.equals(lastMap)) {
cachedSortedMap = inputMap.entrySet()
.stream()
.sorted(Map.Entry.<IrisMobPiece, List<Integer>>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<IrisMobPiece, Integer> lastMap;
private LinkedHashMap<IrisMobPiece, Integer> cachedSortedMap;
@Override
public LinkedHashMap<IrisMobPiece, Integer> apply(Map<IrisMobPiece, Integer> inputMap) {
if (cachedSortedMap == null || !inputMap.equals(lastMap)) {
cachedSortedMap = inputMap.entrySet()
.stream()
.sorted(Map.Entry.<IrisMobPiece, Integer>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<IrisMobPiece, Integer> test(LinkedHashMap<IrisMobPiece, List<Integer>> req) {
LinkedHashMap<IrisMobPiece, Integer> 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<Integer>> = Requested energy + future
* @return returns the energy distribution for each piece
*/
private LinkedHashMap<IrisMobPiece, Integer> assignEnergyToPieces(LinkedHashMap<IrisMobPiece, List<Integer>> map) {
Supplier<LinkedHashMap<IrisMobPiece, List<Integer>>> sortedMapSupplier = new Supplier<>() {
private LinkedHashMap<IrisMobPiece, List<Integer>> cachedMap;
@Override
public LinkedHashMap<IrisMobPiece, List<Integer>> get() {
if (cachedMap == null) {
cachedMap = map.entrySet()
.stream()
.sorted(Map.Entry.<IrisMobPiece, List<Integer>>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<IrisMobPiece, Integer> assignEnergyToPieces(LinkedHashMap<IrisMobPiece, List<Integer>> req) {
// Might need caching?
Function<Integer, Integer> viewHistory = (history) ->
map.values().stream()
.mapToInt(list -> list.isEmpty() ? 0 : list.get(history))
.sum();
int futureView = 60;
int energy = calculateNewEnergy();
LinkedHashMap<IrisMobPiece, Integer> finalMap = req.keySet().stream()
.collect(Collectors.toMap(
piece -> piece,
piece -> null,
(existing, replacement) -> existing,
LinkedHashMap::new
));
Function<Integer, Stream<Integer>> viewSingleFuture = (future) ->
req.values().stream()
.mapToInt(list -> list.isEmpty() ? 0 : list.get(future)).boxed();
Function<Integer, Function<Integer, Stream<Integer>>> viewFuture = (rangeMin) -> (rangeMax) ->
IntStream.range(rangeMin, rangeMax)
.boxed()
.flatMap(viewSingleFuture);
Function<Integer, Double> 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<IrisMobPiece, Integer> 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<Integer> 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<T> {
private DataType dataType;
private T value;
private long iteration;
}
}

View File

@@ -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<K, V, I> {
private final Deque<HistoryEntry<K, V, I>> 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<K, V, I> 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<K, V, I> {
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;
}
}
}

View File

@@ -26,11 +26,12 @@ public interface IrisMobDataHandler {
enum DataType {
ENERGY_MAX,
ENERGY_CONSUMPTION
ENERGY_CONSUMPTION,
ENERGY_ADDITION
}
long getIrritation();
long getIteration();
Function<EntityType, Types> getMobType();