package net.minestom.server.event;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Player;
import net.minestom.server.event.trait.*;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.block.Block;
import net.minestom.server.inventory.Inventory;
import net.minestom.server.item.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Function;
/**
* Represents a filter for a specific {@link Event} type.
*
* The handler represents a "target" of the event. This can be used
* to create filters for all events of a specific type using information
* about the target.
*
* For example, the target of a {@link PlayerEvent} is a {@link Player} so
* you could create a player event filter which checks if the target player
* is in creative mode.
*
* @param The event type to filter
* @param The handler type to filter on.
*/
public interface EventFilter {
EventFilter ALL = from(Event.class, null, null);
EventFilter ENTITY = from(EntityEvent.class, Entity.class, EntityEvent::getEntity);
EventFilter PLAYER = from(PlayerEvent.class, Player.class, PlayerEvent::getPlayer);
EventFilter ITEM = from(ItemEvent.class, ItemStack.class, ItemEvent::getItemStack);
EventFilter INSTANCE = from(InstanceEvent.class, Instance.class, InstanceEvent::getInstance);
EventFilter INVENTORY = from(InventoryEvent.class, Inventory.class, InventoryEvent::getInventory);
EventFilter BLOCK = from(BlockEvent.class, Block.class, BlockEvent::getBlock);
static EventFilter from(@NotNull Class eventType,
@Nullable Class handlerType,
@Nullable Function handlerGetter) {
return new EventFilter<>() {
@Override
public @Nullable H getHandler(@NotNull E event) {
return handlerGetter != null ? handlerGetter.apply(event) : null;
}
@Override
public @NotNull Class eventType() {
return eventType;
}
@Override
public @Nullable Class handlerType() {
return handlerType;
}
};
}
/**
* Gets the handler for the given event instance, or null if the event
* type has no handler.
*
* @param event The event instance
* @return The handler, if it exists for the given event
*/
@Nullable H getHandler(@NotNull E event);
@ApiStatus.Internal
default @Nullable H castHandler(@NotNull Object event) {
//noinspection unchecked
return getHandler((E) event);
}
/**
* The event type to filter on.
*
* @return The event type.
*/
@NotNull Class eventType();
/**
* The type returned by {@link #getHandler(Event)}.
*
* @return the handler type, null if not any
*/
@Nullable Class handlerType();
}