diff --git a/src/main/java/net/minestom/server/acquirable/Acquirable.java b/src/main/java/net/minestom/server/acquirable/Acquirable.java index 4c781b04c..8a82de2ce 100644 --- a/src/main/java/net/minestom/server/acquirable/Acquirable.java +++ b/src/main/java/net/minestom/server/acquirable/Acquirable.java @@ -38,10 +38,30 @@ public interface Acquirable { AcquirableImpl.CURRENT_ENTITIES.set(entities); } + /** + * Creates a new {@link Acquirable} object. + *

+ * Mostly for internal use, as a {@link TickThread} has to be used + * and properly synchronized. + * + * @param value the acquirable element + * @param the acquirable element type + * @return a new acquirable object + */ + @ApiStatus.Internal static @NotNull Acquirable of(@NotNull T value) { return new AcquirableImpl<>(value); } + /** + * Returns a new {@link Acquired} object which will be locked to the current thread. + *

+ * Useful when your code cannot be done inside a callback and need to be sync. + * Do not forget to call {@link Acquired#unlock()} once you are done with it. + * + * @return an acquired object + * @see #sync(Consumer) for auto-closeable capability + */ default @NotNull Acquired lock() { var optional = local(); if (optional.isPresent()) { @@ -54,6 +74,16 @@ public interface Acquirable { } } + /** + * Retrieves the acquirable value if and only if the element + * is already present/ticked in the current thread. + *

+ * Useful when you want only want to acquire an element when you are guaranteed + * to do not create a huge performance impact. + * + * @return an optional containing the acquired element if safe, + * {@link Optional#empty()} otherwise + */ default @NotNull Optional local() { final Thread currentThread = Thread.currentThread(); final TickThread tickThread = getHandler().getTickThread(); @@ -63,12 +93,28 @@ public interface Acquirable { return Optional.empty(); } + /** + * Locks the acquirable element, execute {@code consumer} synchronously and unlock the thread. + *

+ * Free if the element is already present in the current thread, blocking otherwise. + * + * @param consumer the callback to execute once the element has been safely acquired + * @see #async(Consumer) + */ default void sync(@NotNull Consumer consumer) { var acquired = lock(); consumer.accept(acquired.get()); acquired.unlock(); } + /** + * Locks the acquirable element, execute {@code consumer} asynchronously and unlock the thread. + *

+ * Free if the element is already present in the current thread, blocking otherwise. + * + * @param consumer the callback to execute once the element has been safely acquired + * @see #sync(Consumer) + */ default void async(@NotNull Consumer consumer) { // TODO per-thread list AsyncUtils.runAsync(() -> sync(consumer));