diff --git a/examples/minestom/src/main/kotlin/me/devnatan/inventoryframework/runtime/command/IFExampleCommand.kt b/examples/minestom/src/main/kotlin/me/devnatan/inventoryframework/runtime/command/IFExampleCommand.kt index be5bd477c..e81a44933 100644 --- a/examples/minestom/src/main/kotlin/me/devnatan/inventoryframework/runtime/command/IFExampleCommand.kt +++ b/examples/minestom/src/main/kotlin/me/devnatan/inventoryframework/runtime/command/IFExampleCommand.kt @@ -3,6 +3,7 @@ package me.devnatan.inventoryframework.runtime.command import me.devnatan.inventoryframework.ViewFrame import me.devnatan.inventoryframework.runtime.view.Failing import me.devnatan.inventoryframework.runtime.view.ScheduledView +import me.devnatan.inventoryframework.runtime.view.ScheduledViewAdvanced import me.devnatan.inventoryframework.runtime.view.SimplePagination import net.minestom.server.command.CommandSender import net.minestom.server.command.builder.Command @@ -20,6 +21,7 @@ class IFExampleCommand( "failing" to Failing::class.java, "simple-pagination" to SimplePagination::class.java, "scheduled" to ScheduledView::class.java, + "scheduled-advanced" to ScheduledViewAdvanced::class.java, ) private val arg: Argument = diff --git a/examples/minestom/src/main/kotlin/me/devnatan/inventoryframework/runtime/view/ScheduledViewAdvanced.kt b/examples/minestom/src/main/kotlin/me/devnatan/inventoryframework/runtime/view/ScheduledViewAdvanced.kt new file mode 100644 index 000000000..9a54e188f --- /dev/null +++ b/examples/minestom/src/main/kotlin/me/devnatan/inventoryframework/runtime/view/ScheduledViewAdvanced.kt @@ -0,0 +1,36 @@ +package me.devnatan.inventoryframework.runtime.view + +import me.devnatan.inventoryframework.View +import me.devnatan.inventoryframework.ViewConfigBuilder +import me.devnatan.inventoryframework.context.Context +import me.devnatan.inventoryframework.context.RenderContext +import me.devnatan.inventoryframework.context.SlotClickContext +import me.devnatan.inventoryframework.runtime.ExampleUtil +import me.devnatan.inventoryframework.state.timerState +import net.minestom.server.item.Material +import kotlin.time.Duration.Companion.seconds + +class ScheduledViewAdvanced : View() { + val counter = mutableState(0) + val timer = timerState(1.seconds) + + override fun onInit(config: ViewConfigBuilder): Unit = + with(config) { + cancelOnClick() + size(3) + title("Simple Pagination") + layout(" ", " C ", "B ") + scheduleUpdate(timer) + } + + override fun onFirstRender(render: RenderContext) { + render.layoutSlot('C').onRender { + it.item = ExampleUtil.displayItem(Material.STONE, counter.increment(it).toString()) + } + + render + .layoutSlot('B', ExampleUtil.displayItem(Material.PAPER, "Back")) + .displayIf(Context::canBack) + .onClick(SlotClickContext::back) + } +} diff --git a/examples/paper/src/main/java/me/devnatan/inventoryframework/runtime/SamplePlugin.java b/examples/paper/src/main/java/me/devnatan/inventoryframework/runtime/SamplePlugin.java index 57c94c90b..cf7aa5b64 100644 --- a/examples/paper/src/main/java/me/devnatan/inventoryframework/runtime/SamplePlugin.java +++ b/examples/paper/src/main/java/me/devnatan/inventoryframework/runtime/SamplePlugin.java @@ -17,7 +17,12 @@ public class SamplePlugin extends JavaPlugin { public void onEnable() { ViewFrame viewFrame = ViewFrame.create(this) .install(AnvilInputFeature.AnvilInput) - .with(new AnvilInputSample(), new Failing(), new SimplePagination(), new AutoUpdate()) + .with( + new AnvilInputSample(), + new Failing(), + new SimplePagination(), + new AutoUpdate(), + new TimerSample()) .register(); IFExampleCommandExecutor command = new IFExampleCommandExecutor(viewFrame); diff --git a/examples/paper/src/main/java/me/devnatan/inventoryframework/runtime/commands/IFExampleCommandExecutor.java b/examples/paper/src/main/java/me/devnatan/inventoryframework/runtime/commands/IFExampleCommandExecutor.java index aa9fd9efd..db9bfc10b 100644 --- a/examples/paper/src/main/java/me/devnatan/inventoryframework/runtime/commands/IFExampleCommandExecutor.java +++ b/examples/paper/src/main/java/me/devnatan/inventoryframework/runtime/commands/IFExampleCommandExecutor.java @@ -1,6 +1,7 @@ package me.devnatan.inventoryframework.runtime.commands; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import me.devnatan.inventoryframework.View; @@ -9,6 +10,7 @@ import me.devnatan.inventoryframework.runtime.view.AutoUpdate; import me.devnatan.inventoryframework.runtime.view.Failing; import me.devnatan.inventoryframework.runtime.view.SimplePagination; +import me.devnatan.inventoryframework.runtime.view.TimerSample; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; @@ -19,11 +21,15 @@ public class IFExampleCommandExecutor implements CommandExecutor, TabCompleter { - private static final Map> views = Map.of( - "anvil", AnvilInputSample.class, - "failing", Failing.class, - "simple-pagination", SimplePagination.class, - "auto-update", AutoUpdate.class); + private static final Map> views = new HashMap<>(); + + static { + views.put("anvil", AnvilInputSample.class); + views.put("failing", Failing.class); + views.put("simple-pagination", SimplePagination.class); + views.put("auto-update", AutoUpdate.class); + views.put("timer", TimerSample.class); + } private final ViewFrame viewFrame; diff --git a/examples/paper/src/main/java/me/devnatan/inventoryframework/runtime/view/TimerSample.java b/examples/paper/src/main/java/me/devnatan/inventoryframework/runtime/view/TimerSample.java new file mode 100644 index 000000000..63c483bf3 --- /dev/null +++ b/examples/paper/src/main/java/me/devnatan/inventoryframework/runtime/view/TimerSample.java @@ -0,0 +1,91 @@ +package me.devnatan.inventoryframework.runtime.view; + +import me.devnatan.inventoryframework.View; +import me.devnatan.inventoryframework.ViewConfigBuilder; +import me.devnatan.inventoryframework.context.Context; +import me.devnatan.inventoryframework.context.RenderContext; +import me.devnatan.inventoryframework.context.SlotClickContext; +import me.devnatan.inventoryframework.context.SlotRenderContext; +import me.devnatan.inventoryframework.state.MutableIntState; +import me.devnatan.inventoryframework.state.timer.Timer; +import me.devnatan.inventoryframework.state.timer.TimerState; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; + +import java.util.Arrays; + +public class TimerSample extends View { + + private final MutableIntState countState = mutableState(0); + private final TimerState timerState = timerState(20); + + @Override + public void onInit(@NotNull ViewConfigBuilder config) { + config.cancelOnClick().title("Timer (?)").scheduleUpdate(timerState); + } + + @Override + public void onFirstRender(@NotNull RenderContext render) { + render.firstSlot() + .onRender(this::onClockItemRender) + .onClick(this::onClockItemClick) + .updateOnStateChange(timerState); + + render.lastSlot() + .renderWith(() -> createIntervalItem(timerState.get(render))) + .onClick(this::onIntervalItemClicked) + .updateOnStateChange(timerState); + } + + @Override + public void onUpdate(@NotNull Context update) { + final int count = countState.increment(update); + final String pause = timerState.get(update).isPaused() ? "paused" : "running"; + update.updateTitleForPlayer(String.format("Timer (%d) [%b]", count, pause)); + } + + private void onIntervalItemClicked(SlotClickContext click) { + final Timer timer = timerState.get(click); + final long newInterval = (timer.currentInterval() + 1) % 20; + + click.getPlayer().sendMessage(String.format( + "Timer interval changed from %d to %d ticks", + timer.currentInterval(), newInterval + )); + timer.changeInterval(newInterval); + } + + private static @NotNull ItemStack createIntervalItem(Timer timer) { + final long intervalInSeconds = Math.max(timer.currentInterval(), 1) / 20L; // ticks to seconds + final ItemStack item = new ItemStack(Material.ARROW, (int) intervalInSeconds); + final ItemMeta meta = item.getItemMeta(); + meta.setDisplayName("Current clock interval"); + meta.setLore(Arrays.asList("Initial: " + timer.initialInterval(), "Current: " + timer.currentInterval())); + item.setItemMeta(meta); + + return item; + } + + private void onClockItemRender(SlotRenderContext context) { + final Timer timer = timerState.get(context); + + final ItemStack stack = new ItemStack(Material.CLOCK); + final ItemMeta meta = stack.getItemMeta(); + meta.setDisplayName("Timer"); + meta.setLore(Arrays.asList(timer.isPaused() ? "Click to unpause" : "Click to pause")); + stack.setItemMeta(meta); + + context.setItem(stack); + } + + private void onClockItemClick(SlotClickContext context) { + final Timer timer = timerState.get(context); + if (timer.pause()) { + context.getPlayer().sendMessage("Paused"); + } else { + context.getPlayer().sendMessage("Unpaused"); + } + } +} diff --git a/inventory-framework-api/src/main/java/me/devnatan/inventoryframework/ViewConfigBuilder.java b/inventory-framework-api/src/main/java/me/devnatan/inventoryframework/ViewConfigBuilder.java index 930cae428..f6c08f713 100644 --- a/inventory-framework-api/src/main/java/me/devnatan/inventoryframework/ViewConfigBuilder.java +++ b/inventory-framework-api/src/main/java/me/devnatan/inventoryframework/ViewConfigBuilder.java @@ -8,6 +8,7 @@ import java.util.Set; import java.util.stream.Collectors; import me.devnatan.inventoryframework.exception.InvalidLayoutException; +import me.devnatan.inventoryframework.state.timer.TimerState; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; @@ -31,6 +32,7 @@ public final class ViewConfigBuilder { private String[] layout = null; private final Set modifiers = new HashSet<>(); private long updateIntervalInTicks, interactionDelayInMillis; + private TimerState updateIntervalState; private boolean transitiveInitialData; /** @@ -200,6 +202,19 @@ public ViewConfigBuilder scheduleUpdate(long intervalInTicks) { return this; } + /** + * Schedules the view to update every fixed interval. + * + * @param timerState The + * @return This configuration builder. + * @see Scheduled Updates on Wiki + */ + @ApiStatus.Experimental + public ViewConfigBuilder scheduleUpdate(TimerState timerState) { + this.updateIntervalState = timerState; + return this; + } + /** * Waits a fixed delay before any player interaction. *

diff --git a/inventory-framework-api/src/main/java/me/devnatan/inventoryframework/internal/ElementFactory.java b/inventory-framework-api/src/main/java/me/devnatan/inventoryframework/internal/ElementFactory.java index 97de9a70a..2f4a71260 100644 --- a/inventory-framework-api/src/main/java/me/devnatan/inventoryframework/internal/ElementFactory.java +++ b/inventory-framework-api/src/main/java/me/devnatan/inventoryframework/internal/ElementFactory.java @@ -17,6 +17,7 @@ import me.devnatan.inventoryframework.context.IFSlotClickContext; import me.devnatan.inventoryframework.context.IFSlotRenderContext; import me.devnatan.inventoryframework.logging.Logger; +import me.devnatan.inventoryframework.state.timer.TimerState; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -89,4 +90,6 @@ public abstract IFCloseContext createCloseContext( public abstract boolean worksInCurrentPlatform(); public abstract Job scheduleJobInterval(@NotNull RootView root, long intervalInTicks, @NotNull Runnable execution); + + public abstract TimerState createTimerState(long stateId, long intervalInTicks); } diff --git a/inventory-framework-api/src/main/java/me/devnatan/inventoryframework/state/StateAccess.java b/inventory-framework-api/src/main/java/me/devnatan/inventoryframework/state/StateAccess.java index a9eac47d4..27b00a547 100644 --- a/inventory-framework-api/src/main/java/me/devnatan/inventoryframework/state/StateAccess.java +++ b/inventory-framework-api/src/main/java/me/devnatan/inventoryframework/state/StateAccess.java @@ -11,6 +11,7 @@ import me.devnatan.inventoryframework.component.PaginationValueConsumer; import me.devnatan.inventoryframework.context.IFContext; import me.devnatan.inventoryframework.context.IFOpenContext; +import me.devnatan.inventoryframework.state.timer.TimerState; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; @@ -173,6 +174,19 @@ public interface StateAccess< */ MutableState initialState(@NotNull String key); + /** + * Creates a new unmodifiable timer state. + * + * @param intervalInTicks Ticks to schedule the timer to run. + *

+ * This API is experimental and is not subject to the general compatibility guarantees + * such API may be changed or may be removed completely in any further release. + * + * @return A new unmodifiable timer state. + */ + @ApiStatus.Experimental + TimerState timerState(long intervalInTicks); + /** * Creates a new immutable pagination with static data source. * diff --git a/inventory-framework-api/src/main/java/me/devnatan/inventoryframework/state/timer/Timer.java b/inventory-framework-api/src/main/java/me/devnatan/inventoryframework/state/timer/Timer.java new file mode 100644 index 000000000..cff7a0221 --- /dev/null +++ b/inventory-framework-api/src/main/java/me/devnatan/inventoryframework/state/timer/Timer.java @@ -0,0 +1,16 @@ +package me.devnatan.inventoryframework.state.timer; + +public interface Timer { + + void loop(); + + long initialInterval(); + + long currentInterval(); + + void changeInterval(long interval); + + boolean isPaused(); + + boolean pause(); +} \ No newline at end of file diff --git a/inventory-framework-api/src/main/java/me/devnatan/inventoryframework/state/timer/TimerState.java b/inventory-framework-api/src/main/java/me/devnatan/inventoryframework/state/timer/TimerState.java new file mode 100644 index 000000000..9c7652c38 --- /dev/null +++ b/inventory-framework-api/src/main/java/me/devnatan/inventoryframework/state/timer/TimerState.java @@ -0,0 +1,6 @@ +package me.devnatan.inventoryframework.state.timer; + +import me.devnatan.inventoryframework.state.State; + +public interface TimerState extends State { +} diff --git a/inventory-framework-api/src/main/kotlin/me/devnatan/inventoryframework/state/StateAccess.kt b/inventory-framework-api/src/main/kotlin/me/devnatan/inventoryframework/state/StateAccess.kt new file mode 100644 index 000000000..765f3b12e --- /dev/null +++ b/inventory-framework-api/src/main/kotlin/me/devnatan/inventoryframework/state/StateAccess.kt @@ -0,0 +1,6 @@ +package me.devnatan.inventoryframework.state + +import me.devnatan.inventoryframework.state.timer.TimerState +import kotlin.time.Duration + +public fun StateAccess<*, *>.timerState(interval: Duration): TimerState = timerState(interval.inWholeSeconds / 20) diff --git a/inventory-framework-core/src/main/java/me/devnatan/inventoryframework/state/StateAccessImpl.java b/inventory-framework-core/src/main/java/me/devnatan/inventoryframework/state/StateAccessImpl.java index c1783fb87..3d199d980 100644 --- a/inventory-framework-core/src/main/java/me/devnatan/inventoryframework/state/StateAccessImpl.java +++ b/inventory-framework-core/src/main/java/me/devnatan/inventoryframework/state/StateAccessImpl.java @@ -14,6 +14,7 @@ import me.devnatan.inventoryframework.component.PaginationValueConsumer; import me.devnatan.inventoryframework.context.IFContext; import me.devnatan.inventoryframework.internal.ElementFactory; +import me.devnatan.inventoryframework.state.timer.TimerState; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; @@ -39,7 +40,7 @@ public StateAccessImpl( } @Override - public final State state(T initialValue) { + public State state(T initialValue) { final long id = State.next(); final StateValueFactory factory = (host, state) -> new ImmutableValue(state, initialValue); final State state = new BaseState<>(id, factory); @@ -49,7 +50,7 @@ public final State state(T initialValue) { } @Override - public final MutableState mutableState(T initialValue) { + public MutableState mutableState(T initialValue) { final long id = State.next(); final StateValueFactory factory = (host, state) -> new MutableValue(state, initialValue); final MutableState state = new MutableGenericStateImpl<>(id, factory); @@ -59,7 +60,7 @@ public final MutableState mutableState(T initialValue) { } @Override - public final MutableIntState mutableState(int initialValue) { + public MutableIntState mutableState(int initialValue) { final long id = State.next(); final StateValueFactory factory = (host, state) -> new MutableValue(state, initialValue); final MutableIntState state = new MutableIntStateImpl(id, factory); @@ -69,7 +70,7 @@ public final MutableIntState mutableState(int initialValue) { } @Override - public final State computedState(@NotNull Function computation) { + public State computedState(@NotNull Function computation) { final long id = State.next(); @SuppressWarnings("unchecked") final StateValueFactory factory = @@ -81,7 +82,7 @@ public final State computedState(@NotNull Function computatio } @Override - public final State computedState(@NotNull Supplier computation) { + public State computedState(@NotNull Supplier computation) { final long id = State.next(); final StateValueFactory factory = (host, state) -> new ComputedValue(state, computation); final State state = new BaseState<>(id, factory); @@ -91,7 +92,7 @@ public final State computedState(@NotNull Supplier computation) { } @Override - public final State lazyState(@NotNull Function computation) { + public State lazyState(@NotNull Function computation) { final long id = State.next(); @SuppressWarnings("unchecked") final StateValueFactory factory = @@ -103,7 +104,7 @@ public final State lazyState(@NotNull Function computation) { } @Override - public final State lazyState(@NotNull Supplier computation) { + public State lazyState(@NotNull Supplier computation) { final long id = State.next(); final StateValueFactory factory = (host, state) -> new LazyValue(state, computation); final State state = new BaseState<>(id, factory); @@ -114,13 +115,13 @@ public final State lazyState(@NotNull Supplier computation) { @SuppressWarnings("DataFlowIssue") @Override - public final MutableState initialState() { + public MutableState initialState() { return initialState(null); } @SuppressWarnings("NullableProblems") @Override - public final MutableState initialState(@NotNull String key) { + public MutableState initialState(@NotNull String key) { final long id = State.next(); final MutableState state = new BaseMutableState<>(id, (host, valueState) -> new InitialDataStateValue(valueState, host, key)); @@ -130,7 +131,14 @@ public final MutableState initialState(@NotNull String key) { } @Override - public final State paginationState( + public TimerState timerState(long intervalInTicks) { + final TimerState state = elementFactory.createTimerState(State.next(), intervalInTicks); + this.stateRegistry.registerState(state, this); + return state; + } + + @Override + public State paginationState( @NotNull List sourceProvider, @NotNull PaginationValueConsumer elementConsumer) { return this.buildPaginationState(sourceProvider) @@ -139,7 +147,7 @@ public final State paginationState( } @Override - public final State computedPaginationState( + public State computedPaginationState( @NotNull Function> sourceProvider, @NotNull PaginationValueConsumer valueConsumer) { return this.buildComputedPaginationState(sourceProvider) @@ -148,7 +156,7 @@ public final State computedPaginationState( } @Override - public final State computedAsyncPaginationState( + public State computedAsyncPaginationState( @NotNull Function>> sourceProvider, @NotNull PaginationValueConsumer valueConsumer) { return this.buildComputedAsyncPaginationState(sourceProvider) @@ -157,7 +165,7 @@ public final State computedAsyncPaginationState( } @Override - public final State lazyPaginationState( + public State lazyPaginationState( @NotNull Function> sourceProvider, @NotNull PaginationValueConsumer valueConsumer) { return this.buildLazyPaginationState(sourceProvider) @@ -184,48 +192,48 @@ public State lazyAsyncPaginationState( } @Override - public final PaginationStateBuilder buildPaginationState( + public PaginationStateBuilder buildPaginationState( @NotNull List sourceProvider) { return new PaginationStateBuilder<>( elementFactoryProvider, sourceProvider, this::createPaginationState, false, false); } @Override - public final PaginationStateBuilder buildComputedPaginationState( + public PaginationStateBuilder buildComputedPaginationState( @NotNull Function> sourceProvider) { return new PaginationStateBuilder<>( elementFactoryProvider, sourceProvider, this::createPaginationState, false, true); } @Override - public final PaginationStateBuilder buildComputedAsyncPaginationState( + public PaginationStateBuilder buildComputedAsyncPaginationState( @NotNull Function>> sourceProvider) { return new PaginationStateBuilder<>( elementFactoryProvider, sourceProvider, this::createPaginationState, true, true); } @Override - public final PaginationStateBuilder buildLazyPaginationState( + public PaginationStateBuilder buildLazyPaginationState( @NotNull Supplier> sourceProvider) { return new PaginationStateBuilder<>( elementFactoryProvider, sourceProvider, this::createPaginationState, false, false); } @Override - public final PaginationStateBuilder buildLazyPaginationState( + public PaginationStateBuilder buildLazyPaginationState( @NotNull Function> sourceProvider) { return new PaginationStateBuilder<>( elementFactoryProvider, sourceProvider, this::createPaginationState, false, false); } @Override - public final PaginationStateBuilder buildLazyAsyncPaginationState( + public PaginationStateBuilder buildLazyAsyncPaginationState( @NotNull Function>> sourceProvider) { return new PaginationStateBuilder<>( elementFactoryProvider, sourceProvider, this::createPaginationState, true, false); } - protected final State createPaginationState( + private State createPaginationState( @NotNull PaginationStateBuilder builder) { final long id = State.next(); @SuppressWarnings({"unchecked", "rawtypes"}) diff --git a/inventory-framework-platform-bukkit/src/main/java/me/devnatan/inventoryframework/internal/BukkitElementFactory.java b/inventory-framework-platform-bukkit/src/main/java/me/devnatan/inventoryframework/internal/BukkitElementFactory.java index 245696266..a641a0669 100644 --- a/inventory-framework-platform-bukkit/src/main/java/me/devnatan/inventoryframework/internal/BukkitElementFactory.java +++ b/inventory-framework-platform-bukkit/src/main/java/me/devnatan/inventoryframework/internal/BukkitElementFactory.java @@ -15,6 +15,7 @@ import me.devnatan.inventoryframework.context.*; import me.devnatan.inventoryframework.logging.Logger; import me.devnatan.inventoryframework.logging.NoopLogger; +import me.devnatan.inventoryframework.state.timer.TimerState; import org.bukkit.entity.Player; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryCloseEvent; @@ -156,4 +157,9 @@ public Logger getLogger() { public Job scheduleJobInterval(@NotNull RootView root, long intervalInTicks, @NotNull Runnable execution) { return new BukkitTaskJobImpl(foliaLib.getScheduler(), intervalInTicks, execution); } + + @Override + public TimerState createTimerState(long stateId, long intervalInTicks) { + return null; + } } diff --git a/inventory-framework-platform-paper/build.gradle.kts b/inventory-framework-platform-paper/build.gradle.kts index 8c4131015..0f7247090 100644 --- a/inventory-framework-platform-paper/build.gradle.kts +++ b/inventory-framework-platform-paper/build.gradle.kts @@ -7,6 +7,10 @@ inventoryFramework { publish = true } +repositories { + maven("https://repo.tcoded.com/releases") +} + dependencies { compileOnly(libs.paperSpigot) implementation(projects.inventoryFrameworkPlatformBukkit) diff --git a/inventory-framework-platform/src/main/java/me/devnatan/inventoryframework/PlatformView.java b/inventory-framework-platform/src/main/java/me/devnatan/inventoryframework/PlatformView.java index 560687c0a..e28e74d91 100644 --- a/inventory-framework-platform/src/main/java/me/devnatan/inventoryframework/PlatformView.java +++ b/inventory-framework-platform/src/main/java/me/devnatan/inventoryframework/PlatformView.java @@ -39,13 +39,8 @@ import me.devnatan.inventoryframework.pipeline.StandardPipelinePhases; import me.devnatan.inventoryframework.pipeline.UpdateInterceptor; import me.devnatan.inventoryframework.pipeline.ViewerLastInteractionTrackerInterceptor; -import me.devnatan.inventoryframework.state.InitialDataStateValue; -import me.devnatan.inventoryframework.state.MutableIntState; -import me.devnatan.inventoryframework.state.MutableState; -import me.devnatan.inventoryframework.state.State; -import me.devnatan.inventoryframework.state.StateAccess; -import me.devnatan.inventoryframework.state.StateAccessImpl; -import me.devnatan.inventoryframework.state.StateValue; +import me.devnatan.inventoryframework.state.*; +import me.devnatan.inventoryframework.state.timer.TimerState; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; @@ -765,5 +760,11 @@ public final PaginationStateBuilder buildLazyAsyncPagina requireNotInitialized(); return stateAccess.buildLazyAsyncPaginationState(sourceProvider); } + + @Override + public TimerState timerState(long intervalInTicks) { + requireNotInitialized(); + return stateAccess.timerState(intervalInTicks); + } // endregion }