package tc.oc.commons.bukkit.suspend;
import java.util.Set;
import javax.inject.Inject;
import org.bukkit.event.Event;
import org.bukkit.event.EventException;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.server.ServerSuspendEvent;
import tc.oc.commons.core.plugin.PluginFacet;
import tc.oc.commons.core.util.ThrowingConsumer;
import tc.oc.minecraft.suspend.Suspendable;
import static com.google.common.base.Preconditions.checkState;
/**
* Listens for {@link ServerSuspendEvent} and dispatches it to all {@link Suspendable}s
*/
public class SuspendListener implements PluginFacet, Listener {
private final ThrowingConsumer<ServerSuspendEvent, EventException> yielder;
@Inject SuspendListener(Set<Suspendable> suspendables) {
ThrowingConsumer<ServerSuspendEvent, EventException> yielder = Event::yield;
for(Suspendable suspendable : suspendables) {
ThrowingConsumer<ServerSuspendEvent, EventException> next = yielder;
yielder = event -> suspendable.suspend(() -> next.acceptThrows(event));
}
this.yielder = yielder;
}
@EventHandler
void onSuspend(ServerSuspendEvent event) throws EventException {
yielder.acceptThrows(event);
checkState(!event.canYield(), "Suspendable didn't yield");
}
}