mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-04-06 15:56:27 +00:00
Repackage utils
This commit is contained in:
42
src/main/java/com/volmit/iris/util/scheduling/AR.java
Normal file
42
src/main/java/com/volmit/iris/util/scheduling/AR.java
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util;
|
||||
|
||||
import com.volmit.iris.util.plugin.CancellableTask;
|
||||
|
||||
public abstract class AR implements Runnable, CancellableTask {
|
||||
private int id = 0;
|
||||
|
||||
public AR() {
|
||||
this(0);
|
||||
}
|
||||
|
||||
public AR(int interval) {
|
||||
id = J.ar(this, interval);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
J.car(id);
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
35
src/main/java/com/volmit/iris/util/scheduling/Callback.java
Normal file
35
src/main/java/com/volmit/iris/util/scheduling/Callback.java
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util;
|
||||
|
||||
/**
|
||||
* Callback for async workers
|
||||
*
|
||||
* @param <T> the type of object to be returned in the runnable
|
||||
* @author cyberpwn
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface Callback<T> {
|
||||
/**
|
||||
* Called when the callback calls back...
|
||||
*
|
||||
* @param t the object to be called back
|
||||
*/
|
||||
void run(T t);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util;
|
||||
|
||||
public interface CallbackCV<T> {
|
||||
void run(T t);
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util;
|
||||
|
||||
public class ChronoLatch {
|
||||
private final long interval;
|
||||
private long since;
|
||||
|
||||
public ChronoLatch(long interval, boolean openedAtStart) {
|
||||
this.interval = interval;
|
||||
since = System.currentTimeMillis() - (openedAtStart ? interval * 2 : 0);
|
||||
}
|
||||
|
||||
public ChronoLatch(long interval) {
|
||||
this(interval, true);
|
||||
}
|
||||
|
||||
public void flipDown() {
|
||||
since = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public boolean couldFlip() {
|
||||
return System.currentTimeMillis() - since > interval;
|
||||
}
|
||||
|
||||
public boolean flip() {
|
||||
if (System.currentTimeMillis() - since > interval) {
|
||||
since = System.currentTimeMillis();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
73
src/main/java/com/volmit/iris/util/scheduling/Chunker.java
Normal file
73
src/main/java/com/volmit/iris/util/scheduling/Chunker.java
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util;
|
||||
|
||||
import com.volmit.iris.util.scheduling.Callback;
|
||||
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||
import com.volmit.iris.util.scheduling.Contained;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class Chunker<T> {
|
||||
private ExecutorService executor;
|
||||
private int threads;
|
||||
private int workload;
|
||||
private final KList<T> q;
|
||||
|
||||
public Chunker(KList<T> q) {
|
||||
this.q = q;
|
||||
}
|
||||
|
||||
public Chunker<T> threads(int threads) {
|
||||
this.threads = threads;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Chunker<T> workload(int workload) {
|
||||
this.workload = workload;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void execute(Consumer<T> consumer, Callback<Double> progress, int progressInterval) {
|
||||
ChronoLatch cl = new ChronoLatch(progressInterval);
|
||||
Contained<Integer> consumed = new Contained<>(0);
|
||||
executor = Executors.newFixedThreadPool(threads);
|
||||
int length = q.size();
|
||||
int remaining = length;
|
||||
|
||||
while (remaining > 0) {
|
||||
int at = remaining;
|
||||
remaining -= (Math.min(remaining, workload));
|
||||
int to = remaining;
|
||||
|
||||
executor.submit(() ->
|
||||
{
|
||||
J.dofor(at, (i) -> i >= to, -1, (i) -> J.attempt(() -> consumer.accept(q.get(i))));
|
||||
consumed.mod((c) -> c += workload);
|
||||
J.doif(() -> progress != null && cl.flip(), () -> progress.run((double) consumed.get() / (double) length));
|
||||
});
|
||||
}
|
||||
|
||||
executor.shutdown();
|
||||
J.attempt(() -> executor.awaitTermination(100, TimeUnit.HOURS));
|
||||
}
|
||||
}
|
||||
45
src/main/java/com/volmit/iris/util/scheduling/Contained.java
Normal file
45
src/main/java/com/volmit/iris/util/scheduling/Contained.java
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class Contained<T> {
|
||||
private T t;
|
||||
|
||||
public Contained(T t) {
|
||||
set(t);
|
||||
}
|
||||
|
||||
public Contained() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public void mod(Function<T, T> x) {
|
||||
set(x.apply(t));
|
||||
}
|
||||
|
||||
public T get() {
|
||||
return t;
|
||||
}
|
||||
|
||||
public void set(T t) {
|
||||
this.t = t;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.util.collection.KMap;
|
||||
import com.volmit.iris.util.function.NastyRunnable;
|
||||
import com.volmit.iris.util.scheduling.J;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory;
|
||||
import java.util.concurrent.ForkJoinWorkerThread;
|
||||
|
||||
public class GroupedExecutor {
|
||||
private int xc;
|
||||
private final ExecutorService service;
|
||||
private final KMap<String, Integer> mirror;
|
||||
|
||||
public GroupedExecutor(int threadLimit, int priority, String name) {
|
||||
xc = 1;
|
||||
mirror = new KMap<>();
|
||||
|
||||
if (threadLimit == 1) {
|
||||
service = Executors.newSingleThreadExecutor((r) ->
|
||||
{
|
||||
Thread t = new Thread(r);
|
||||
t.setName(name);
|
||||
t.setPriority(priority);
|
||||
|
||||
return t;
|
||||
});
|
||||
} else if (threadLimit > 1) {
|
||||
final ForkJoinWorkerThreadFactory factory = pool -> {
|
||||
final ForkJoinWorkerThread worker = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
|
||||
worker.setName(name + " " + xc++);
|
||||
worker.setPriority(priority);
|
||||
return worker;
|
||||
};
|
||||
|
||||
service = new ForkJoinPool(threadLimit, factory, null, false);
|
||||
} else {
|
||||
service = Executors.newCachedThreadPool((r) ->
|
||||
{
|
||||
Thread t = new Thread(r);
|
||||
t.setName(name + " " + xc++);
|
||||
t.setPriority(priority);
|
||||
|
||||
return t;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void waitFor(String g) {
|
||||
if (g == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mirror.containsKey(g)) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if (mirror.get(g) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void queue(String q, NastyRunnable r) {
|
||||
mirror.compute(q, (k, v) -> k == null || v == null ? 1 : v + 1);
|
||||
|
||||
service.execute(() ->
|
||||
{
|
||||
try {
|
||||
r.run();
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
mirror.compute(q, (k, v) -> v - 1);
|
||||
});
|
||||
}
|
||||
|
||||
public void close() {
|
||||
J.a(() ->
|
||||
{
|
||||
J.sleep(100);
|
||||
service.shutdown();
|
||||
});
|
||||
}
|
||||
|
||||
public void closeNow() {
|
||||
service.shutdown();
|
||||
}
|
||||
}
|
||||
56
src/main/java/com/volmit/iris/util/scheduling/IrisLock.java
Normal file
56
src/main/java/com/volmit/iris/util/scheduling/IrisLock.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
@Data
|
||||
public class IrisLock {
|
||||
private transient final ReentrantLock lock;
|
||||
private transient final String name;
|
||||
private transient boolean disabled = false;
|
||||
|
||||
public IrisLock(String name) {
|
||||
this.name = name;
|
||||
lock = new ReentrantLock(false);
|
||||
}
|
||||
|
||||
public void lock() {
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
lock.lock();
|
||||
}
|
||||
|
||||
public void unlock() {
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
lock.unlock();
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError(e);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
326
src/main/java/com/volmit/iris/util/scheduling/J.java
Normal file
326
src/main/java/com/volmit/iris/util/scheduling/J.java
Normal file
@@ -0,0 +1,326 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.util.function.NastyFunction;
|
||||
import com.volmit.iris.util.function.NastyFuture;
|
||||
import com.volmit.iris.util.function.NastyRunnable;
|
||||
import com.volmit.iris.util.scheduling.AR;
|
||||
import com.volmit.iris.util.scheduling.SR;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.util.concurrent.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@SuppressWarnings("ALL")
|
||||
public class J {
|
||||
private static int tid = 0;
|
||||
private static final ExecutorService e = Executors.newCachedThreadPool(new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
tid++;
|
||||
Thread t = new Thread(r);
|
||||
t.setName("Iris Actuator " + tid);
|
||||
t.setPriority(8);
|
||||
t.setUncaughtExceptionHandler((et, e) ->
|
||||
{
|
||||
Iris.info("Exception encountered in " + et.getName());
|
||||
e.printStackTrace();
|
||||
});
|
||||
|
||||
return t;
|
||||
}
|
||||
});
|
||||
|
||||
public static void dofor(int a, Function<Integer, Boolean> c, int ch, Consumer<Integer> d) {
|
||||
for (int i = a; c.apply(i); i += ch) {
|
||||
c.apply(i);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean doif(Supplier<Boolean> c, Runnable g) {
|
||||
try {
|
||||
if (c.get()) {
|
||||
g.run();
|
||||
return true;
|
||||
}
|
||||
} catch (NullPointerException e) {Iris.reportError(e);
|
||||
// TODO: Fix this because this is just a suppression for an NPE on g
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void arun(Runnable a) {
|
||||
e.submit(() -> {
|
||||
try {
|
||||
a.run();
|
||||
} catch (Throwable e) {Iris.reportError(e);
|
||||
System.out.println("Failed to run async task");
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void a(Runnable a) {
|
||||
e.submit(() -> {
|
||||
try {
|
||||
a.run();
|
||||
} catch (Throwable e) {Iris.reportError(e);
|
||||
System.out.println("Failed to run async task");
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static <T> Future<T> a(Callable<T> a) {
|
||||
return e.submit(a);
|
||||
}
|
||||
|
||||
public static void attemptAsync(NastyRunnable r) {
|
||||
J.a(() -> J.attempt(r));
|
||||
}
|
||||
|
||||
public static <R> R attemptResult(NastyFuture<R> r, R onError) {
|
||||
try {
|
||||
return r.run();
|
||||
} catch (Throwable e) {Iris.reportError(e);
|
||||
|
||||
}
|
||||
|
||||
return onError;
|
||||
}
|
||||
|
||||
public static <T, R> R attemptFunction(NastyFunction<T, R> r, T param, R onError) {
|
||||
try {
|
||||
return r.run(param);
|
||||
} catch (Throwable e) {Iris.reportError(e);
|
||||
|
||||
}
|
||||
|
||||
return onError;
|
||||
}
|
||||
|
||||
public static boolean sleep(long ms) {
|
||||
return J.attempt(() -> Thread.sleep(ms));
|
||||
}
|
||||
|
||||
public static boolean attempt(NastyRunnable r) {
|
||||
return attemptCatch(r) == null;
|
||||
}
|
||||
|
||||
public static Throwable attemptCatch(NastyRunnable r) {
|
||||
try {
|
||||
r.run();
|
||||
} catch (Throwable e) {Iris.reportError(e);
|
||||
return e;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <T> T attempt(Supplier<T> t, T i) {
|
||||
try {
|
||||
return t.get();
|
||||
} catch (Throwable e) {Iris.reportError(e);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
private static KList<Runnable> afterStartup = new KList<>();
|
||||
private static KList<Runnable> afterStartupAsync = new KList<>();
|
||||
private static boolean started = false;
|
||||
|
||||
/**
|
||||
* Dont call this unless you know what you are doing!
|
||||
*/
|
||||
public static void executeAfterStartupQueue() {
|
||||
if (started) {
|
||||
return;
|
||||
}
|
||||
|
||||
started = true;
|
||||
|
||||
for (Runnable r : afterStartup) {
|
||||
s(r);
|
||||
}
|
||||
|
||||
for (Runnable r : afterStartupAsync) {
|
||||
a(r);
|
||||
}
|
||||
|
||||
afterStartup = null;
|
||||
afterStartupAsync = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule a sync task to be run right after startup. If the server has already
|
||||
* started ticking, it will simply run it in a sync task.
|
||||
* <p>
|
||||
* If you dont know if you should queue this or not, do so, it's pretty
|
||||
* forgiving.
|
||||
*
|
||||
* @param r the runnable
|
||||
*/
|
||||
public static void ass(Runnable r) {
|
||||
if (started) {
|
||||
s(r);
|
||||
} else {
|
||||
afterStartup.add(r);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule an async task to be run right after startup. If the server has
|
||||
* already started ticking, it will simply run it in an async task.
|
||||
* <p>
|
||||
* If you dont know if you should queue this or not, do so, it's pretty
|
||||
* forgiving.
|
||||
*
|
||||
* @param r the runnable
|
||||
*/
|
||||
public static void asa(Runnable r) {
|
||||
if (started) {
|
||||
a(r);
|
||||
} else {
|
||||
afterStartupAsync.add(r);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue a sync task
|
||||
*
|
||||
* @param r the runnable
|
||||
*/
|
||||
public static void s(Runnable r) {
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, r);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue a sync task
|
||||
*
|
||||
* @param r the runnable
|
||||
* @param delay the delay to wait in ticks before running
|
||||
*/
|
||||
public static void s(Runnable r, int delay) {
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, r, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel a sync repeating task
|
||||
*
|
||||
* @param id the task id
|
||||
*/
|
||||
public static void csr(int id) {
|
||||
Bukkit.getScheduler().cancelTask(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a sync repeating task
|
||||
*
|
||||
* @param r the runnable
|
||||
* @param interval the interval
|
||||
* @return the task id
|
||||
*/
|
||||
public static int sr(Runnable r, int interval) {
|
||||
return Bukkit.getScheduler().scheduleSyncRepeatingTask(Iris.instance, r, 0, interval);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a sync repeating task for a limited amount of ticks
|
||||
*
|
||||
* @param r the runnable
|
||||
* @param interval the interval in ticks
|
||||
* @param intervals the maximum amount of intervals to run
|
||||
*/
|
||||
public static void sr(Runnable r, int interval, int intervals) {
|
||||
FinalInteger fi = new FinalInteger(0);
|
||||
|
||||
new SR() {
|
||||
@Override
|
||||
public void run() {
|
||||
fi.add(1);
|
||||
r.run();
|
||||
|
||||
if (fi.get() >= intervals) {
|
||||
cancel();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Call an async task dealyed
|
||||
*
|
||||
* @param r the runnable
|
||||
* @param delay the delay to wait before running
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void a(Runnable r, int delay) {
|
||||
Bukkit.getScheduler().scheduleAsyncDelayedTask(Iris.instance, r, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel an async repeat task
|
||||
*
|
||||
* @param id the id
|
||||
*/
|
||||
public static void car(int id) {
|
||||
Bukkit.getScheduler().cancelTask(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start an async repeat task
|
||||
*
|
||||
* @param r the runnable
|
||||
* @param interval the interval in ticks
|
||||
* @return the task id
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public static int ar(Runnable r, int interval) {
|
||||
return Bukkit.getScheduler().scheduleAsyncRepeatingTask(Iris.instance, r, 0, interval);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start an async repeating task for a limited time
|
||||
*
|
||||
* @param r the runnable
|
||||
* @param interval the interval
|
||||
* @param intervals the intervals to run
|
||||
*/
|
||||
public static void ar(Runnable r, int interval, int intervals) {
|
||||
FinalInteger fi = new FinalInteger(0);
|
||||
|
||||
new AR() {
|
||||
@Override
|
||||
public void run() {
|
||||
fi.add(1);
|
||||
r.run();
|
||||
|
||||
if (fi.get() >= intervals) {
|
||||
cancel();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
47
src/main/java/com/volmit/iris/util/scheduling/Looper.java
Normal file
47
src/main/java/com/volmit/iris/util/scheduling/Looper.java
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
|
||||
public abstract class Looper extends Thread {
|
||||
@SuppressWarnings("BusyWait")
|
||||
public void run() {
|
||||
while (!interrupted()) {
|
||||
try {
|
||||
long m = loop();
|
||||
|
||||
if (m < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
//noinspection BusyWait
|
||||
Thread.sleep(m);
|
||||
} catch (InterruptedException e) {Iris.reportError(e);
|
||||
break;
|
||||
} catch (Throwable e) {Iris.reportError(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
Iris.info("Thread " + getName() + " Shutdown.");
|
||||
}
|
||||
|
||||
protected abstract long loop();
|
||||
}
|
||||
62
src/main/java/com/volmit/iris/util/scheduling/O.java
Normal file
62
src/main/java/com/volmit/iris/util/scheduling/O.java
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util;
|
||||
|
||||
public class O<T> implements Observable<T> {
|
||||
private T t = null;
|
||||
private KList<Observer<T>> observers;
|
||||
|
||||
@Override
|
||||
public T get() {
|
||||
return t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public O<T> set(T t) {
|
||||
this.t = t;
|
||||
|
||||
if (observers != null && observers.hasElements()) {
|
||||
observers.forEach((o) -> o.onChanged(t, t));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has() {
|
||||
return t != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public O<T> clearObservers() {
|
||||
observers.clear();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public O<T> observe(Observer<T> t) {
|
||||
if (observers == null) {
|
||||
observers = new KList<>();
|
||||
}
|
||||
|
||||
observers.add(t);
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util;
|
||||
|
||||
public interface Observable<T> {
|
||||
T get();
|
||||
|
||||
Observable<T> set(T t);
|
||||
|
||||
boolean has();
|
||||
|
||||
Observable<T> clearObservers();
|
||||
|
||||
Observable<T> observe(Observer<T> t);
|
||||
}
|
||||
24
src/main/java/com/volmit/iris/util/scheduling/Observer.java
Normal file
24
src/main/java/com/volmit/iris/util/scheduling/Observer.java
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Observer<T> {
|
||||
void onChanged(T from, T to);
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util;
|
||||
|
||||
public class PrecisionStopwatch {
|
||||
private long nanos;
|
||||
private long startNano;
|
||||
private long millis;
|
||||
private long startMillis;
|
||||
private double time;
|
||||
private boolean profiling;
|
||||
|
||||
public static PrecisionStopwatch start() {
|
||||
PrecisionStopwatch p = new PrecisionStopwatch();
|
||||
p.begin();
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
public PrecisionStopwatch() {
|
||||
reset();
|
||||
profiling = false;
|
||||
}
|
||||
|
||||
public void begin() {
|
||||
profiling = true;
|
||||
startNano = System.nanoTime();
|
||||
startMillis = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public void end() {
|
||||
if (!profiling) {
|
||||
return;
|
||||
}
|
||||
|
||||
profiling = false;
|
||||
nanos = System.nanoTime() - startNano;
|
||||
millis = System.currentTimeMillis() - startMillis;
|
||||
time = (double) nanos / 1000000.0;
|
||||
time = (double) millis - time > 1.01 ? millis : time;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
nanos = -1;
|
||||
millis = -1;
|
||||
startNano = -1;
|
||||
startMillis = -1;
|
||||
time = -0;
|
||||
profiling = false;
|
||||
}
|
||||
|
||||
public double getTicks() {
|
||||
return getMilliseconds() / 50.0;
|
||||
}
|
||||
|
||||
public double getSeconds() {
|
||||
return getMilliseconds() / 1000.0;
|
||||
}
|
||||
|
||||
public double getMinutes() {
|
||||
return getSeconds() / 60.0;
|
||||
}
|
||||
|
||||
public double getHours() {
|
||||
return getMinutes() / 60.0;
|
||||
}
|
||||
|
||||
public double getMilliseconds() {
|
||||
nanos = System.nanoTime() - startNano;
|
||||
millis = System.currentTimeMillis() - startMillis;
|
||||
time = (double) nanos / 1000000.0;
|
||||
time = (double) millis - time > 1.01 ? millis : time;
|
||||
return time;
|
||||
}
|
||||
|
||||
public long getNanoseconds() {
|
||||
return (long) (time * 1000000.0);
|
||||
}
|
||||
|
||||
public long getNanos() {
|
||||
return nanos;
|
||||
}
|
||||
|
||||
public long getStartNano() {
|
||||
return startNano;
|
||||
}
|
||||
|
||||
public long getMillis() {
|
||||
return millis;
|
||||
}
|
||||
|
||||
public long getStartMillis() {
|
||||
return startMillis;
|
||||
}
|
||||
|
||||
public double getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public boolean isProfiling() {
|
||||
return profiling;
|
||||
}
|
||||
|
||||
public void rewind(long l) {
|
||||
startMillis -= l;
|
||||
}
|
||||
}
|
||||
49
src/main/java/com/volmit/iris/util/scheduling/Queue.java
Normal file
49
src/main/java/com/volmit/iris/util/scheduling/Queue.java
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util;
|
||||
|
||||
@SuppressWarnings("ALL")
|
||||
public interface Queue<T> {
|
||||
Queue<T> queue(T t);
|
||||
|
||||
Queue<T> queue(KList<T> t);
|
||||
|
||||
boolean hasNext(int amt);
|
||||
|
||||
boolean hasNext();
|
||||
|
||||
T next();
|
||||
|
||||
KList<T> next(int amt);
|
||||
|
||||
Queue<T> clear();
|
||||
|
||||
int size();
|
||||
|
||||
static <T> Queue<T> create(KList<T> t) {
|
||||
return new ShurikenQueue<T>().queue(t);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static <T> Queue<T> create(T... t) {
|
||||
return new ShurikenQueue<T>().queue(new KList<T>().add(t));
|
||||
}
|
||||
|
||||
boolean contains(T p);
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
|
||||
public class QueueExecutor extends Looper {
|
||||
private final Queue<Runnable> queue;
|
||||
private boolean shutdown;
|
||||
|
||||
public QueueExecutor() {
|
||||
queue = new ShurikenQueue<>();
|
||||
shutdown = false;
|
||||
}
|
||||
|
||||
public Queue<Runnable> queue() {
|
||||
return queue;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long loop() {
|
||||
while (queue.hasNext()) {
|
||||
try {
|
||||
queue.next().run();
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (shutdown && !queue.hasNext()) {
|
||||
interrupt();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return Math.max(500, (long) getRunTime() * 10);
|
||||
}
|
||||
|
||||
public double getRunTime() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
shutdown = true;
|
||||
}
|
||||
}
|
||||
29
src/main/java/com/volmit/iris/util/scheduling/S.java
Normal file
29
src/main/java/com/volmit/iris/util/scheduling/S.java
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util;
|
||||
|
||||
public abstract class S implements Runnable {
|
||||
public S() {
|
||||
J.s(this);
|
||||
}
|
||||
|
||||
public S(int delay) {
|
||||
J.s(this, delay);
|
||||
}
|
||||
}
|
||||
42
src/main/java/com/volmit/iris/util/scheduling/SR.java
Normal file
42
src/main/java/com/volmit/iris/util/scheduling/SR.java
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util;
|
||||
|
||||
import com.volmit.iris.util.plugin.CancellableTask;
|
||||
|
||||
public abstract class SR implements Runnable, CancellableTask {
|
||||
private int id = 0;
|
||||
|
||||
public SR() {
|
||||
this(0);
|
||||
}
|
||||
|
||||
public SR(int interval) {
|
||||
id = J.sr(this, interval);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
J.csr(id);
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util;
|
||||
|
||||
public class ShurikenQueue<T> implements Queue<T> {
|
||||
private KList<T> queue;
|
||||
private boolean randomPop;
|
||||
private boolean reversePop;
|
||||
|
||||
public ShurikenQueue() {
|
||||
clear();
|
||||
}
|
||||
|
||||
public ShurikenQueue<T> responsiveMode() {
|
||||
reversePop = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ShurikenQueue<T> randomMode() {
|
||||
randomPop = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShurikenQueue<T> queue(T t) {
|
||||
queue.add(t);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShurikenQueue<T> queue(KList<T> t) {
|
||||
queue.add(t);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext(int amt) {
|
||||
return queue.size() >= amt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return !queue.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
return reversePop ? queue.popLast() : randomPop ? queue.popRandom() : queue.pop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public KList<T> next(int amt) {
|
||||
KList<T> t = new KList<>();
|
||||
|
||||
for (int i = 0; i < amt; i++) {
|
||||
if (!hasNext()) {
|
||||
break;
|
||||
}
|
||||
|
||||
t.add(next());
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShurikenQueue<T> clear() {
|
||||
queue = new KList<>();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return queue.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(T p) {
|
||||
return queue.contains(p);
|
||||
}
|
||||
}
|
||||
42
src/main/java/com/volmit/iris/util/scheduling/Switch.java
Normal file
42
src/main/java/com/volmit/iris/util/scheduling/Switch.java
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util;
|
||||
|
||||
public class Switch {
|
||||
private volatile boolean b;
|
||||
|
||||
/**
|
||||
* Defaulted off
|
||||
*/
|
||||
public Switch() {
|
||||
b = false;
|
||||
}
|
||||
|
||||
public void flip() {
|
||||
b = true;
|
||||
}
|
||||
|
||||
public boolean isFlipped() {
|
||||
return b;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
b = false;
|
||||
}
|
||||
}
|
||||
205
src/main/java/com/volmit/iris/util/scheduling/TaskExecutor.java
Normal file
205
src/main/java/com/volmit/iris/util/scheduling/TaskExecutor.java
Normal file
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.util.function.NastyRunnable;
|
||||
import com.volmit.iris.util.math.M;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory;
|
||||
import java.util.concurrent.ForkJoinWorkerThread;
|
||||
|
||||
public class TaskExecutor {
|
||||
private int xc;
|
||||
private final ExecutorService service;
|
||||
|
||||
public TaskExecutor(int threadLimit, int priority, String name) {
|
||||
xc = 1;
|
||||
|
||||
if (threadLimit == 1) {
|
||||
service = Executors.newSingleThreadExecutor((r) ->
|
||||
{
|
||||
Thread t = new Thread(r);
|
||||
t.setName(name);
|
||||
t.setPriority(priority);
|
||||
|
||||
return t;
|
||||
});
|
||||
} else if (threadLimit > 1) {
|
||||
final ForkJoinWorkerThreadFactory factory = pool -> {
|
||||
final ForkJoinWorkerThread worker = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
|
||||
worker.setName(name + " " + xc++);
|
||||
worker.setPriority(priority);
|
||||
return worker;
|
||||
};
|
||||
|
||||
service = new ForkJoinPool(threadLimit, factory, null, false);
|
||||
} else {
|
||||
service = Executors.newCachedThreadPool((r) ->
|
||||
{
|
||||
Thread t = new Thread(r);
|
||||
t.setName(name + " " + xc++);
|
||||
t.setPriority(priority);
|
||||
|
||||
return t;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public TaskGroup startWork() {
|
||||
return new TaskGroup(this);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
J.a(() ->
|
||||
{
|
||||
J.sleep(10000);
|
||||
service.shutdown();
|
||||
});
|
||||
}
|
||||
|
||||
public void closeNow() {
|
||||
service.shutdown();
|
||||
}
|
||||
|
||||
public static class TaskGroup {
|
||||
private final KList<AssignedTask> tasks;
|
||||
private final TaskExecutor e;
|
||||
|
||||
public TaskGroup(TaskExecutor e) {
|
||||
tasks = new KList<>();
|
||||
this.e = e;
|
||||
}
|
||||
|
||||
public TaskGroup queue(NastyRunnable... r) {
|
||||
for (NastyRunnable i : r) {
|
||||
tasks.add(new AssignedTask(i));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public TaskGroup queue(KList<NastyRunnable> r) {
|
||||
for (NastyRunnable i : r) {
|
||||
tasks.add(new AssignedTask(i));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public TaskResult execute() {
|
||||
double timeElapsed = 0;
|
||||
int tasksExecuted = 0;
|
||||
int tasksFailed = 0;
|
||||
int tasksCompleted = 0;
|
||||
tasks.forEach((t) -> t.go(e));
|
||||
long msv = M.ns();
|
||||
|
||||
waiting:
|
||||
while (true) {
|
||||
try {
|
||||
//noinspection BusyWait
|
||||
Thread.sleep(0);
|
||||
} catch (InterruptedException ignored) {
|
||||
|
||||
}
|
||||
|
||||
for (AssignedTask i : tasks) {
|
||||
if (i.state.equals(TaskState.QUEUED) || i.state.equals(TaskState.RUNNING)) {
|
||||
continue waiting;
|
||||
}
|
||||
}
|
||||
|
||||
timeElapsed = (double) (M.ns() - msv) / 1000000D;
|
||||
|
||||
for (AssignedTask i : tasks) {
|
||||
if (i.state.equals(TaskState.COMPLETED)) {
|
||||
tasksCompleted++;
|
||||
} else {
|
||||
tasksFailed++;
|
||||
}
|
||||
|
||||
tasksExecuted++;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return new TaskResult(timeElapsed, tasksExecuted, tasksFailed, tasksCompleted);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("ClassCanBeRecord")
|
||||
@ToString
|
||||
public static class TaskResult {
|
||||
public TaskResult(double timeElapsed, int tasksExecuted, int tasksFailed, int tasksCompleted) {
|
||||
this.timeElapsed = timeElapsed;
|
||||
this.tasksExecuted = tasksExecuted;
|
||||
this.tasksFailed = tasksFailed;
|
||||
this.tasksCompleted = tasksCompleted;
|
||||
}
|
||||
|
||||
public final double timeElapsed;
|
||||
public final int tasksExecuted;
|
||||
public final int tasksFailed;
|
||||
public final int tasksCompleted;
|
||||
}
|
||||
|
||||
public enum TaskState {
|
||||
QUEUED,
|
||||
RUNNING,
|
||||
COMPLETED,
|
||||
FAILED
|
||||
}
|
||||
|
||||
public static class AssignedTask {
|
||||
@Getter
|
||||
@Setter
|
||||
private TaskState state;
|
||||
|
||||
@Getter
|
||||
private final NastyRunnable task;
|
||||
|
||||
public AssignedTask(NastyRunnable task) {
|
||||
this.task = task;
|
||||
state = TaskState.QUEUED;
|
||||
}
|
||||
|
||||
public void go(TaskExecutor e) {
|
||||
e.service.execute(() ->
|
||||
{
|
||||
state = TaskState.RUNNING;
|
||||
try {
|
||||
task.run();
|
||||
state = TaskState.COMPLETED;
|
||||
} catch (Throwable ex) {Iris.reportError(ex);
|
||||
ex.printStackTrace();
|
||||
Iris.reportError(ex);
|
||||
state = TaskState.FAILED;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
|
||||
/**
|
||||
* Not particularly efficient or perfectly accurate but is great at fast thread
|
||||
* switching detection
|
||||
*
|
||||
* @author dan
|
||||
*/
|
||||
public class ThreadMonitor extends Thread {
|
||||
private final Thread monitor;
|
||||
private boolean running;
|
||||
private State lastState;
|
||||
private final ChronoLatch cl;
|
||||
private PrecisionStopwatch st;
|
||||
int cycles = 0;
|
||||
private final RollingSequence sq = new RollingSequence(3);
|
||||
|
||||
private ThreadMonitor(Thread monitor) {
|
||||
running = true;
|
||||
st = PrecisionStopwatch.start();
|
||||
this.monitor = monitor;
|
||||
lastState = State.NEW;
|
||||
cl = new ChronoLatch(1000);
|
||||
start();
|
||||
}
|
||||
|
||||
public void run() {
|
||||
while (running) {
|
||||
try {
|
||||
//noinspection BusyWait
|
||||
Thread.sleep(0);
|
||||
State s = monitor.getState();
|
||||
if (lastState != s) {
|
||||
cycles++;
|
||||
pushState(s);
|
||||
}
|
||||
|
||||
lastState = s;
|
||||
|
||||
if (cl.flip()) {
|
||||
Iris.info("Cycles: " + Form.f(cycles) + " (" + Form.duration(sq.getAverage(), 2) + ")");
|
||||
}
|
||||
} catch (Throwable e) {Iris.reportError(e);
|
||||
running = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void pushState(State s) {
|
||||
if (s != State.RUNNABLE) {
|
||||
if (st != null) {
|
||||
sq.put(st.getMilliseconds());
|
||||
}
|
||||
} else {
|
||||
|
||||
st = PrecisionStopwatch.start();
|
||||
}
|
||||
}
|
||||
|
||||
public void unbind() {
|
||||
running = false;
|
||||
}
|
||||
|
||||
public static ThreadMonitor bind(Thread monitor) {
|
||||
return new ThreadMonitor(monitor);
|
||||
}
|
||||
}
|
||||
69
src/main/java/com/volmit/iris/util/scheduling/Wrapper.java
Normal file
69
src/main/java/com/volmit/iris/util/scheduling/Wrapper.java
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util;
|
||||
|
||||
public class Wrapper<T> {
|
||||
private T t;
|
||||
|
||||
public Wrapper(T t) {
|
||||
set(t);
|
||||
}
|
||||
|
||||
public void set(T t) {
|
||||
this.t = t;
|
||||
}
|
||||
|
||||
public T get() {
|
||||
return t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((t == null) ? 0 : t.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(obj instanceof Wrapper<?> other)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (t == null) {
|
||||
return other.t == null;
|
||||
} else return t.equals(other.t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (t != null) {
|
||||
return get().toString();
|
||||
}
|
||||
|
||||
return super.toString() + " (null)";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user