001/*
002 * Copyright (c) 2016-2017 Daniel Ennis (Aikar) - MIT License
003 *
004 *  Permission is hereby granted, free of charge, to any person obtaining
005 *  a copy of this software and associated documentation files (the
006 *  "Software"), to deal in the Software without restriction, including
007 *  without limitation the rights to use, copy, modify, merge, publish,
008 *  distribute, sublicense, and/or sell copies of the Software, and to
009 *  permit persons to whom the Software is furnished to do so, subject to
010 *  the following conditions:
011 *
012 *  The above copyright notice and this permission notice shall be
013 *  included in all copies or substantial portions of the Software.
014 *
015 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
016 *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
017 *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
018 *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
019 *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
020 *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
021 *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
022 */
023
024package co.aikar.taskchain;
025
026import java.util.concurrent.TimeUnit;
027
028@SuppressWarnings("WeakerAccess")
029public interface GameInterface {
030    /**
031     * Determines if the current thread is the main thread or not.
032     * @return
033     */
034    boolean isMainThread();
035
036    /**
037     * Returns the AsyncQueue instance used by this game implementation
038     * @return
039     */
040    AsyncQueue getAsyncQueue();
041
042    /**
043     * Schedule a runnable to run on the main thread
044     * @param run
045     */
046    void postToMain(Runnable run);
047
048    /**
049     * Execute the runnable off of the main thread
050     * @param run
051     */
052    default void postAsync(Runnable run) {
053        getAsyncQueue().postAsync(run);
054    };
055
056    /**
057     * Schedule a task within the games scheduler using its own units
058     *
059     * IMPLEMENTATION SPECIFIC
060     *
061     * @param gameUnits
062     * @param run
063     */
064    void scheduleTask(int gameUnits, Runnable run);
065
066    /**
067     * Every factory created needs to register a way to automatically shut itself down (On Disable)
068     *
069     * If its impossible to provide automatic shutdown registry, you should leave this method blank
070     * and manually call {@link TaskChainFactory#shutdown(int, TimeUnit)}
071     * @param factory Factory to shutdown
072     */
073    void registerShutdownHandler(TaskChainFactory factory);
074
075    /**
076     * Adds a delay to the chain execution based on real time
077     *
078     * Method will be ran async from main thread.
079     * Chain must {@link TaskChain#abort()} if the delay is interrupted.
080     *
081     * @param duration Duration to delay
082     * @param units Units to delay in
083     * @param run Callback to execute once the delay is done.
084     */
085    default void scheduleTask(int duration, TimeUnit units, Runnable run) {
086        postAsync(() -> {
087            try {
088                Thread.sleep(units.toMillis(duration));
089                run.run();
090            } catch (InterruptedException e) {
091                TaskChain.abort();
092            }
093        });
094    }
095}