We are creating the main container class.
public class MyContainer extends Session {
public MyContainer(JavaPlugin plugin) {
super(plugin);
}
@NotNull
@Override
protected Board getDefaultStartBoard() {
return new MyBoard(this);
}
@Override
public void componentConstructor(ComponentConstructorEvent event) {
super.componentConstructor(event);
// To activate the controller, we need to add it to the container.
// To do this, we must provide the parent element of the tree in the constructor and call the start method.
new MyController(this).start();
}
}
We are creating a class responsible for the map within the container.
public class MyBoard extends Board {
public MyBoard(Session session) {
super(session);
}
}
We are creating a controller that will display Hello, world to players upon joining the container.
public class MyController extends Controller {
public MyController(ISessionComponent sessionComponent) {
super(sessionComponent);
}
@Override
public void playerConstructor(PlayerConstructorEvent event) {
super.playerConstructor(event);
var player = event.getPlayer();
player.sendMessage("Hello world!");
}
}
To run the container, you need to create a new instance and call the start method.
var containter = new MyContainer(plugin);
containter.start();
containter.addPlayer(player);
🎉 Congratulations! You've created your first container!
Tip
To separate the player's inventory state, you need to start the OtherEquipment
controller
new OtherEquipment(this).start();
public class SneakController extends Controller {
public SneakController(ISessionComponent sessionComponent) {
super(sessionComponent);
}
private static final int DIAMOND_COUNT = 9;
private int gameToggleSneakCounter = 0;
// must return an instance of the bukkit listener
@Override
public @Nullable Listener getListener() {
return new SneakListener();
}
public void toggleSneak() {
gameToggleSneakCounter++;
// broadcast message for container
getSession().getPlayers().forEach(player -> player.sendMessage("someone changed sneak state"));
if (gameToggleSneakCounter == 4) {
startFreeDiamondsTask();
}
}
public void startFreeDiamondsTask() {
// Running a controlled recurring task that ends with this controller
getProcess().runControlledTaskTimer(() -> {
for (var containerPlayer : getSession().getPlayers()) {
var eq = containerPlayer.getInventory();
eq.addItem(new ItemStack(Material.DIAMOND, DIAMOND_COUNT));
}
}, Time.Zero(), Time.Ticks(20));
}
}
public class SneakListener implements Listener {
@EventHandler(ignoreCancelled = true)
public void onPlayerToggleSneak(PlayerToggleSneakEvent event) {
var player = event.getPlayer();
var session = SessionManager.getSession(player);
var sneakControllers = ControllerManager.getControllers(session, SneakController.class);
for (var controller : sneakControllers)
controller.toggleSneak();
}
}
Structure:
- MyContainer (root)
- MyBoard
- MyGroupController
- MyHasteController
- MySpeedController
- MyCookieController
public class MyGroupController extends Controller {
// ...
@Override
public void componentConstructor(ComponentConstructorEvent event) {
super.componentConstructor(event);
new MyHasteController(this).start();
new MySpeedController(this).start();
}
}
public class MyHasteController extends Controller {
// ...
@Override
public void playerConstructor(PlayerConstructorEvent event) {
super.playerConstructor(event);
event.getPlayer()
.addPotionEffect(new PotionEffect(PotionEffectType.FAST_DIGGING, PotionEffect.INFINITE_DURATION, 9));
}
@Override
public void playerDestructor(PlayerDestructorEvent event) {
super.playerDestructor(event);
event.getPlayer().removePotionEffect(PotionEffectType.FAST_DIGGING);
}
}
public class MySpeedController extends Controller {
// ...
@Override
public void componentConstructor(ComponentConstructorEvent event) {
super.componentConstructor(event);
new MyCookieController(this).start();
}
@Override
public void playerConstructor(PlayerConstructorEvent event) {
super.playerConstructor(event);
event.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.SPEED, PotionEffect.INFINITE_DURATION, 9));
}
@Override
public void playerDestructor(PlayerDestructorEvent event) {
super.playerDestructor(event);
event.getPlayer().removePotionEffect(PotionEffectType.SPEED);
}
}
public class MyCookieController extends Controller {
// ...
@Override
public void componentConstructor(ComponentConstructorEvent event) {
super.componentConstructor(event);
getProcess().runControlledTaskTimer(() -> {
for (var containerPlayer : getSession().getPlayers()) {
var eq = containerPlayer.getInventory();
eq.addItem(new ItemStack(Material.COOKIE));
}
}, Time.Zero(), Time.Ticks(20));
}
}
public class MyContainer extends Session {
// ...
@Override
public void componentConstructor(ComponentConstructorEvent event) {
super.componentConstructor(event);
var groupController = new MyGroupController(this);
groupController.start();
// End the 'MyGroupController' after 3 seconds
getProcess().runControlledTaskLater(groupController::stop, Time.Seconds(3));
}
}
It demonstrates that removing the "groupController" triggers cascading removal of subordinate controllers and threads.