I've a problem with a plugin for MC and I need an infinite loop which await the condition to be satisfiated. But it create an infinite loop but the variable have changed. Here is the code :
boolean bState;
public boolean GetState(){
return bState;
}
public void SetState(boolean bState) {
this.bState = bState;
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) throws InterruptedException {
Player player = event.getPlayer();
if (event.getAction().equals(Action.RIGHT_CLICK_BLOCK) && event.getClickedBlock().getType() == Material.CHEST && event.getItem().getType() == Material.DIAMOND_SWORD) {
Chest chest = (Chest) event.getClickedBlock().getState();
event.setCancelled(true);
Inventory inv = chest.getInventory();
inv.getContents();
Inventory sinv = Bukkit.createInventory(player, chest.getInventory().getSize());
sinv.setContents(inv.getContents());
SetState(false);
player.openInventory(sinv);
while(GetState() == false){
getLogger().info("Ok");
}
//Some other things to do
}
}
@EventHandler
public void onPlayerCloseInv(InventoryCloseEvent event) {
Player player = (Player) event.getPlayer();
SetState(true);
}
I'm sure at 100% that the event onPlayerCloseInv is triggered after onPlayerInteract. Can anyone help me ? Thank you :D
EDIT: With my new code onPlayerCloseInv doesn't start anyone have an idea ?
With bukkit, you have the principle of a single main thread only.
Because this thread can only do 1 thing at a time, you cannot use spinlocks to wait for conditions, as a spinlock essentially keeps the thread busy.
setState
While this is the easiest method, using the will, you will lose track of your local variables.
public void SetState(boolean bState) {
if(this.bState == false && bState == true) {
//Some other things to do
getLogger().info('Inventory closed');
}
this.bState = bState;
}
While this method suffers of the penalty of a new lamba instance, and a slightly more obfuscated stack trace, it offers benefit in the fact that using this, you have access to all your local (implied) final variables.
Runnable closeTask = null;
public void SetState(boolean bState) {
if(this.bState == false && bState == true ) {
if(closeTask != null) {
closeTask.run();
closeTask = null;
}
}
this.bState = bState;
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) throws InterruptedException {
Player player = event.getPlayer();
if (event.getAction().equals(Action.RIGHT_CLICK_BLOCK) && event.getClickedBlock().getType() == Material.CHEST && event.getItem().getType() == Material.DIAMOND_SWORD) {
...
player.openInventory(sinv);
closeTask = () => {
//Some other things to do
getLogger().info('Inventory closed');
};
}
}