Skip to content
Draft
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 @@ -2,20 +2,26 @@

import java.util.Arrays;
import java.util.Objects;
import java.util.function.IntFunction;
import me.devnatan.inventoryframework.component.ComponentFactory;
import me.devnatan.inventoryframework.jdk.IndexSlotFunction;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;

/**
* <b><i> This is an internal inventory-framework API that should not be used from outside of
* this library. No compatibility guarantees are provided. </i></b>
*/
@ApiStatus.Internal
public final class LayoutSlot {

// Retro compatibility
public static final char FILLED_RESERVED_CHAR = 'O';

private final char character;
private final IntFunction<ComponentFactory> factory;
private final IndexSlotFunction<ComponentFactory> factory;
private final int[] positions;

public LayoutSlot(char character, @Nullable IntFunction<ComponentFactory> factory, int[] positions) {
public LayoutSlot(char character, @Nullable IndexSlotFunction<ComponentFactory> factory, int[] positions) {
this.character = character;
this.factory = factory;
this.positions = positions;
Expand All @@ -25,11 +31,11 @@ public char getCharacter() {
return character;
}

public IntFunction<ComponentFactory> getFactory() {
public IndexSlotFunction<ComponentFactory> getFactory() {
return factory;
}

public LayoutSlot withFactory(@Nullable IntFunction<ComponentFactory> factory) {
public LayoutSlot withFactory(@Nullable IndexSlotFunction<ComponentFactory> factory) {
return new LayoutSlot(character, factory, positions);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package me.devnatan.inventoryframework.jdk;

/**
* Represents an operation that accepts an iteration index as first argument, an int-valued slot position as second argument
* and an object-valued input as third argument, and returns no result.
*
* @param <T> The type of the object argument to the operation.
*/
@FunctionalInterface
public interface IndexSlotConsumer<T> {

/**
* Performs this operation on the given arguments.
*
* @param index The iteration index.
* @param slot The slot position.
* @param value The input argument.
*/
void accept(int index, int slot, T value);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package me.devnatan.inventoryframework.jdk;

/**
* Represents a function that accepts and int-valued iteration index as first argument
* and a int-valued slot position as second argument and produces a result.
*
* @param <R> The type of the result of the function.
*/
@FunctionalInterface
public interface IndexSlotFunction<R> {

/**
* Applies this function to the given argument.
*
* @param index The iteration index.
* @param slot The slot position.
* @return The function result.
*/
R apply(int index, int slot);
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package me.devnatan.inventoryframework.pipeline;

import java.util.function.IntFunction;
import me.devnatan.inventoryframework.InventoryFrameworkException;
import me.devnatan.inventoryframework.VirtualView;
import me.devnatan.inventoryframework.component.Component;
import me.devnatan.inventoryframework.component.ComponentFactory;
import me.devnatan.inventoryframework.component.ItemComponentBuilder;
import me.devnatan.inventoryframework.context.IFRenderContext;
import me.devnatan.inventoryframework.internal.LayoutSlot;
import me.devnatan.inventoryframework.jdk.IndexSlotFunction;

public final class LayoutRenderInterceptor implements PipelineInterceptor<VirtualView> {

Expand All @@ -17,8 +16,8 @@ public void intercept(PipelineContext<VirtualView> pipeline, VirtualView subject

final IFRenderContext renderContext = (IFRenderContext) subject;
for (final LayoutSlot layoutSlot : renderContext.getLayoutSlots()) {
final IntFunction<ComponentFactory> factory = layoutSlot.getFactory();
if (factory == null) {
final IndexSlotFunction<ComponentFactory> elementsFactory = layoutSlot.getFactory();
if (elementsFactory == null) {
if (layoutSlot.isDefinedByTheUser())
throw new InventoryFrameworkException(
"#layoutSlot(...) factory cannot be null when defined by the user");
Expand All @@ -27,11 +26,8 @@ public void intercept(PipelineContext<VirtualView> pipeline, VirtualView subject

int iterationIndex = 0;
for (final int slot : layoutSlot.getPositions()) {
final ComponentFactory componentFactory = factory.apply(iterationIndex++);
if (componentFactory instanceof ItemComponentBuilder)
((ItemComponentBuilder<?, ?>) componentFactory).withSlot(slot);

final Component component = componentFactory.create();
final ComponentFactory factory = elementsFactory.apply(iterationIndex++, slot);
final Component component = factory.create();
renderContext.addComponent(component);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
import static java.lang.String.format;
import static me.devnatan.inventoryframework.utils.SlotConverter.convertSlot;

import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import me.devnatan.inventoryframework.InventoryFrameworkException;
Expand All @@ -14,6 +18,7 @@
import me.devnatan.inventoryframework.component.ComponentFactory;
import me.devnatan.inventoryframework.component.ItemComponentBuilder;
import me.devnatan.inventoryframework.internal.LayoutSlot;
import me.devnatan.inventoryframework.jdk.IndexSlotConsumer;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.UnmodifiableView;
Expand Down Expand Up @@ -171,8 +176,11 @@ public void availableSlot(@NotNull BiConsumer<Integer, T> factory) {
/**
* Defines the item that will represent a character provided in the context layout.
*
*
*
* @param character The layout character target.
* @return An item builder to configure the item.
* @see <a href="https://github.com/DevNatan/inventory-framework/wiki/layouts#layout-slot">Layout Slot on Wiki</a>
*/
public @NotNull T layoutSlot(char character) {
requireNonReservedLayoutCharacter(character);
Expand All @@ -184,21 +192,21 @@ public void availableSlot(@NotNull BiConsumer<Integer, T> factory) {
.orElseThrow(() -> new InventoryFrameworkException("Missing layout character: " + character));

final T builder = createBuilder();
final int elIndex = getLayoutSlots().indexOf(layoutSlot);
getLayoutSlots().set(elIndex, layoutSlot.withFactory($ -> (ComponentFactory) builder));
getLayoutSlots().set(getLayoutSlots().indexOf(layoutSlot), layoutSlot.withFactory((index, slot) ->
(ComponentFactory) builder.withSlot(slot)));
return builder;
}

/**
* Defines the item that will represent a character provided in the context layout.
*
* <pre>{@code
* layoutSlot('F', (index, builder) -> builder.withItem(...));
* layoutSlot('F', (index, slot, builder) -> builder.withItem(...));
* }</pre>
*
* @param character The layout character target.
*/
public void layoutSlot(char character, @NotNull BiConsumer<Integer, T> factory) {
public void layoutSlot(char character, @NotNull IndexSlotConsumer<T> factory) {
requireNonReservedLayoutCharacter(character);

// TODO More detailed exception message
Expand All @@ -207,14 +215,43 @@ public void layoutSlot(char character, @NotNull BiConsumer<Integer, T> factory)
.findFirst()
.orElseThrow(() -> new InventoryFrameworkException("Missing layout character: " + character));

final int elIndex = getLayoutSlots().indexOf(layoutSlot);
getLayoutSlots().set(elIndex, layoutSlot.withFactory(index -> {
getLayoutSlots().set(getLayoutSlots().indexOf(layoutSlot), layoutSlot.withFactory((index, slot) -> {
final T builder = createBuilder();
factory.accept(index, builder);
builder.withSlot(slot);
factory.accept(index, slot, builder);
return (ComponentFactory) builder;
}));
}

/**
* TODO
*
* <p><b><i> 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. </i></b>
*
* @param character The layout character target.
* @param items The items to be iterated for each character present in the layout.
* @param factory The function that'll be called for each iterated item.
*/
// @ApiStatus.Experimental
// <V> layoutSlot(char character, @NotNull Iterable<V> items, @NotNull IndexSlotConsumer<T> factory) {
// requireNonReservedLayoutCharacter(character);
//
// // TODO More detailed exception message
// final LayoutSlot layoutSlot = getLayoutSlots().stream()
// .filter(value -> value.getCharacter() == character)
// .findFirst()
// .orElseThrow(() -> new InventoryFrameworkException("Missing layout character: " + character));
//
// final Iterator<T> iterator = items.iterator();
// getLayoutSlots().set(getLayoutSlots().indexOf(layoutSlot), layoutSlot.withFactory((index, slot) -> {
// final T builder = createBuilder();
// builder.withSlot(slot);
// factory.accept(index, slot, builder);
// return (ComponentFactory) builder;
// }));
// }

/**
* Creates a new platform builder instance.
*
Expand Down