fslib.scheduler.FSScheduleController.java Source code

Java tutorial

Introduction

Here is the source code for fslib.scheduler.FSScheduleController.java

Source

/**
 * fslib is an open-source, high-level API for MinecraftForge, providing maximal coverage.
 *
 * Copyright (C) 2015 Company <support@company.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package fslib.scheduler;

import java.util.HashSet;
import java.util.Set;

import org.apache.commons.lang3.Validate;

import net.minecraft.client.Minecraft;
import net.minecraft.server.MinecraftServer;
import net.minecraftforge.fml.relauncher.FMLLaunchHandler;

public class FSScheduleController {

    public FSScheduleController() {
        new TaskExecutorThread(true).start();
        new TaskExecutorThread(false).start();
    }

    private boolean loaded = false;

    private final Set<Task> onLoaded = new HashSet<>();
    private final Set<ScheduledTask> sync = new HashSet<>();
    private volatile Set<ScheduledTask> async = new HashSet<>();

    public synchronized void onLoaded(Task task) {
        Validate.notNull(task, "task cannot be null");
        if (loaded) {
            task.run();
            return;
        }
        onLoaded.add(task);
    }

    public synchronized void loaded() {
        if (loaded)
            return;
        loaded = true;
        new Thread(() -> {
            try {
                Thread.sleep(5000);
            } catch (Exception e) {
            }
            onLoaded.forEach(t -> {
                try {
                    t.run();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            });
        }, "ScheduleController: onLoaded").start();
    }

    public synchronized ScheduledTask later(Task task, long delay, boolean sync) {
        Validate.notNull(task, "task cannot be null");
        Validate.isTrue(delay >= 0, "delay must be positive");
        long exec = System.currentTimeMillis() + delay;
        ScheduledTask stask = new ScheduledTask(task, exec, sync);
        if (delay == 0)
            stask.run();
        else
            (sync ? this.sync : this.async).add(stask);
        return stask;
    }

    public synchronized ScheduledTask repeat(Task task, long delay, long period, boolean sync) {
        Validate.notNull(task, "task cannot be null");
        Validate.isTrue(delay >= 0, "delay must be positive");
        Validate.isTrue(period > 0, "period must be positive");
        long exec = System.currentTimeMillis() + delay;
        ScheduledTask stask = new ScheduledTask(task, exec, period, sync);
        if (delay == 0)
            stask.run();
        else
            (sync ? this.sync : this.async).add(stask);
        return stask;
    }

    public synchronized void cancel(ScheduledTask task) {
        Set<ScheduledTask> tasks = task.sync ? this.sync : this.async;
        if (tasks.contains(task))
            tasks.remove(task);
    }

    private class TaskExecutorThread extends Thread {

        private final boolean sync;

        public TaskExecutorThread(boolean sync) {
            super((sync ? "Sync" : "Async") + " Task Executor Thread");
            this.sync = sync;
        }

        @Override
        public synchronized void run() {
            while (true) {
                try {
                    Thread.sleep(5);
                } catch (InterruptedException e) {
                }
                _run();
            }
        }

        public synchronized void _run() {
            Set<ScheduledTask> tasks = sync ? FSScheduleController.this.sync : FSScheduleController.this.async;
            long now = System.currentTimeMillis();
            for (ScheduledTask task : tasks) {
                if (task.exec <= now)
                    if (sync)
                        switch (FMLLaunchHandler.side()) {
                        case CLIENT:
                            Minecraft.getMinecraft().addScheduledTask(task);
                            break;
                        case SERVER:
                            MinecraftServer.getServer().addScheduledTask(task);
                            break;
                        }
                    else
                        task.run();
            }
        }

    }

}