001package com.ericlam.mc.eld.services;
002
003import com.ericlam.mc.eld.misc.ChainCallable;
004import org.bukkit.plugin.Plugin;
005import org.bukkit.scheduler.BukkitRunnable;
006import org.bukkit.scheduler.BukkitTask;
007
008import java.util.List;
009import java.util.concurrent.Callable;
010import java.util.function.Consumer;
011
012/**
013 * 計時器
014 */
015public interface ScheduleService {
016
017    /**
018     * 注入計時器, 可讓計時器進行依賴注入
019     * @param runnable 計時器
020     * @return 計時器工廠
021     */
022    ScheduleFactory injectTask(BukkitRunnable runnable);
023
024    /**
025     * 從異步呼叫數值
026     * @param <E> 回傳數值
027     * @param plugin 插件
028     * @param callable 呼叫類
029     * @return bukkit promise
030     */
031    <E> BukkitPromise<E> callAsync(Plugin plugin, Callable<E> callable);
032
033    /***
034     * 從異步運行
035     * @param plugin 插件
036     * @param runnable 異步運行
037     * @return bukkit promise
038     */
039    BukkitPromise<Void> runAsync(Plugin plugin, Runnable runnable);
040
041    /**
042     * 等待多個異步的數值呼叫並傳回
043     * @param plugin 插件
044     * @param promises 異步呼叫
045     * @return bukkit promise
046     */
047    BukkitPromise<Object[]> callAllAsync(Plugin plugin, List<BukkitPromise<Object>> promises);
048
049    /**
050     * 等待多個異步完成
051     * @param plugin 插件
052     * @param promises 異步運行
053     * @return bukkit promise
054     */
055    BukkitPromise<Void> runAllAsync(Plugin plugin, List<BukkitPromise<Void>> promises);
056
057
058    /**
059     * 等待其中一個異步事件完成後立刻傳回
060     * @param plugin 插件
061     * @param promises 異步呼叫
062     * @return bukkit promise
063     */
064    BukkitPromise<Object> callAnyAsync(Plugin plugin, List<BukkitPromise<Object>> promises);
065
066    /**
067     * 等待其中一個異步事件完成後立刻返回
068     * @param plugin 插件
069     * @param promises 異步運行
070     * @return bukkit promise
071     */
072    BukkitPromise<Void> runAnyAsync(Plugin plugin, List<BukkitPromise<Void>> promises);
073
074
075    /**
076     * 計時器工廠
077     */
078    interface ScheduleFactory {
079
080        /**
081         * 是否異步
082         * @param async 異步
083         * @return this
084         */
085        ScheduleFactory asynchronous(boolean async);
086
087        /**
088         * 間隔, 設定後即為 timer
089         * @param ticks ticks
090         * @return this
091         */
092        ScheduleFactory interval(long ticks);
093
094        /**
095         * 延遲
096         * @param ticks ticks
097         * @return this
098         */
099        ScheduleFactory timeout(long ticks);
100
101        /**
102         * 運行
103         * @param plugin 插件
104         * @return this
105         */
106        BukkitTask run(Plugin plugin);
107
108    }
109
110    /**
111     * 鏈式的計時及數值提取器 (bukkit promise)
112     * @param <E> 回傳數值
113     */
114    interface BukkitPromise<E> {
115
116        /**
117         * 同步運行並傳遞數值
118         * @param function 運行
119         * @param <R> 新的回傳數值
120         * @return this
121         */
122        <R> BukkitPromise<R> thenApplySync(ChainCallable<E, R> function);
123
124        /**
125         * 同步運行
126         * @param function 運行
127         * @return 沒有傳遞數值的 bukkit promise
128         */
129        BukkitPromise<Void> thenRunSync(Consumer<E> function);
130
131        /**
132         * 異步運行並傳遞數值
133         * @param function 運行
134         * @param <R> 新的回傳數值
135         * @return this
136         */
137        <R> BukkitPromise<R> thenApplyAsync(ChainCallable<E, R> function);
138
139        /**
140         * 異步運行
141         * @param function 運行
142         * @return 沒有傳遞數值的 bukkit promise
143         */
144        BukkitPromise<Void> thenRunAsync(Consumer<E> function);
145
146        /**
147         * 啟動
148         */
149        void join();
150
151        /**
152         * 阻塞啟動
153         * @return 回傳數值
154         * @throws Throwable 阻塞時可能出現的錯誤
155         */
156        E block() throws Throwable;
157
158        /**
159         * 啟動並手動處理錯誤(如有)
160         * @param handler 錯誤處理
161         */
162        void joinWithCatch(Consumer<Throwable> handler);
163    }
164
165}