001/*
002 * PlotSquared, a land and world management plugin for Minecraft.
003 * Copyright (C) IntellectualSites <https://intellectualsites.com>
004 * Copyright (C) IntellectualSites team and contributors
005 *
006 * This program is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation, either version 3 of the License, or
009 * (at your option) any later version.
010 *
011 * This program is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014 * GNU General Public License for more details.
015 *
016 * You should have received a copy of the GNU General Public License
017 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
018 */
019package com.plotsquared.bukkit.util.task;
020
021import com.google.inject.Inject;
022import com.google.inject.Singleton;
023import com.plotsquared.bukkit.BukkitPlatform;
024import com.plotsquared.core.PlotSquared;
025import com.plotsquared.core.util.task.PlotSquaredTask;
026import com.plotsquared.core.util.task.TaskManager;
027import com.plotsquared.core.util.task.TaskTime;
028import org.bukkit.Bukkit;
029import org.checkerframework.checker.nullness.qual.NonNull;
030
031import java.util.concurrent.Callable;
032import java.util.concurrent.Future;
033import java.util.concurrent.TimeUnit;
034
035/**
036 * Bukkit implementation of {@link TaskManager} using
037 * by {@link org.bukkit.scheduler.BukkitScheduler} and {@link BukkitPlotSquaredTask}
038 */
039@Singleton
040public class BukkitTaskManager extends TaskManager {
041
042    private final BukkitPlatform bukkitMain;
043    private final TaskTime.TimeConverter timeConverter;
044
045    @Inject
046    public BukkitTaskManager(
047            final @NonNull BukkitPlatform bukkitMain,
048            final TaskTime.@NonNull TimeConverter timeConverter
049    ) {
050        this.bukkitMain = bukkitMain;
051        this.timeConverter = timeConverter;
052    }
053
054    @Override
055    public PlotSquaredTask taskRepeat(
056            final @NonNull Runnable runnable,
057            final @NonNull TaskTime taskTime
058    ) {
059        final long ticks = this.timeConverter.toTicks(taskTime);
060        final BukkitPlotSquaredTask bukkitPlotSquaredTask = new BukkitPlotSquaredTask(runnable);
061        bukkitPlotSquaredTask.runTaskTimer(this.bukkitMain, ticks, ticks);
062        return bukkitPlotSquaredTask;
063    }
064
065    @Override
066    public PlotSquaredTask taskRepeatAsync(
067            final @NonNull Runnable runnable,
068            final @NonNull TaskTime taskTime
069    ) {
070        final long ticks = this.timeConverter.toTicks(taskTime);
071        final BukkitPlotSquaredTask bukkitPlotSquaredTask = new BukkitPlotSquaredTask(runnable);
072        bukkitPlotSquaredTask.runTaskTimerAsynchronously(this.bukkitMain, ticks, ticks);
073        return bukkitPlotSquaredTask;
074    }
075
076    @Override
077    public void taskAsync(final @NonNull Runnable runnable) {
078        if (this.bukkitMain.isEnabled()) {
079            new BukkitPlotSquaredTask(runnable).runTaskAsynchronously(this.bukkitMain);
080        } else {
081            runnable.run();
082        }
083    }
084
085    @Override
086    public <T> T sync(final @NonNull Callable<T> function, final int timeout) throws Exception {
087        if (PlotSquared.get().isMainThread(Thread.currentThread())) {
088            return function.call();
089        }
090        return this.callMethodSync(function).get(timeout, TimeUnit.MILLISECONDS);
091    }
092
093    @Override
094    public <T> Future<T> callMethodSync(final @NonNull Callable<T> method) {
095        return Bukkit.getScheduler().callSyncMethod(this.bukkitMain, method);
096    }
097
098    @Override
099    public void task(final @NonNull Runnable runnable) {
100        new BukkitPlotSquaredTask(runnable).runTask(this.bukkitMain);
101    }
102
103    @Override
104    public void taskLater(
105            final @NonNull Runnable runnable,
106            final @NonNull TaskTime taskTime
107    ) {
108        final long delay = this.timeConverter.toTicks(taskTime);
109        new BukkitPlotSquaredTask(runnable).runTaskLater(this.bukkitMain, delay);
110    }
111
112    @Override
113    public void taskLaterAsync(
114            final @NonNull Runnable runnable,
115            final @NonNull TaskTime taskTime
116    ) {
117        final long delay = this.timeConverter.toTicks(taskTime);
118        new BukkitPlotSquaredTask(runnable).runTaskLaterAsynchronously(this.bukkitMain, delay);
119    }
120
121}