Skip to content
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ default MultiblockControllerMachine self() {

/**
* Check MultiBlock Pattern. Just checking pattern without any other logic.
* You can override it but it's unsafe for calling. because it will also be called in an async thread.
* You can override it, but direct calls are unsafe because multiple lifecycle paths may request a check.
* <br>
* you should always use {@link IMultiController#checkPatternWithLock()} and
* {@link IMultiController#checkPatternWithTryLock()} instead.
Expand Down Expand Up @@ -91,24 +91,78 @@ default BlockPattern getPattern() {
}

/**
* Whether Multiblock Formed.
* <br>
* NOTE: even machine is formed, it doesn't mean to workable!
* Its parts maybe invalid due to chunk unload.
* Whether the multiblock is currently safe to expose as formed to gameplay code. Implementations with deferred
* validation should return false while that validation is pending.
*/
boolean isFormed();

/**
* The last successfully persisted or observed formation state, including while transient revalidation is pending.
*/
boolean isStructureFormedSnapshot();

/**
* The mirrored orientation owned by the last completed structure validation.
*/
boolean isStructureFlippedSnapshot();

/**
* Whether this controller is waiting for a full, server-thread structure validation.
* <p>
* This is deliberately separate from {@link #isStructureFormedSnapshot()}: a controller may retain its formation
* snapshot while one of its structure chunks is temporarily unavailable, but it must not operate until validation
* succeeds.
*/
boolean isStructureRevalidationPending();

/**
* Update the transient structure-validation state. Implementations must pause and resume work subscriptions when
* this value changes.
*/
void setStructureRevalidationPending(boolean pending);

/**
* Whether the structure is both formed and fully validated for operation.
*/
default boolean isStructureOperational() {
return isStructureFormedSnapshot() && !isStructureRevalidationPending();
}

/**
* Stable identity for the controller's current structure-ownership epoch. A definitive invalidation retires the
* epoch, while transient unloads retain it; the next successful formation receives a newer identity. Zero means
* no ownership epoch has been assigned. Callers must pair it with {@code self().getPos()}.
*/
long getStructureInstanceId();

/**
* Assign a persistent ownership-epoch identity.
*/
void setStructureInstanceId(long instanceId);

/**
* Called after this exact controller state has been installed in the world mapping. Controllers persist the
* participating chunk set so their first post-restart validation cannot select another geometry while an old
* structure chunk is unavailable.
*/
void onStructureMappingInstalled(long[] mappedChunks);

/**
* Snapshot of chunks owned by the last confirmed structure validation. Schedulers use this to wait for the exact
* unloaded chunks without requesting them.
*/
long[] getConfirmedStructureChunks();

/**
* Get MultiblockState. It records all structure-related information.
*/
@NotNull
MultiblockState getMultiblockState();

/**
* Called in an async thread. It's unsafe, Don't modify anything of world but checking information.
* It will be called per 5 tick.
* Called on the server thread for controllers waiting to form or recover from an unloaded chunk.
*
* @param periodID period Tick
* @param periodID current level tick counter
*/
void asyncCheckPattern(long periodID);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ default boolean canShared() {
*/
boolean hasController(BlockPos controllerPos);

/**
* Whether this part belongs to this exact controller ownership epoch.
*/
boolean hasController(IMultiController controller);

/**
* Whether it belongs to a formed Multiblock.
*/
Expand All @@ -52,6 +57,18 @@ default boolean canShared() {
*/
void removedFromController(IMultiController controller);

/**
* Unlink a controller whose block entity is unloading without treating the structure as broken.
*/
void unloadedFromController(IMultiController controller);

/**
* Called after a persisted controller binding is known to have ended definitively (structure invalidation,
* controller retirement, or replacement by a newer ownership epoch). Transient chunk unloads never invoke this
* hook.
*/
default void onControllerBindingRetired(BlockPos controllerPos, long instanceId) {}

/**
* Called when it was added to a multiblock.
*/
Expand Down
Loading