Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

更正电网tick中原件加入为队列加入 #1017

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 81 additions & 45 deletions common/src/main/java/dev/dubhe/anvilcraft/api/power/PowerGrid.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,16 @@
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
* 电网
*/
@SuppressWarnings("unused")
public class PowerGrid {
public static boolean isServerClosing = false;
private static final Map<Level, Set<PowerGrid>> GRID_MAP = Collections.synchronizedMap(new HashMap<>());
private static final PowerGridData GRID_DATA = new PowerGridData();
public static final int GRID_TICK = 20;
@Getter
public boolean remove = false;
Expand Down Expand Up @@ -71,14 +73,7 @@ public boolean isEmpty() {
* 总电力刻
*/
public static void tickGrid() {
for (Set<PowerGrid> grids : PowerGrid.GRID_MAP.values()) {
Set<PowerGrid> remove = Collections.synchronizedSet(new HashSet<>());
grids.forEach(powerGrid -> {
if (powerGrid.isEmpty() || powerGrid.isRemove()) remove.add(powerGrid);
powerGrid.tick();
});
grids.removeAll(remove);
}
GRID_DATA.tick();
}

/**
Expand Down Expand Up @@ -277,49 +272,90 @@ public boolean isInRange(@NotNull IPowerComponent component) {
* @param components 元件
*/
public static void addComponent(IPowerComponent @NotNull ... components) {

for (IPowerComponent component : components) {
if (component.getComponentType() == PowerComponentType.INVALID) continue;
final PowerGrid[] grid = {null};
Set<PowerGrid> grids = PowerGrid.getGridSet(component.getCurrentLevel());
Set<PowerGrid> remove = Collections.synchronizedSet(new HashSet<>());
grids.forEach(powerGrid -> {
if (powerGrid.isRemove() || !powerGrid.isInRange(component)) return;
if (grid[0] == null) grid[0] = powerGrid;
else {
grid[0].merge(powerGrid);
remove.add(powerGrid);
new PowerGridRemovePack(powerGrid).broadcast();
}
});
grids.removeAll(remove);
if (grid[0] == null) grid[0] = new PowerGrid(component.getCurrentLevel());
grid[0].add(component);
grids.add(grid[0]);
}

}

/**
* 获取指定世界的电网集合
*
* @param level 世界
* @return 电网集合
*/
public static Set<PowerGrid> getGridSet(Level level) {
if (PowerGrid.GRID_MAP.containsKey(level)) {
return PowerGrid.GRID_MAP.get(level);
} else {
Set<PowerGrid> grids = Collections.synchronizedSet(new HashSet<>());
PowerGrid.GRID_MAP.put(level, grids);
return grids;
GRID_DATA.addComponent(component);
}
}

/**
* 清空电网
*/
public static void clear() {
PowerGrid.GRID_MAP.values().forEach(Collection::clear);
PowerGrid.GRID_DATA.clear();
}

private static class PowerGridData {
private final Map<Level, Set<PowerGrid>> gridMap = Collections.synchronizedMap(new HashMap<>());
private final LinkedBlockingQueue<Map.Entry<Level, IPowerComponent>> addQueue = new LinkedBlockingQueue<>();

public PowerGridData() {
}

public synchronized void addComponent(@NotNull IPowerComponent component) {
try {
addQueue.offer(Map.entry(component.getCurrentLevel(), component), 500, TimeUnit.MICROSECONDS);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}

public synchronized void remove(PowerGrid powerGrid) {
powerGrid.remove = true;
}

public synchronized void removeAll(Collection<PowerGrid> powerGrids) {
powerGrids.forEach(this::remove);
}

public void clear() {
gridMap.clear();
}

public synchronized void tick() {
for (int i = 0; i < addQueue.size(); i++) {
try {
Map.Entry<Level, IPowerComponent> entry = addQueue.poll(500, TimeUnit.MICROSECONDS);
if (entry == null) continue;
IPowerComponent component = entry.getValue();
if (component.getComponentType() == PowerComponentType.INVALID) continue;
final PowerGrid[] grid = {null};
Set<PowerGrid> grids = getGridSet(entry.getKey());
Set<PowerGrid> remove = Collections.synchronizedSet(new HashSet<>());
grids.forEach(powerGrid -> {
if (powerGrid.isRemove() || !powerGrid.isInRange(component)) return;
if (grid[0] == null) grid[0] = powerGrid;
else {
grid[0].merge(powerGrid);
remove.add(powerGrid);
new PowerGridRemovePack(powerGrid).broadcast();
}
});
grids.removeAll(remove);
if (grid[0] == null) grid[0] = new PowerGrid(component.getCurrentLevel());
grid[0].add(component);
grids.add(grid[0]);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
for (Set<PowerGrid> grids : gridMap.values()) {
Set<PowerGrid> remove = Collections.synchronizedSet(new HashSet<>());
grids.forEach(powerGrid -> {
if (powerGrid.isEmpty() || powerGrid.isRemove()) remove.add(powerGrid);
powerGrid.tick();
});
grids.removeAll(remove);
}
}

private Set<PowerGrid> getGridSet(Level level) {
if (gridMap.containsKey(level)) {
return gridMap.get(level);
} else {
Set<PowerGrid> grids = Collections.synchronizedSet(new HashSet<>());
gridMap.put(level, grids);
return grids;
}
}
}
}
6 changes: 3 additions & 3 deletions common/src/main/resources/anvilcraft.accesswidener
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ accessible class net/minecraft/server/MinecraftServer$ReloadableResources
accessible class net/minecraft/world/item/crafting/Ingredient$Value
accessible class net/minecraft/world/item/crafting/Ingredient$TagValue
accessible class net/minecraft/world/inventory/BeaconMenu$PaymentSlot
extendable method net/minecraft/client/gui/screens/inventory/AbstractContainerScreen renderSlot (Lnet/minecraft/client/gui/GuiGraphics;Lnet/minecraft/world/inventory/Slot;)V
accessible method net/minecraft/server/MinecraftServer$ReloadableResources resourceManager ()Lnet/minecraft/server/packs/resources/CloseableResourceManager;
accessible field net/minecraft/world/item/crafting/RecipeManager recipes Ljava/util/Map;
accessible field net/minecraft/world/item/crafting/Ingredient values [Lnet/minecraft/world/item/crafting/Ingredient$Value;
accessible field net/minecraft/world/item/crafting/Ingredient$TagValue tag Lnet/minecraft/tags/TagKey;
Expand All @@ -21,10 +19,12 @@ accessible field net/minecraft/client/renderer/RenderStateShard NO_CULL Lnet/min
accessible field net/minecraft/client/renderer/RenderStateShard NO_DEPTH_TEST Lnet/minecraft/client/renderer/RenderStateShard$DepthTestStateShard;
accessible field net/minecraft/client/renderer/RenderStateShard VIEW_OFFSET_Z_LAYERING Lnet/minecraft/client/renderer/RenderStateShard$LayeringStateShard;
accessible field net/minecraft/server/level/ChunkMap updatingChunkMap Lit/unimi/dsi/fastutil/longs/Long2ObjectLinkedOpenHashMap;
accessible field net/minecraft/world/entity/item/FallingBlockEntity blockState Lnet/minecraft/world/level/block/state/BlockState;
extendable method net/minecraft/client/gui/screens/inventory/AbstractContainerScreen renderSlot (Lnet/minecraft/client/gui/GuiGraphics;Lnet/minecraft/world/inventory/Slot;)V
accessible method net/minecraft/server/MinecraftServer$ReloadableResources resourceManager ()Lnet/minecraft/server/packs/resources/CloseableResourceManager;
accessible method net/minecraft/world/item/BlockItem getPlaceSound (Lnet/minecraft/world/level/block/state/BlockState;)Lnet/minecraft/sounds/SoundEvent;
accessible method net/minecraft/world/level/block/Blocks never (Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/EntityType;)Ljava/lang/Boolean;
accessible method net/minecraft/world/level/block/Blocks never (Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)Z
accessible method net/minecraft/util/SortedArraySet findIndex (Ljava/lang/Object;)I
accessible method net/minecraft/util/SortedArraySet getInternal (I)Ljava/lang/Object;
accessible field net/minecraft/world/entity/item/FallingBlockEntity blockState Lnet/minecraft/world/level/block/state/BlockState;
accessible method net/minecraft/world/item/BlockItem canPlace (Lnet/minecraft/world/item/context/BlockPlaceContext;Lnet/minecraft/world/level/block/state/BlockState;)Z
Loading