Skip to content
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
8 changes: 8 additions & 0 deletions src/main/java/com/cleanroommc/modularui/CommonProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import net.minecraftforge.fml.common.registry.EntityEntry;
import net.minecraftforge.fml.common.registry.EntityEntryBuilder;
import net.minecraftforge.fml.relauncher.Side;
Expand Down Expand Up @@ -81,4 +82,11 @@ public void onConfigChange(ConfigChangedEvent.OnConfigChangedEvent event) {
ConfigManager.sync(ModularUI.ID, Config.Type.INSTANCE);
}
}

@SubscribeEvent
public static void onTick(TickEvent.PlayerTickEvent event) {
if (event.player.openContainer instanceof ModularContainer container) {
container.onUpdate();
}
}
}
13 changes: 13 additions & 0 deletions src/main/java/com/cleanroommc/modularui/api/IPacketWriter.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package com.cleanroommc.modularui.api;

import io.netty.buffer.Unpooled;

import net.minecraft.network.PacketBuffer;

import java.io.IOException;

/**
* A function that can write any data to an {@link PacketBuffer}.
*/
@FunctionalInterface
public interface IPacketWriter {

/**
Expand All @@ -16,4 +19,14 @@ public interface IPacketWriter {
* @throws IOException if data can not be written for some reason
*/
void write(PacketBuffer buffer) throws IOException;

default PacketBuffer toPacket() {
PacketBuffer buffer = new PacketBuffer(Unpooled.buffer());
try {
write(buffer);
} catch (IOException e) {
throw new RuntimeException(e);
}
return buffer;
}
}
13 changes: 13 additions & 0 deletions src/main/java/com/cleanroommc/modularui/api/ISyncedAction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.cleanroommc.modularui.api;

import net.minecraft.network.PacketBuffer;

import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;

@FunctionalInterface
public interface ISyncedAction {

@ApiStatus.OverrideOnly
void invoke(@NotNull PacketBuffer packet);
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ default W getThis() {
* Called when this widget gets initialised or when this widget is added to the gui
*
* @param syncManager sync manager
* @param late
*/
void initialiseSyncHandler(ModularSyncManager syncManager);
void initialiseSyncHandler(ModularSyncManager syncManager, boolean late);

/**
* Checks if the received sync handler is valid for this widget.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ public interface IWidget extends IGuiElement {
* This element now becomes valid
*
* @param parent the parent this element belongs to
* @param late true if this is called some time after the widget tree of the parent has been initialised
*/
void initialise(@NotNull IWidget parent);
void initialise(@NotNull IWidget parent, boolean late);

/**
* Invalidates this element.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public static <T extends GuiData> void open(@NotNull UIFactory<T> factory, @NotN
// create panel, collect sync handlers and create container
UISettings settings = new UISettings(JeiSettings.DUMMY);
settings.defaultCanInteractWith(factory, guiData);
PanelSyncManager syncManager = new PanelSyncManager();
PanelSyncManager syncManager = new PanelSyncManager(false);
ModularPanel panel = factory.createPanel(guiData, syncManager, settings);
WidgetTree.collectSyncValues(syncManager, panel);
ModularContainer container = settings.hasContainer() ? settings.createContainer() : factory.createContainer();
Expand All @@ -100,7 +100,7 @@ public static <T extends GuiData> void openFromClient(int windowId, @NotNull UIF
T guiData = factory.readGuiData(player, data);
UISettings settings = new UISettings();
settings.defaultCanInteractWith(factory, guiData);
PanelSyncManager syncManager = new PanelSyncManager();
PanelSyncManager syncManager = new PanelSyncManager(true);
ModularPanel panel = factory.createPanel(guiData, syncManager, settings);
WidgetTree.collectSyncValues(syncManager, panel);
ModularScreen screen = factory.createScreen(guiData, panel);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package com.cleanroommc.modularui.network.packets;

import com.cleanroommc.modularui.ModularUI;
import com.cleanroommc.modularui.network.IPacket;
import com.cleanroommc.modularui.network.NetworkUtils;
import com.cleanroommc.modularui.screen.ModularContainer;
import com.cleanroommc.modularui.screen.ModularScreen;

import com.cleanroommc.modularui.value.sync.ModularSyncManager;

import net.minecraft.client.network.NetHandlerPlayClient;
import net.minecraft.inventory.Container;
import net.minecraft.network.NetHandlerPlayServer;
Expand All @@ -18,12 +21,12 @@ public class PacketSyncHandler implements IPacket {

private String panel;
private String key;
private boolean action;
private PacketBuffer packet;

public PacketSyncHandler() {
}
public PacketSyncHandler() {}

public PacketSyncHandler(String panel, String key, PacketBuffer packet) {
public PacketSyncHandler(String panel, String key, boolean action, PacketBuffer packet) {
this.panel = panel;
this.key = key;
this.packet = packet;
Expand All @@ -33,25 +36,23 @@ public PacketSyncHandler(String panel, String key, PacketBuffer packet) {
public void write(PacketBuffer buf) {
NetworkUtils.writeStringSafe(buf, this.panel);
NetworkUtils.writeStringSafe(buf, this.key, 64, true);
buf.writeBoolean(this.action);
NetworkUtils.writeByteBuf(buf, this.packet);
}

@Override
public void read(PacketBuffer buf) {
this.panel = NetworkUtils.readStringSafe(buf);
this.key = NetworkUtils.readStringSafe(buf);
this.action = buf.readBoolean();
this.packet = NetworkUtils.readPacketBuffer(buf);
}

@Override
public @Nullable IPacket executeClient(NetHandlerPlayClient handler) {
ModularScreen screen = ModularScreen.getCurrent();
if (screen != null) {
try {
screen.getSyncManager().receiveWidgetUpdate(this.panel, this.key, this.packet.readVarInt(), this.packet);
} catch (IOException e) {
throw new RuntimeException(e);
}
execute(screen.getSyncManager());
}
return null;
}
Expand All @@ -60,12 +61,19 @@ public void read(PacketBuffer buf) {
public @Nullable IPacket executeServer(NetHandlerPlayServer handler) {
Container container = handler.player.openContainer;
if (container instanceof ModularContainer modularContainer) {
try {
modularContainer.getSyncManager().receiveWidgetUpdate(this.panel, this.key, this.packet.readVarInt(), this.packet);
} catch (IOException e) {
throw new RuntimeException(e);
}
execute(modularContainer.getSyncManager());
}
return null;
}

private void execute(ModularSyncManager syncManager) {
try {
int id = this.action ? 0 : this.packet.readVarInt();
syncManager.receiveWidgetUpdate(this.panel, this.key, this.action, id, this.packet);
} catch (IndexOutOfBoundsException e) {
ModularUI.LOGGER.error("Failed to read packet for sync handler {} in panel {}", this.key, this.panel);
} catch (IOException e) {
ModularUI.LOGGER.throwing(e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,14 @@ public void detectAndSendChanges() {
this.init = false;
}

@ApiStatus.Internal
public void onUpdate() {
// detectAndSendChanges is potentially called multiple times per tick, while this method is called exactly once per tick
if (this.syncManager != null) {
this.syncManager.onUpdate();
}
}

private void sortShiftClickSlots() {
this.shiftClickSlots.sort(Comparator.comparingInt(slot -> Objects.requireNonNull(slot.getSlotGroup()).getShiftClickPriority()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ public boolean canHover() {
public void onOpen(ModularScreen screen) {
this.screen = screen;
getArea().z(1);
initialise(this);
initialise(this, false);
// call first tick after everything is initialised
WidgetTree.onUpdate(this);
if (!isMainPanel() && shouldAnimate()) {
Expand Down
76 changes: 65 additions & 11 deletions src/main/java/com/cleanroommc/modularui/test/TestTile.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.cleanroommc.modularui.drawable.Rectangle;
import com.cleanroommc.modularui.drawable.text.AnimatedText;
import com.cleanroommc.modularui.factory.PosGuiData;
import com.cleanroommc.modularui.network.NetworkUtils;
import com.cleanroommc.modularui.screen.ModularPanel;
import com.cleanroommc.modularui.screen.RichTooltip;
import com.cleanroommc.modularui.screen.UISettings;
Expand All @@ -20,10 +21,13 @@
import com.cleanroommc.modularui.value.BoolValue;
import com.cleanroommc.modularui.value.IntValue;
import com.cleanroommc.modularui.value.StringValue;
import com.cleanroommc.modularui.value.sync.DynamicSyncHandler;
import com.cleanroommc.modularui.value.sync.GenericSyncValue;
import com.cleanroommc.modularui.value.sync.IntSyncValue;
import com.cleanroommc.modularui.value.sync.ItemSlotSH;
import com.cleanroommc.modularui.value.sync.PanelSyncManager;
import com.cleanroommc.modularui.value.sync.SyncHandlers;
import com.cleanroommc.modularui.widget.EmptyWidget;
import com.cleanroommc.modularui.widget.ParentWidget;
import com.cleanroommc.modularui.widgets.*;
import com.cleanroommc.modularui.widgets.layout.Column;
Expand All @@ -32,6 +36,10 @@
import com.cleanroommc.modularui.widgets.slot.*;
import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget;

import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;

import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
Expand All @@ -48,12 +56,22 @@

import java.util.Collection;
import java.util.Random;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;

public class TestTile extends TileEntity implements IGuiHolder<PosGuiData>, ITickable {

private static final Object2IntMap<Item> handlerSizeMap = new Object2IntOpenHashMap<>() {{
put(Items.DIAMOND, 9);
put(Items.EMERALD, 9);
put(Items.GOLD_INGOT, 7);
put(Items.IRON_INGOT, 6);
put(Items.CLAY_BALL, 2);
defaultReturnValue(3);
}};

private final FluidTank fluidTank = new FluidTank(10000);
private final FluidTank fluidTankPhantom = new FluidTank(Integer.MAX_VALUE);
private long time = 0;
Expand All @@ -78,26 +96,44 @@ public int getSlotLimit(int slot) {
private final FluidTank mixerFluids1 = new FluidTank(16000);
private final FluidTank mixerFluids2 = new FluidTank(16000);
private final ItemStackHandler craftingInventory = new ItemStackHandler(10);
private final ItemStackHandler storageInventory0 = new ItemStackHandler(1);
private final Map<Item, ItemStackHandler> stackHandlerMap = new Object2ObjectOpenHashMap<>();

private int num = 2;

@Override
public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager, UISettings settings) {
public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager syncManager, UISettings settings) {
settings.customContainer(() -> new CraftingModularContainer(3, 3, this.craftingInventory));

guiSyncManager.registerSlotGroup("item_inv", 3);
guiSyncManager.registerSlotGroup("mixer_items", 2);
syncManager.registerSlotGroup("item_inv", 3);
syncManager.registerSlotGroup("mixer_items", 2);

guiSyncManager.syncValue("mixer_fluids", 0, SyncHandlers.fluidSlot(this.mixerFluids1));
guiSyncManager.syncValue("mixer_fluids", 1, SyncHandlers.fluidSlot(this.mixerFluids2));
syncManager.syncValue("mixer_fluids", 0, SyncHandlers.fluidSlot(this.mixerFluids1));
syncManager.syncValue("mixer_fluids", 1, SyncHandlers.fluidSlot(this.mixerFluids2));
IntSyncValue cycleStateValue = new IntSyncValue(() -> this.cycleState, val -> this.cycleState = val);
guiSyncManager.syncValue("cycle_state", cycleStateValue);
guiSyncManager.syncValue("display_item", GenericSyncValue.forItem(() -> this.displayItem, null));
guiSyncManager.bindPlayerInventory(guiData.getPlayer());
syncManager.syncValue("cycle_state", cycleStateValue);
syncManager.syncValue("display_item", GenericSyncValue.forItem(() -> this.displayItem, null));
syncManager.bindPlayerInventory(guiData.getPlayer());

DynamicSyncHandler dynamicSyncHandler = new DynamicSyncHandler()
.widgetProvider((syncManager1, packet) -> {
ItemStack itemStack = NetworkUtils.readItemStack(packet);
if (itemStack.isEmpty()) return new EmptyWidget();
Item item = itemStack.getItem();
ItemStackHandler handler = stackHandlerMap.computeIfAbsent(item, k -> new ItemStackHandler(handlerSizeMap.getInt(k)));
String name = item.getRegistryName().toString();
Flow flow = Flow.row();
for (int i = 0; i < handler.getSlots(); i++) {
int finalI = i;
flow.child(new ItemSlot()
.syncHandler(syncManager1.getOrCreateSyncHandler(name, i, ItemSlotSH.class, () -> new ItemSlotSH(new ModularSlot(handler, finalI)))));
}
return flow;
});

Rectangle colorPickerBackground = new Rectangle().setColor(Color.RED.main);
ModularPanel panel = new ModularPanel("test_tile");
IPanelHandler panelSyncHandler = guiSyncManager.panel("other_panel", this::openSecondWindow, true);
IPanelHandler panelSyncHandler = syncManager.panel("other_panel", this::openSecondWindow, true);
IPanelHandler colorPicker = IPanelHandler.simple(panel, (mainPanel, player) -> new ColorPickerDialog(colorPickerBackground::setColor, colorPickerBackground.getColor(), true)
.setDraggable(true)
.relative(panel)
Expand All @@ -117,7 +153,10 @@ public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager,
.child(new PageButton(1, tabController)
.tab(GuiTextures.TAB_TOP, 0))
.child(new PageButton(2, tabController)
.tab(GuiTextures.TAB_TOP, 0)))
.tab(GuiTextures.TAB_TOP, 0))
.child(new PageButton(3, tabController)
.tab(GuiTextures.TAB_TOP, 0)
.overlay(new ItemDrawable(Blocks.CHEST).asIcon())))
.child(new Expandable()
.debugName("expandable")
.top(0)
Expand Down Expand Up @@ -368,7 +407,22 @@ public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager,
.size(14, 14))
.child(IKey.lang("bogosort.gui.enabled").asWidget()
.height(14)))))
))
.addPage(new ParentWidget<>()
.debugName("page 4 storage")
.sizeRel(1f)
.child(new Column()
.padding(7)
.child(new ItemSlot()
.slot(new ModularSlot(this.storageInventory0, 0)
.changeListener(((newItem, onlyAmountChanged, client, init) -> {
if (client && !onlyAmountChanged) {
dynamicSyncHandler.notifyUpdate(packet -> NetworkUtils.writeItemStack(packet, newItem));
}
}))))
.child(new DynamicSyncedWidget<>()
.widthRel(1f)
.syncHandler(dynamicSyncHandler)))
)))
.child(SlotGroupWidget.playerInventory(false))
);
/*panel.child(new ButtonWidget<>()
Expand Down
Loading