mirror of
https://github.com/SimplexDevelopment/SimplexSS.git
synced 2025-07-07 08:43:04 +00:00
Finalization
This commit is contained in:
@ -0,0 +1,221 @@
|
||||
package io.github.simplexdevelopment.scheduler;
|
||||
|
||||
import io.github.simplexdevelopment.api.IService;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract class ExecutableService implements IService {
|
||||
/**
|
||||
* The name of the service.
|
||||
*/
|
||||
private final String service_name;
|
||||
/**
|
||||
* How long the service should wait before executing the first time.
|
||||
*/
|
||||
private final long delay;
|
||||
/**
|
||||
* How long the service should wait between executions.
|
||||
*/
|
||||
private final long period;
|
||||
/**
|
||||
* If the service should be executed once or continuously.
|
||||
*/
|
||||
private final boolean repeating;
|
||||
/**
|
||||
* If the service should be allowed to stop while executing.
|
||||
*/
|
||||
private final boolean mayInterruptWhenRunning;
|
||||
/**
|
||||
* The service's execution thread.
|
||||
*/
|
||||
private ServicePool parentPool;
|
||||
/**
|
||||
* Whether the service has been cancelled or not.
|
||||
*/
|
||||
private boolean cancelled = false;
|
||||
|
||||
/**
|
||||
* Creates a new instance of an executable service.
|
||||
* Each service is registered with a {@link String},
|
||||
* to allow for easy identification within the associated {@link ServicePool}.
|
||||
*
|
||||
* @param service_name A namespaced key which can be used to identify the service.
|
||||
*/
|
||||
public ExecutableService(@NotNull String service_name) {
|
||||
this((new ServicePool("defaultPool" + SchedulingSystem.denom, false)),
|
||||
service_name,
|
||||
0L,
|
||||
0L,
|
||||
false,
|
||||
false);
|
||||
|
||||
SchedulingSystem.denom++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of an executable service.
|
||||
* Each service is registered with a {@link String},
|
||||
* to allow for easy identification within the associated {@link ServicePool}.
|
||||
*
|
||||
* @param parentPool The {@link ServicePool} which this service is executing on.
|
||||
* @param service_name A namespaced key which can be used to identify the service.
|
||||
*/
|
||||
public ExecutableService(@Nullable ServicePool parentPool, @NotNull String service_name) {
|
||||
this(parentPool,
|
||||
service_name,
|
||||
0L,
|
||||
0L,
|
||||
false,
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of an executable service.
|
||||
* The timings are measured in ticks (20 ticks per second).
|
||||
* You do not need to explicitly define a delay.
|
||||
* Each service is registered with a {@link String},
|
||||
* to allow for easy identification within the associated {@link ServicePool}.
|
||||
*
|
||||
* @param parentPool The {@link ServicePool} which this service is executing on.
|
||||
* @param service_name A namespaced key which can be used to identify the service.
|
||||
* @param delay A specified amount of time (in ticks) to wait before the service runs.
|
||||
*/
|
||||
public ExecutableService(
|
||||
@Nullable ServicePool parentPool,
|
||||
@NotNull String service_name,
|
||||
@Nullable Long delay) {
|
||||
this(parentPool,
|
||||
service_name,
|
||||
delay,
|
||||
0L,
|
||||
false,
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of an executable service.
|
||||
* The timings are measured in ticks (20 ticks per second).
|
||||
* You do not need to explicitly define a delay or a period,
|
||||
* however if you have flagged {@link #repeating} as true, and the period is null,
|
||||
* then the period will automatically be set to 20 minutes.
|
||||
* Each service is registered with a {@link String},
|
||||
* to allow for easy identification within the associated {@link ServicePool}.
|
||||
*
|
||||
* @param parentPool The {@link ServicePool} which this service is executing on.
|
||||
* @param service_name A namespaced key which can be used to identify the service.
|
||||
* @param delay A specified amount of time (in ticks) to wait before the service runs.
|
||||
* @param period How long the service should wait between service executions (in ticks).
|
||||
* @param repeating If the service should be scheduled for repeated executions or not.
|
||||
*/
|
||||
public ExecutableService(
|
||||
@Nullable ServicePool parentPool,
|
||||
@NotNull String service_name,
|
||||
@NotNull Long delay,
|
||||
@NotNull Long period,
|
||||
@NotNull Boolean repeating) {
|
||||
this(parentPool,
|
||||
service_name,
|
||||
delay, period,
|
||||
repeating,
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of an executable service.
|
||||
* The timings are measured in ticks (20 ticks per second).
|
||||
* You do not need to explicitly define a delay or a period,
|
||||
* however if you have flagged {@link #repeating} as true, and the period is null,
|
||||
* then the period will automatically be set to 20 minutes.
|
||||
* Each service is registered with a {@link String},
|
||||
* to allow for easy identification within the associated {@link ServicePool}.
|
||||
*
|
||||
* @param parentPool The {@link ServicePool} which this service is executing on.
|
||||
* @param service_name A namespaced key which can be used to identify the service.
|
||||
* @param delay A specified amount of time (in ticks) to wait before the service runs.
|
||||
* @param period How long the service should wait between service executions (in ticks).
|
||||
* @param repeating If the service should be scheduled for repeated executions or not.
|
||||
* @param mayInterruptWhenRunning If the service can be cancelled during execution.
|
||||
*/
|
||||
public ExecutableService(
|
||||
@Nullable ServicePool parentPool,
|
||||
@NotNull String service_name,
|
||||
@Nullable Long delay,
|
||||
@Nullable Long period,
|
||||
@NotNull Boolean repeating,
|
||||
@NotNull Boolean mayInterruptWhenRunning) {
|
||||
this.service_name = service_name;
|
||||
this.repeating = repeating;
|
||||
this.delay = Objects.requireNonNullElse(delay, 0L);
|
||||
this.period = Objects.requireNonNullElse(period, (20L * 60L) * 20L);
|
||||
this.mayInterruptWhenRunning = mayInterruptWhenRunning;
|
||||
this.parentPool = parentPool;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDelay() {
|
||||
return delay;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getPeriod() {
|
||||
return period;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPeriodic() {
|
||||
return repeating;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels the execution of this service.
|
||||
*
|
||||
* @return true if the service was cancelled, false if not.
|
||||
*/
|
||||
public boolean isCancelled() {
|
||||
return this.cancelled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels the execution of this service.
|
||||
*
|
||||
* @param cancel Whether the service should be cancelled or not.
|
||||
*/
|
||||
public Mono<Void> setCancelled(boolean cancel) {
|
||||
if (!mayInterruptWhenRunning) {
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
cancelled = cancel;
|
||||
return cancel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Actual stop call, to ensure that the service actually #isCancelled().
|
||||
*/
|
||||
@Contract(pure = true)
|
||||
Mono<Void> cancel() {
|
||||
if (isCancelled()) {
|
||||
return stop().then();
|
||||
}
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<ServicePool> getParentPool() {
|
||||
return Mono.just(parentPool);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return service_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> setParentPool(ServicePool servicePool) {
|
||||
return Mono.just(servicePool).doOnNext(pool -> this.parentPool = pool).then();
|
||||
}
|
||||
}
|
@ -40,7 +40,7 @@ public final class ReactorBukkitScheduler
|
||||
* @return A disposable that can be used to cancel the task.
|
||||
*/
|
||||
@Override
|
||||
public @NotNull Disposable schedule(@NotNull Runnable task, long delay, @Nullable TimeUnit unit) {
|
||||
public @NotNull Disposable schedule(@NotNull Runnable task, long delay, @Deprecated @Nullable TimeUnit unit) {
|
||||
return new BukkitDisposable(scheduler.runTaskLater(plugin, task, delay));
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ public final class ReactorBukkitScheduler
|
||||
* @return A disposable that can be used to cancel the task.
|
||||
*/
|
||||
@Override
|
||||
public @NotNull Disposable schedulePeriodically(@NotNull Runnable task, long initialDelay, long period, @Nullable TimeUnit unit) {
|
||||
public @NotNull Disposable schedulePeriodically(@NotNull Runnable task, long initialDelay, long period, @Deprecated @Nullable TimeUnit unit) {
|
||||
if (period <= 0L) {
|
||||
throw new IllegalArgumentException("Period must be greater than 0L");
|
||||
}
|
||||
@ -78,6 +78,7 @@ public final class ReactorBukkitScheduler
|
||||
* This method does nothing and is unused.
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public void dispose() {
|
||||
}
|
||||
}
|
||||
|
@ -6,40 +6,39 @@ import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import reactor.core.Disposable;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Scheduler;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
public final class SchedulingSystem<T extends JavaPlugin> implements ISchedule {
|
||||
/**
|
||||
* A denominator to use when registering default service pool names.
|
||||
*/
|
||||
static int denom = 0;
|
||||
/**
|
||||
* The service manager to use for controlling service pools.
|
||||
*/
|
||||
private final ServiceManager serviceManager;
|
||||
/**
|
||||
* The plugin to use for registering tasks. This should be an instance of your plugin.
|
||||
*/
|
||||
private final T plugin;
|
||||
private final Set<ServicePool> repeatingPools;
|
||||
/**
|
||||
* The main scheduler which this system runs on. This is an abstraction of the {@link BukkitScheduler},
|
||||
* and as a result runs on the Main server thread.
|
||||
*/
|
||||
private final ReactorBukkitScheduler mainScheduler;
|
||||
|
||||
/**
|
||||
* Creates a new instance of the scheduling system. This is used to manage the scheduling of services.
|
||||
*
|
||||
* @param plugin The plugin to use for this scheduling system. This should be an instance of your plugin.
|
||||
* @param plugin The plugin to use for this scheduling system. This should be an instance of your plugin.
|
||||
*/
|
||||
public SchedulingSystem(T plugin) {
|
||||
this.serviceManager = new ServiceManager();
|
||||
this.plugin = plugin;
|
||||
this.repeatingPools = new HashSet<>();
|
||||
this.mainScheduler = new ReactorBukkitScheduler(plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A set of {@link ServicePool}s which contain repeating services.
|
||||
*/
|
||||
@Contract(pure = true)
|
||||
public Set<ServicePool> getRepeatingPools() {
|
||||
return repeatingPools;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Mono<ServiceManager> getServiceManager() {
|
||||
return Mono.just(serviceManager);
|
||||
@ -47,20 +46,19 @@ public final class SchedulingSystem<T extends JavaPlugin> implements ISchedule {
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Mono<ServicePool> queue(@NotNull IService service) {
|
||||
return getServiceManager().flatMap(serviceManager -> {
|
||||
Mono<ServicePool> pool = serviceManager.getAssociatedServicePool(service);
|
||||
return pool.defaultIfEmpty(Objects.requireNonNull(serviceManager
|
||||
.createServicePool(ServicePool.getDefaultNamespacedKey(), service)
|
||||
.block()));
|
||||
});
|
||||
public Mono<Disposable> queue(@NotNull IService service) {
|
||||
return getServiceManager()
|
||||
.flatMap(manager -> manager.getAssociatedServicePool(service))
|
||||
.flatMap(pool -> pool.queueService(service));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Mono<Void> runOnce(IService service) {
|
||||
return Mono.just(service).doOnNext(s -> {
|
||||
s.start().then(s.stop()).subscribe();
|
||||
}).then();
|
||||
return Mono.just(service)
|
||||
.doOnNext(s -> s.start()
|
||||
.then(s.stop())
|
||||
.subscribe())
|
||||
.then();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,7 +1,6 @@
|
||||
package io.github.simplexdevelopment.scheduler;
|
||||
|
||||
import io.github.simplexdevelopment.api.IService;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import reactor.core.publisher.Flux;
|
||||
@ -12,6 +11,9 @@ import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public final class ServiceManager {
|
||||
/**
|
||||
* A set of {@link ServicePool}s which are currently active.
|
||||
*/
|
||||
private final Set<ServicePool> servicePools;
|
||||
|
||||
/**
|
||||
@ -32,7 +34,7 @@ public final class ServiceManager {
|
||||
* This service pool will execute each service consecutively within a singular non-blocking thread.
|
||||
*/
|
||||
@Contract(pure = true, value = "_, _ -> new")
|
||||
public @NotNull Mono<ServicePool> createServicePool(NamespacedKey poolName, IService... services) {
|
||||
public @NotNull Mono<ServicePool> createServicePool(String poolName, IService... services) {
|
||||
ServicePool pool = new ServicePool(poolName, false);
|
||||
Flux.fromIterable(Arrays.asList(services)).doOnEach(s -> pool.addService(s.get()));
|
||||
return Mono.just(pool);
|
||||
@ -45,7 +47,7 @@ public final class ServiceManager {
|
||||
* This service pool will execute each service across a set of non-blocking threads.
|
||||
*/
|
||||
@Contract(pure = true, value = "_, _ -> new")
|
||||
public @NotNull Mono<ServicePool> multithreadedServicePool(NamespacedKey name, IService... services) {
|
||||
public @NotNull Mono<ServicePool> multithreadedServicePool(String name, IService... services) {
|
||||
ServicePool pool = new ServicePool(name, true);
|
||||
Flux.fromIterable(Arrays.asList(services)).doOnEach(s -> pool.addService(s.get()));
|
||||
return Mono.just(pool);
|
||||
@ -60,7 +62,7 @@ public final class ServiceManager {
|
||||
* or by using {@link ServicePool#addService(IService)}.
|
||||
*/
|
||||
@Contract(pure = true, value = "_, _ -> new")
|
||||
public @NotNull Mono<ServicePool> emptyServicePool(NamespacedKey poolName, boolean multithreaded) {
|
||||
public @NotNull Mono<ServicePool> emptyServicePool(String poolName, boolean multithreaded) {
|
||||
ServicePool pool = new ServicePool(poolName, multithreaded);
|
||||
return Mono.just(pool);
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package io.github.simplexdevelopment.scheduler;
|
||||
|
||||
import io.github.simplexdevelopment.api.IService;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -18,9 +17,9 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
public final class ServicePool {
|
||||
/**
|
||||
* The default {@link NamespacedKey} used to identify unmarked services. This will cause errors if left unchecked.
|
||||
* The default {@link String} used to identify unmarked services. This will cause errors if left unchecked.
|
||||
*/
|
||||
private static final NamespacedKey DEFAULT = new NamespacedKey("simplex_ss", "default_service_pool");
|
||||
private static final String DEFAULT = "default_service_pool";
|
||||
/**
|
||||
* A collection of services related to this service pool.
|
||||
*/
|
||||
@ -30,9 +29,9 @@ public final class ServicePool {
|
||||
*/
|
||||
private final Scheduler scheduler;
|
||||
/**
|
||||
* The key used to identify this service pool.
|
||||
* The name used to identify this service pool.
|
||||
*/
|
||||
private final NamespacedKey name;
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* This will create a new instance of a Service Pool with a {@link Scheduler} as its main scheduler.
|
||||
@ -41,7 +40,7 @@ public final class ServicePool {
|
||||
* @param name The name of this service pool.
|
||||
* @param multithreaded Whether this service pool should be multithreaded, or operate upon a single thread.
|
||||
*/
|
||||
public ServicePool(NamespacedKey name, boolean multithreaded) {
|
||||
public ServicePool(String name, boolean multithreaded) {
|
||||
this.name = name;
|
||||
this.associatedServices = new HashSet<>();
|
||||
if (multithreaded) {
|
||||
@ -57,7 +56,7 @@ public final class ServicePool {
|
||||
*
|
||||
* @param name The name of this service pool.
|
||||
*/
|
||||
public ServicePool(NamespacedKey name, JavaPlugin plugin) {
|
||||
public ServicePool(String name, JavaPlugin plugin) {
|
||||
this.name = name;
|
||||
this.associatedServices = new HashSet<>();
|
||||
this.scheduler = new ReactorBukkitScheduler(plugin);
|
||||
@ -66,7 +65,7 @@ public final class ServicePool {
|
||||
/**
|
||||
* @return The default namespaced key to use if one is not assigned.
|
||||
*/
|
||||
static NamespacedKey getDefaultNamespacedKey() {
|
||||
static String getDefaultNamespacedKey() {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
@ -140,7 +139,7 @@ public final class ServicePool {
|
||||
* @param disposable A {@link Disposable} object which contains the service that should be disposed.
|
||||
* @return A {@link Mono<Void>} object which can be used to stop the service.
|
||||
*/
|
||||
public @NotNull Mono<Void> stopService(@NotNull NamespacedKey service_name, @Nullable Mono<Disposable> disposable) {
|
||||
public @NotNull Mono<Void> stopService(@NotNull String service_name, @Nullable Mono<Disposable> disposable) {
|
||||
getService(service_name).doOnNext(IService::stop).subscribe();
|
||||
if (disposable != null) {
|
||||
disposable.doOnNext(Disposable::dispose).subscribe();
|
||||
@ -152,9 +151,9 @@ public final class ServicePool {
|
||||
* @param service_name The name of the service to get.
|
||||
* @return A {@link Mono} object which contains the service.
|
||||
*/
|
||||
public @NotNull Mono<IService> getService(NamespacedKey service_name) {
|
||||
public @NotNull Mono<IService> getService(String service_name) {
|
||||
return Flux.fromIterable(getAssociatedServices())
|
||||
.filter(service -> service.getNamespacedKey().equals(service_name))
|
||||
.filter(service -> service.getName().equals(service_name))
|
||||
.next();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user