A set of tools that simplify asynchronous development.
We use Semantic Versioning 2.0.0 to manage our releases.
- Easy to use
- Include reactor core
- ServerThread sync
- Chain-based wrappers for sync part of code with ServerThread
- On paper(and forks) 1.19.3+ enable circular loading
Download from our repository or depend via Gradle:
repositories {
maven("https://repo.animecraft.fun/repository/maven-snapshots/")
}
dependencies {
implementation("dev.ckateptb.minecraft:Atom:<version>")
}
- Import the dependency as shown above
- Add Atom as a dependency to your
plugin.yml
name: ...
version: ...
main: ...
depend: [ Atom ]
authors: ...
description: ...
- Run tasks in async thread
public class PluginExample extends JavaPlugin {
public PluginExample() {
Schedulers.boundedElastic().schedule(() -> {
// The common boundedElastic instance, a Scheduler that dynamically
// creates a bounded number of ExecutorService-based
// Workers, reusing them once the Workers have been
// shut down. The underlying daemon threads can be
// evicted if idle for more than 60 seconds.
});
Schedulers.single().schedule(() -> {
// The common single instance, a Scheduler that hosts a
// single-threaded ExecutorService-based worker.
// Only one instance of this common scheduler will be created
// on the first call and is cached. The same instance is returned
// on subsequent calls until it is disposed.
});
Schedulers.immediate().schedule(() -> {
// Executes tasks immediately instead of scheduling them.
});
Schedulers.parallel().schedule(() -> {
// The common parallel instance, a Scheduler that hosts
// a fixed pool of single-threaded ExecutorService-based
// workers and is suited for parallel work.
// Only one instance of this common scheduler will be created
// on the first call and is cached. The same instance is returned
// on subsequent calls until it is disposed.
});
Atom.syncScheduler().schedule(() -> {
// The bukkit tick thread instance, a Scheduler that
// can be used for sync sth with main server thread.
});
}
}
- Work with reactive stream more info
import dev.ckateptb.common.tableclothcontainer.IoC;
import dev.ckateptb.minecraft.atom.adapter.AdapterUtils;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.plugin.java.JavaPlugin;
import reactor.core.publisher.Flux;
import reactor.core.scheduler.Schedulers;
import java.util.Collection;
import java.util.Comparator;
public class PluginExample extends JavaPlugin {
public PluginExample() {
Location location = ...;
Mono.just(location)
.publishOn(Atom.syncScheduler()) // Switch to main-thread
.flatMapMany(value -> Flux.fromIterable(value.getNearbyEntities(20, 20, 20))) // Call AsyncCatchOp method
.publishOn(Schedulers.boundedElastic()) // Switch to other thread
.filter(entity -> entity instanceof LivingEntity) // filter entity is living
.sort(Comparator.comparingDouble(entity -> entity.getLocation().distanceSquared(location))) // sort by distance
.doOnNext(entity -> System.out.println("Wow, one more living entity!"))
.doOnSubscribe(subscription -> subscription.request(20)) // request 20 entity
.subscribe(living -> /*to do*/); // subscribe reactive stream
}
}
- Work with block
public class ThreadSafeBlockExample {
public void example() {
// Pseudo async block placement example with queue
Schedulers.boundedElastic().schedule(() -> // Async thread
Flux.fromIterable(blocks) // Flux from blocks iterator
// Declare queue 1 bpms = 50 bpt = 1000 bps
.concatMap(block -> Mono.just(block).delayElement(Duration.of(1, ChronoUnit.MILLIS)))
.publishOn(Atom.syncScheduler()) // Switch to main-thread
.subscribe(block -> block.setType(Material.AIR, false))); // do sth
}
}
- Start work