mirror of
https://github.com/SimplexDevelopment/SimplexSS.git
synced 2025-07-01 22:56:42 +00:00
Finalization
This commit is contained in:
@ -1,31 +1,34 @@
|
||||
package io.github.simplexdevelopment.api;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Objects;
|
||||
|
||||
public interface Context<S> {
|
||||
/**
|
||||
* @return A Mono object which contains a single element represented by the definer of this Context class.
|
||||
*/
|
||||
Mono<S> getContext();
|
||||
@NotNull Mono<S> getContext();
|
||||
|
||||
/**
|
||||
* @param context A separate (or identical) object identified by the definer of this Context class.
|
||||
* @return A Mono object which can be used to set the element of this Context class in a non-blocking manner.
|
||||
*/
|
||||
Mono<Void> setContext(S context);
|
||||
@NotNull Mono<Void> setContext(S context);
|
||||
|
||||
/**
|
||||
* @return A collection of objects related to the definer of this Context class.
|
||||
*/
|
||||
Collection<S> contextCollection();
|
||||
@Nullable Collection<S> contextCollection();
|
||||
|
||||
/**
|
||||
* @return A Flux object which contains the values of the {@link Context#contextCollection()}, for non-blocking interpretation.
|
||||
*/
|
||||
default Flux<S> fluxFromCollection() {
|
||||
return Flux.fromIterable(contextCollection());
|
||||
default @Nullable Flux<S> fluxFromCollection() {
|
||||
return contextCollection() == null ? null : Flux.fromIterable(Objects.requireNonNull(contextCollection()));
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
package io.github.simplexdevelopment.api;
|
||||
|
||||
import io.github.simplexdevelopment.scheduler.ServiceManager;
|
||||
import io.github.simplexdevelopment.scheduler.ServicePool;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import reactor.core.Disposable;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public interface ISchedule {
|
||||
@ -12,11 +13,12 @@ public interface ISchedule {
|
||||
Mono<ServiceManager> getServiceManager();
|
||||
|
||||
/**
|
||||
* Queues a service to be executed in a service pool.
|
||||
*
|
||||
* @param service The service to use to locate the associated service pool and queue the service for execution.
|
||||
* @return A Mono<ServicePool> that can be used to prepare the service for execution within it's associated service pool.
|
||||
* If the service has no associated pool, a new pool will be created.
|
||||
* @return A Mono<Disposable> that can be used to cancel the service.
|
||||
*/
|
||||
Mono<ServicePool> queue(IService service);
|
||||
@NotNull Mono<Disposable> queue(@NotNull IService service);
|
||||
|
||||
/**
|
||||
* @param service The service to run once.
|
||||
@ -35,4 +37,4 @@ public interface ISchedule {
|
||||
* @return A Mono<Void> object which can be used to forcefully start the service with {@link Mono#subscribe()}.
|
||||
*/
|
||||
Mono<Void> forceStart(IService service);
|
||||
}
|
||||
}
|
@ -1,22 +1,12 @@
|
||||
package io.github.simplexdevelopment.api;
|
||||
|
||||
import io.github.simplexdevelopment.scheduler.ServicePool;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public interface IService extends Runnable {
|
||||
@Contract(" -> new")
|
||||
static @NotNull NamespacedKey getDefaultNamespacedKey() {
|
||||
return new NamespacedKey("simplex_ss", "default_service_name");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The NamespacedKey of this service.
|
||||
*/
|
||||
NamespacedKey getNamespacedKey();
|
||||
public interface IService extends Runnable, Identifier {
|
||||
|
||||
/**
|
||||
* @return If the service should be scheduled for repeated executions or not.
|
||||
@ -60,24 +50,16 @@ public interface IService extends Runnable {
|
||||
*/
|
||||
Mono<ServicePool> getParentPool();
|
||||
|
||||
/**
|
||||
* Sets the parent pool for this service.
|
||||
*
|
||||
* @param servicePool The service pool to attach this service to.
|
||||
* @return An encapsulated Mono object representing the set operation.
|
||||
*/
|
||||
Mono<Void> setParentPool(ServicePool servicePool);
|
||||
|
||||
@Override
|
||||
default void run() {
|
||||
start().subscribeOn(getParentPool()
|
||||
.map(ServicePool::getScheduler)
|
||||
.blockOptional()
|
||||
.orElseThrow(InvalidServicePoolException.supplyException()))
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is an easy static call for creating a new namespaced key for services and service pools.
|
||||
*
|
||||
* @param space The namespace of the service.
|
||||
* @param key The key name of the service.
|
||||
* @return A NamespacedKey object representing the service.
|
||||
*/
|
||||
@Contract("_, _ -> new")
|
||||
static @NotNull NamespacedKey newNamespacedKey(String space, String key) {
|
||||
return new NamespacedKey(space, key);
|
||||
start().subscribe();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,26 @@
|
||||
package io.github.simplexdevelopment.api;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public interface Identifier {
|
||||
/**
|
||||
* @return The name of the identifiable object in a readable format.
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* @return The UUID of the identifiable object, based on the {@link Identifier#getName()} value.
|
||||
* This is calculated using {@link UUID#nameUUIDFromBytes(byte[])}.
|
||||
*/
|
||||
default UUID getUniqueId() {
|
||||
return UUID.nameUUIDFromBytes(getName().getBytes());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The numerical id of the identifiable object, based on the {@link Identifier#getUniqueId()} value.
|
||||
* This is calculated using {@link UUID#hashCode()}.
|
||||
*/
|
||||
default int getNumericalId() {
|
||||
return getUniqueId().hashCode();
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package io.github.simplexdevelopment.api;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class InvalidServiceException extends RuntimeException {
|
||||
public InvalidServiceException(IService service) {
|
||||
super("The service " + service.getNamespacedKey().getKey() + " is not present within any service pool.");
|
||||
}
|
||||
|
||||
public InvalidServiceException(Throwable th) {
|
||||
super(th);
|
||||
}
|
||||
|
||||
public static Supplier<InvalidServiceException> supplyException(IService service) {
|
||||
return () -> new InvalidServiceException(service);
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
package io.github.simplexdevelopment.api;
|
||||
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class InvalidServicePoolException extends RuntimeException {
|
||||
public InvalidServicePoolException() {
|
||||
super("There is no service pool associated with this service. The service will be automatically recycled.");
|
||||
}
|
||||
|
||||
public InvalidServicePoolException(@NotNull String string) {
|
||||
super(string);
|
||||
}
|
||||
|
||||
public InvalidServicePoolException(Throwable ex) {
|
||||
super(ex);
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
public static @NotNull Supplier<InvalidServicePoolException> supplyException() {
|
||||
return InvalidServicePoolException::new;
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package io.github.simplexdevelopment.api;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ServiceException extends RuntimeException {
|
||||
/**
|
||||
* Constructs a new service exception which states the service is not present within any service pools.
|
||||
*
|
||||
* @param service The service that threw the exception.
|
||||
*/
|
||||
public ServiceException(IService service) {
|
||||
super("The service " + service.getName() + " is not present within any service pool.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param th The throwable that was thrown.
|
||||
*/
|
||||
public ServiceException(Throwable th) {
|
||||
super(th);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param service The service that threw the exception.
|
||||
* @return A supplier that can be used in conjunction with Reactor.
|
||||
*/
|
||||
public static Supplier<ServiceException> supplyException(IService service) {
|
||||
return () -> new ServiceException(service);
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package io.github.simplexdevelopment.api;
|
||||
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ServicePoolException extends RuntimeException {
|
||||
/**
|
||||
* Constructs a new generic service pool exception.
|
||||
* This will be thrown when a service attempts to execute without an associated service pool.
|
||||
*/
|
||||
public ServicePoolException() {
|
||||
super("There is no service pool associated with this service. The service will be automatically recycled.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string The message to be displayed when the exception is thrown.
|
||||
*/
|
||||
public ServicePoolException(@NotNull String string) {
|
||||
super(string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ex The exception to be thrown.
|
||||
*/
|
||||
public ServicePoolException(Throwable ex) {
|
||||
super(ex);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A supplier which can be used in conjunction with Reactor.
|
||||
*/
|
||||
@Contract(pure = true)
|
||||
public static @NotNull Supplier<ServicePoolException> supplyException() {
|
||||
return ServicePoolException::new;
|
||||
}
|
||||
}
|
@ -1,29 +1,32 @@
|
||||
package io.github.simplexdevelopment.impl;
|
||||
|
||||
import io.github.simplexdevelopment.api.IService;
|
||||
import io.github.simplexdevelopment.scheduler.SchedulingSystem;
|
||||
import io.github.simplexdevelopment.scheduler.ServiceManager;
|
||||
import io.github.simplexdevelopment.scheduler.ServicePool;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import reactor.core.Disposable;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
public class Main extends JavaPlugin {
|
||||
public ServicePool pool = new ServicePool(IService.newNamespacedKey("pool", "one"), true);
|
||||
private SchedulingSystem<Main> scheduler;
|
||||
private Flux<Disposable> disposables;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
// Plugin startup logic
|
||||
// Create a new instance of the scheduling system.
|
||||
this.scheduler = new SchedulingSystem<>(this);
|
||||
IService service = new ServiceImpl(this);
|
||||
service.getParentPool().subscribe(element -> disposables = element.startServices());
|
||||
// This will register all the services and set our Flux<Disposable> object above.
|
||||
registerServices(new PoolHolder(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
// Plugin shutdown logic
|
||||
// This will dispose of all the services we have previously registered in our Flux<Disposable> object.
|
||||
scheduler.getServiceManager().subscribe(manager -> {
|
||||
manager.getServicePools().doOnEach(signal -> Objects.requireNonNull(signal.get())
|
||||
.stopServices(disposables)
|
||||
@ -31,6 +34,27 @@ public class Main extends JavaPlugin {
|
||||
});
|
||||
}
|
||||
|
||||
public void registerServices(@NotNull PoolHolder poolHolder) {
|
||||
// This set will be used to set the Flux<Disposable> object
|
||||
// that will be used to stop the services when the plugin is disabled.
|
||||
Set<Disposable> dispos = new HashSet<>();
|
||||
|
||||
// Register services here
|
||||
ServiceImpl impl = new ServiceImpl(this, poolHolder.getContext().block());
|
||||
|
||||
// This will register the service to the service pool.
|
||||
dispos.add(scheduler.getMainScheduler().schedule(impl));
|
||||
// OR
|
||||
scheduler.queue(impl).subscribe(dispos::add);
|
||||
// OR
|
||||
scheduler.getServiceManager()
|
||||
.flatMap(manager -> manager.createServicePool("newPool", impl))
|
||||
.subscribe(p -> p.queueService(impl).subscribe(dispos::add));
|
||||
|
||||
// This will set the Flux<Disposable> object on our previously made set, so that we can use it later on.
|
||||
disposables = Flux.fromIterable(dispos);
|
||||
}
|
||||
|
||||
public SchedulingSystem<Main> getScheduler() {
|
||||
return this.scheduler;
|
||||
}
|
||||
|
@ -0,0 +1,36 @@
|
||||
package io.github.simplexdevelopment.impl;
|
||||
|
||||
import io.github.simplexdevelopment.api.Context;
|
||||
import io.github.simplexdevelopment.scheduler.ServicePool;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
public class PoolHolder implements Context<ServicePool> {
|
||||
private final Collection<ServicePool> servicePoolCollection = new ArrayList<>();
|
||||
private ServicePool selectedPool;
|
||||
|
||||
public PoolHolder(Main plugin) {
|
||||
this.servicePoolCollection.add(new ServicePool("Pool-One", plugin));
|
||||
this.servicePoolCollection.add(new ServicePool("Pool-Two", true));
|
||||
this.servicePoolCollection.add(new ServicePool("Pool-Three", false));
|
||||
this.selectedPool = servicePoolCollection.stream().findFirst().orElseGet(() -> new ServicePool("Default", plugin));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Mono<ServicePool> getContext() {
|
||||
return Mono.just(selectedPool);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Mono<Void> setContext(ServicePool context) {
|
||||
return Mono.just(context).doOnNext(pool -> this.selectedPool = pool).then();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ServicePool> contextCollection() {
|
||||
return servicePoolCollection;
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
package io.github.simplexdevelopment.impl;
|
||||
|
||||
import io.github.simplexdevelopment.api.ExecutableService;
|
||||
import io.github.simplexdevelopment.api.IService;
|
||||
import io.github.simplexdevelopment.scheduler.ExecutableService;
|
||||
import io.github.simplexdevelopment.scheduler.ServicePool;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import reactor.core.publisher.Mono;
|
||||
@ -9,8 +8,8 @@ import reactor.core.publisher.Mono;
|
||||
public class ServiceImpl extends ExecutableService {
|
||||
private final Main plugin;
|
||||
|
||||
public ServiceImpl(Main plugin) {
|
||||
super(plugin.pool, IService.getDefaultNamespacedKey(), 0L, 20 * 60 * 20L, true, false);
|
||||
public ServiceImpl(Main plugin, ServicePool pool) {
|
||||
super(pool, "default", 0L, 20 * 60 * 20L, true, false);
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@ -34,12 +33,4 @@ public class ServiceImpl extends ExecutableService {
|
||||
public Main getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<ServicePool> getParentPool() {
|
||||
return getPlugin()
|
||||
.getScheduler()
|
||||
.getServiceManager()
|
||||
.flatMap(manager -> manager.getAssociatedServicePool(this));
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package io.github.simplexdevelopment.api;
|
||||
package io.github.simplexdevelopment.scheduler;
|
||||
|
||||
import io.github.simplexdevelopment.scheduler.ServicePool;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import io.github.simplexdevelopment.api.IService;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@ -10,43 +9,75 @@ import reactor.core.publisher.Mono;
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract class ExecutableService implements IService {
|
||||
private final NamespacedKey service_name;
|
||||
/**
|
||||
* 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;
|
||||
|
||||
private boolean cancelled = false;
|
||||
/**
|
||||
* 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 NamespacedKey},
|
||||
* 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 NamespacedKey service_name) {
|
||||
this((new ServicePool(IService.newNamespacedKey("", ""), false)), service_name, 0L, 0L, false, false);
|
||||
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 NamespacedKey},
|
||||
* 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 NamespacedKey service_name) {
|
||||
this(parentPool, service_name, 0L, 0L, false, false);
|
||||
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 NamespacedKey},
|
||||
* 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.
|
||||
@ -55,9 +86,14 @@ public abstract class ExecutableService implements IService {
|
||||
*/
|
||||
public ExecutableService(
|
||||
@Nullable ServicePool parentPool,
|
||||
@NotNull NamespacedKey service_name,
|
||||
@NotNull String service_name,
|
||||
@Nullable Long delay) {
|
||||
this(parentPool, service_name, delay, 0L, false, false);
|
||||
this(parentPool,
|
||||
service_name,
|
||||
delay,
|
||||
0L,
|
||||
false,
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -66,7 +102,7 @@ public abstract class ExecutableService implements IService {
|
||||
* 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 NamespacedKey},
|
||||
* 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.
|
||||
@ -77,11 +113,15 @@ public abstract class ExecutableService implements IService {
|
||||
*/
|
||||
public ExecutableService(
|
||||
@Nullable ServicePool parentPool,
|
||||
@NotNull NamespacedKey service_name,
|
||||
@NotNull String service_name,
|
||||
@NotNull Long delay,
|
||||
@NotNull Long period,
|
||||
@NotNull Boolean repeating) {
|
||||
this(parentPool, service_name, delay, period, repeating, false);
|
||||
this(parentPool,
|
||||
service_name,
|
||||
delay, period,
|
||||
repeating,
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -90,7 +130,7 @@ public abstract class ExecutableService implements IService {
|
||||
* 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 NamespacedKey},
|
||||
* 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.
|
||||
@ -102,7 +142,7 @@ public abstract class ExecutableService implements IService {
|
||||
*/
|
||||
public ExecutableService(
|
||||
@Nullable ServicePool parentPool,
|
||||
@NotNull NamespacedKey service_name,
|
||||
@NotNull String service_name,
|
||||
@Nullable Long delay,
|
||||
@Nullable Long period,
|
||||
@NotNull Boolean repeating,
|
||||
@ -115,11 +155,6 @@ public abstract class ExecutableService implements IService {
|
||||
this.parentPool = parentPool;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NamespacedKey getNamespacedKey() {
|
||||
return service_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDelay() {
|
||||
return delay;
|
||||
@ -173,4 +208,14 @@ public abstract class ExecutableService implements IService {
|
||||
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