-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from kuba6000/tracking
Job tracking (time spent on crafting etc...)
- Loading branch information
Showing
18 changed files
with
804 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
178 changes: 178 additions & 0 deletions
178
src/main/java/com/kuba6000/ae2webintegration/AE2JobTracker.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
package com.kuba6000.ae2webintegration; | ||
|
||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
|
||
import com.kuba6000.ae2webintegration.mixins.AE2.CraftingCPUClusterAccessor; | ||
import com.kuba6000.ae2webintegration.mixins.AE2.CraftingLinkAccessor; | ||
import com.kuba6000.ae2webintegration.utils.GSONUtils; | ||
|
||
import appeng.api.networking.crafting.ICraftingCPU; | ||
import appeng.api.networking.crafting.ICraftingLink; | ||
import appeng.api.storage.data.IAEItemStack; | ||
import appeng.api.storage.data.IItemList; | ||
import appeng.crafting.CraftingLink; | ||
import appeng.me.cluster.implementations.CraftingCPUCluster; | ||
import cpw.mods.fml.common.registry.GameRegistry; | ||
|
||
public class AE2JobTracker { | ||
|
||
public static class JobTrackingInfo { | ||
|
||
public IAEItemStack finalOutput; | ||
public long timeStarted; | ||
public long timeDone; | ||
public HashMap<IAEItemStack, Long> timeSpentOn = new HashMap<>(); | ||
public HashMap<IAEItemStack, Long> startedWaitingFor = new HashMap<>(); | ||
public HashMap<IAEItemStack, Long> craftedTotal = new HashMap<>(); | ||
public HashMap<IAEItemStack, Long> waitingFor = new HashMap<>(); | ||
public boolean isDone = false; | ||
public boolean wasCancelled = false; | ||
|
||
public long getTimeSpentOn(IAEItemStack stack) { | ||
Long time = timeSpentOn.get(stack); | ||
if (time == null) return 0L; | ||
Long additionalTime = startedWaitingFor.get(stack); | ||
if (additionalTime != null) { | ||
time += System.nanoTime() - additionalTime; | ||
} | ||
return time; | ||
} | ||
|
||
public double getShareInCraftingTime(IAEItemStack stack) { | ||
long total = 0L; | ||
long stackTime = 0L; | ||
for (IAEItemStack iaeItemStack : timeSpentOn.keySet()) { | ||
long timeSpent = getTimeSpentOn(iaeItemStack); | ||
total += timeSpent; | ||
if (stack.isSameType(iaeItemStack)) { | ||
stackTime = timeSpent; | ||
} | ||
} | ||
if (total == 0L) return 1d; | ||
return (double) stackTime / (double) total; | ||
} | ||
} | ||
|
||
public static class CompactedJobTrackingInfo { | ||
|
||
public static class CompactedTrackingGSONItem { | ||
|
||
public String itemid; | ||
public String itemname; | ||
public long timeSpentOn; | ||
public long craftedTotal; | ||
public double shareInCraftingTime = 0d; | ||
public double craftsPerSec = 0d; | ||
} | ||
|
||
public AE2Controller.GSONItem finalOutput; | ||
public long timeStarted; | ||
public long timeDone; | ||
public boolean wasCancelled; | ||
public ArrayList<CompactedTrackingGSONItem> items = new ArrayList<>(); | ||
|
||
public CompactedJobTrackingInfo(JobTrackingInfo info) { | ||
this.finalOutput = GSONUtils.convertToGSONItem(info.finalOutput); | ||
this.timeStarted = info.timeStarted; | ||
this.timeDone = info.timeDone; | ||
this.wasCancelled = info.wasCancelled; | ||
for (Map.Entry<IAEItemStack, Long> iaeItemStackLongEntry : info.timeSpentOn.entrySet()) { | ||
IAEItemStack stack = iaeItemStackLongEntry.getKey(); | ||
long spent = iaeItemStackLongEntry.getValue(); | ||
CompactedTrackingGSONItem item = new CompactedTrackingGSONItem(); | ||
item.itemid = GameRegistry.findUniqueIdentifierFor(stack.getItem()) | ||
.toString() + ":" | ||
+ stack.getItemDamage(); | ||
item.itemname = stack.getItemStack() | ||
.getDisplayName(); | ||
item.timeSpentOn = spent; | ||
item.craftedTotal = info.craftedTotal.get(stack); | ||
item.shareInCraftingTime = info.getShareInCraftingTime(stack); | ||
item.craftsPerSec = (double) item.craftedTotal / (item.timeSpentOn / 1e9d); | ||
items.add(item); | ||
} | ||
items.sort((i1, i2) -> Double.compare(i2.shareInCraftingTime, i1.shareInCraftingTime)); | ||
} | ||
} | ||
|
||
public static HashMap<ICraftingCPU, JobTrackingInfo> trackingInfoMap = new HashMap<>(); | ||
public static ConcurrentHashMap<Integer, JobTrackingInfo> trackingInfos = new ConcurrentHashMap<>(); | ||
|
||
private static int nextFreeTrackingInfoID = 1; | ||
|
||
public static void addJob(ICraftingLink link) { | ||
if (link instanceof CraftingLink craftingLink) { | ||
ICraftingCPU cpu = ((CraftingLinkAccessor) craftingLink).callGetCpu(); | ||
if (cpu instanceof CraftingCPUCluster cpuCluster) { | ||
JobTrackingInfo info; | ||
trackingInfoMap.put(cpu, info = new JobTrackingInfo()); | ||
info.timeStarted = System.currentTimeMillis() / 1000L; | ||
info.finalOutput = cpu.getFinalOutput() | ||
.copy(); | ||
for (IAEItemStack iaeItemStack : ((CraftingCPUClusterAccessor) (Object) cpuCluster).getWaitingFor()) { | ||
info.startedWaitingFor.put(iaeItemStack, System.nanoTime()); | ||
info.timeSpentOn.put(iaeItemStack, 0L); | ||
info.craftedTotal.put(iaeItemStack, 0L); | ||
info.waitingFor.put(iaeItemStack, iaeItemStack.getStackSize()); | ||
} | ||
} | ||
} | ||
} | ||
|
||
public static void updateCraftingStatus(ICraftingCPU cpu, IAEItemStack diff) { | ||
JobTrackingInfo info = trackingInfoMap.get(cpu); | ||
if (info == null) return; | ||
CraftingCPUCluster cpuCluster = (CraftingCPUCluster) cpu; | ||
IItemList<IAEItemStack> waitingFor = ((CraftingCPUClusterAccessor) (Object) cpuCluster).getWaitingFor(); | ||
IAEItemStack found = waitingFor.findPrecise(diff); | ||
if (found != null && found.getStackSize() > 0L) { | ||
if (!info.startedWaitingFor.containsKey(found)) { | ||
info.startedWaitingFor.put(found, System.nanoTime()); | ||
info.timeSpentOn.putIfAbsent(found, 0L); | ||
info.waitingFor.put(found, found.getStackSize()); | ||
} else { | ||
long i = info.waitingFor.get(found); | ||
long newi = found.getStackSize(); | ||
if (i > newi) { | ||
info.craftedTotal.merge(found, i - newi, Long::sum); | ||
} | ||
info.waitingFor.put(found, newi); | ||
} | ||
} else { | ||
if (info.startedWaitingFor.containsKey(diff)) { | ||
Long started = info.startedWaitingFor.remove(diff); | ||
Long elapsed = System.nanoTime() - started; | ||
info.timeSpentOn.merge(diff, elapsed, Long::sum); | ||
info.craftedTotal.merge(diff, info.waitingFor.remove(diff), Long::sum); | ||
} | ||
} | ||
} | ||
|
||
public static void completeCrafting(ICraftingCPU cpu) { | ||
JobTrackingInfo info = trackingInfoMap.remove(cpu); | ||
if (info == null) return; | ||
for (Map.Entry<IAEItemStack, Long> iaeItemStackLongEntry : info.waitingFor.entrySet()) { | ||
info.craftedTotal.merge(iaeItemStackLongEntry.getKey(), iaeItemStackLongEntry.getValue(), Long::sum); | ||
} | ||
info.waitingFor.clear(); | ||
for (Map.Entry<IAEItemStack, Long> iaeItemStackLongEntry : info.startedWaitingFor.entrySet()) { | ||
info.timeSpentOn | ||
.merge(iaeItemStackLongEntry.getKey(), System.nanoTime() - iaeItemStackLongEntry.getValue(), Long::sum); | ||
} | ||
info.startedWaitingFor.clear(); | ||
info.isDone = true; | ||
info.timeDone = System.currentTimeMillis() / 1000L; | ||
trackingInfos.put(nextFreeTrackingInfoID++, info); | ||
} | ||
|
||
public static void cancelCrafting(ICraftingCPU cpu) { | ||
JobTrackingInfo info = trackingInfoMap.get(cpu); | ||
if (info == null) return; | ||
completeCrafting(cpu); | ||
info.wasCancelled = true; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.