Skip to content

Commit 6f4e395

Browse files
committed
disallow registering panel sync handlers late
1 parent 57b58b3 commit 6f4e395

File tree

1 file changed

+55
-16
lines changed

1 file changed

+55
-16
lines changed

src/main/java/com/cleanroommc/modularui/value/sync/PanelSyncManager.java

Lines changed: 55 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public class PanelSyncManager {
4040
private final Map<String, SlotGroup> slotGroups = new Object2ObjectOpenHashMap<>();
4141
private final Map<SyncHandler, String> reverseSyncHandlers = new Object2ObjectOpenHashMap<>();
4242
private final Map<String, SyncedAction> syncedActions = new Object2ObjectOpenHashMap<>();
43-
private final Map<String, SyncHandler> subPanels = new Object2ObjectArrayMap<>();
43+
private final Map<String, PanelSyncHandler> subPanels = new Object2ObjectArrayMap<>();
4444
private ModularSyncManager modularSyncManager;
4545
private String panelName;
4646
private boolean init = true;
@@ -69,22 +69,24 @@ public void initialize(String panelName, ModularSyncManager msm) {
6969
private void registerPanelSyncHandler(String name, SyncHandler syncHandler) {
7070
// only called on main psm
7171
SyncHandler currentSh = this.syncHandlers.get(name);
72-
if (currentSh != null && currentSh != syncHandler) throw new IllegalStateException();
72+
if (currentSh != null && currentSh != syncHandler) {
73+
throw new IllegalStateException("Failed to register panel sync handler during initialization. " +
74+
"There already exists a sync handler for the name '" + name + "'.");
75+
}
7376
String currentName = this.reverseSyncHandlers.get(syncHandler);
74-
if (currentName != null && !name.equals(currentName)) throw new IllegalStateException();
77+
if (currentName != null && !name.equals(currentName)) {
78+
throw new IllegalStateException("Failed to register panel sync handler for name '" + name + "' during initialization. " +
79+
"The panel sync handler is already registered under the name '" + currentName + "'.");
80+
}
7581
this.syncHandlers.put(name, syncHandler);
7682
this.reverseSyncHandlers.put(syncHandler, name);
7783
syncHandler.init(name, this);
7884
}
7985

8086
void closeSubPanels() {
8187
this.subPanels.values().forEach(syncHandler -> {
82-
if (syncHandler instanceof IPanelHandler panelHandler) {
83-
if (panelHandler.isSubPanel()) {
84-
panelHandler.closePanel();
85-
}
86-
} else {
87-
throw new IllegalStateException();
88+
if (syncHandler.isSubPanel()) {
89+
syncHandler.closePanel();
8890
}
8991
});
9092
}
@@ -142,7 +144,7 @@ private boolean invokeSyncedAction(String mapKey, PacketBuffer buf) {
142144
ModularUI.LOGGER.warn("SyncAction '{}' does not exist for panel '{}'!.", mapKey, panelName);
143145
return false;
144146
}
145-
if (this.allowSyncHandlerRegistration || !syncedAction.isExecuteClient() || !syncedAction.isExecuteServer()) {
147+
if (!isLocked() || this.allowSyncHandlerRegistration || !syncedAction.isExecuteClient() || !syncedAction.isExecuteServer()) {
146148
syncedAction.invoke(this.client, buf);
147149
} else {
148150
// only allow sync handler registration if it is executed on client and server
@@ -234,28 +236,65 @@ public DynamicSyncHandler dynamicSyncHandler(String key, int id, DynamicSyncHand
234236
return syncHandler;
235237
}
236238

239+
/**
240+
* @deprecated replaced by {@link #syncedPanel(String, boolean, PanelSyncHandler.IPanelBuilder)}
241+
*/
242+
@ApiStatus.ScheduledForRemoval(inVersion = "3.3.0")
243+
@Deprecated
244+
public IPanelHandler panel(String key, PanelSyncHandler.IPanelBuilder panelBuilder, boolean subPanel) {
245+
SyncHandler sh = this.subPanels.get(key);
246+
if (sh != null) return (IPanelHandler) sh;
247+
PanelSyncHandler syncHandler = new PanelSyncHandler(panelBuilder, subPanel);
248+
this.subPanels.put(key, syncHandler);
249+
return syncHandler;
250+
}
251+
237252
/**
238253
* Creates a synced panel handler. This can be used to automatically handle syncing for synced panels.
239254
* Synced panels do not need to be synced themselves, but contain at least one widget which is synced.
240-
* <p>NOTE</p>
255+
* <p><b>NOTE</b></p>
241256
* A panel sync handler is only created once. If one was already registered, that one will be returned.
242-
* (This is only relevant for nested sub panels.)
257+
* (This is only relevant for nested sub panels.) Furthermore, the panel handler has to be created on client and server with the same
258+
* key. Like any other sync handler, the panel sync handler has to be created before the panel opened. The only exception is inside
259+
* dynamic sync handlers.
243260
*
244261
* @param key the key used for syncing
245-
* @param panelBuilder the panel builder, that will create the new panel. It must not return null or any existing panels.
246262
* @param subPanel true if this panel should close when its parent closes (the parent is defined by <i>this</i> {@link PanelSyncManager})
263+
* @param panelBuilder the panel builder, that will create the new panel. It must not return null or any existing panels.
247264
* @return a synced panel handler.
248265
* @throws NullPointerException if the build panel of the builder is null
249266
* @throws IllegalArgumentException if the build panel of the builder is the main panel
267+
* @throws IllegalStateException if this method was called too late
250268
*/
251-
public IPanelHandler panel(String key, PanelSyncHandler.IPanelBuilder panelBuilder, boolean subPanel) {
252-
SyncHandler sh = this.subPanels.get(key);
253-
if (sh != null) return (IPanelHandler) sh;
269+
public IPanelHandler syncedPanel(String key, boolean subPanel, PanelSyncHandler.IPanelBuilder panelBuilder) {
270+
IPanelHandler ph = findPanelHandlerNullable(key);
271+
if (ph != null) return ph;
272+
if (isLocked() && !this.allowSyncHandlerRegistration) {
273+
// registration of sync handlers forbidden
274+
throw new IllegalStateException("Synced panels must be registered during panel building. The only exceptions is via a DynamicSyncHandler and sync functions!");
275+
}
254276
PanelSyncHandler syncHandler = new PanelSyncHandler(panelBuilder, subPanel);
255277
this.subPanels.put(key, syncHandler);
278+
if (isInitialised() && (this == this.modularSyncManager.getMainPSM() ||
279+
this.modularSyncManager.getMainPSM().findSyncHandlerNullable(this.panelName, PanelSyncHandler.class) == null)) {
280+
// current panel is open
281+
this.modularSyncManager.getMainPSM().registerPanelSyncHandler(key, syncHandler);
282+
}
256283
return syncHandler;
257284
}
258285

286+
public @Nullable IPanelHandler findPanelHandlerNullable(String key) {
287+
return this.subPanels.get(key);
288+
}
289+
290+
public @NotNull IPanelHandler findPanelHandler(String key) {
291+
IPanelHandler panelHandler = findPanelHandlerNullable(key);
292+
if (panelHandler == null) {
293+
throw new NoSuchElementException("Expected to find panel sync handler with key '" + key + "', but none was found.");
294+
}
295+
return panelHandler;
296+
}
297+
259298
public PanelSyncManager registerSlotGroup(SlotGroup slotGroup) {
260299
if (!slotGroup.isSingleton()) {
261300
this.slotGroups.put(slotGroup.getName(), slotGroup);

0 commit comments

Comments
 (0)