@@ -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