package com.supaham.commons.bukkit; import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.base.Supplier; import com.supaham.commons.bukkit.area.Region; import org.bukkit.entity.Entity; import org.bukkit.plugin.Plugin; import java.util.Collection; import javax.annotation.Nonnull; /** * Represents a customizable {@link TickerTask} that's main purpose is tracking entities. The * entities are supplied to this task using a {@link Supplier}. * * @since 0.1 */ public abstract class LocationChecker<T extends Entity> extends TickerTask { private final Region region; private Supplier<Collection<T>> supplier; /** * Constructs a new location checker. * * @param plugin plugin to own this task * @param interval how often this task should run (in minecraft ticks) * @param region region to check for entities in * @param supplier supplier of entities to call for each iteration */ public LocationChecker(@Nonnull Plugin plugin, int interval, @Nonnull Region region, @Nonnull Supplier<Collection<T>> supplier) { super(plugin, 0, interval); checkNotNull(region, "region cannot be null."); checkNotNull(supplier, "supplier cannot be null."); this.region = region; this.supplier = supplier; } /** * This method is called pre entity location check. * * @param entity entity that is about to be checked * * @return true to preform the entity location check, false to cancel it */ protected boolean preRun(@Nonnull T entity) { return true; } /** * This method is called post entity location check. * * @param entity entity that has been checked */ protected void postRun(@Nonnull T entity) {} /** * This method is called if the entity is out of boundaries. * * @param entity entity that has left the boundaries */ protected abstract void onOutOfBounds(@Nonnull T entity); /** * This method is called if the entity is inside the boundaries. * * @param entity entity that is inside the boundaries */ protected abstract void onInBounds(@Nonnull T entity); /** * Returns whether an entity is within this checker. * * @param entity entity to check * * @return true if the entity passed the check, meaning 'in bounds' */ protected boolean check(T entity) { return this.region.contains(entity.getLocation().toVector()); } @Override public void run() { Collection<T> entities = this.supplier.get(); for (T entity : entities) { if (entity == null) { continue; } if (!preRun(entity)) { continue; } if (!check(entity)) { onOutOfBounds(entity); } else { onInBounds(entity); } postRun(entity); } } public Supplier<Collection<T>> getSupplier() { return supplier; } public void setSupplier(Supplier<Collection<T>> supplier) { this.supplier = supplier; } }