mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 19:28:01 +00:00
Button flickering eliminated, LockUI showMessage put on delay
This commit is contained in:
@@ -3,6 +3,8 @@ package forge;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
@@ -13,15 +15,16 @@ import forge.control.input.InputSynchronized;
|
||||
*
|
||||
*/
|
||||
public class FThreads {
|
||||
|
||||
static {
|
||||
System.out.printf("(FThreads static ctor): Running on a machine with %d cpu core(s)%n", Runtime.getRuntime().availableProcessors() );
|
||||
}
|
||||
|
||||
private FThreads() { } // no instances supposed
|
||||
|
||||
private final static ExecutorService threadPool = Executors.newCachedThreadPool();
|
||||
public static ExecutorService getCachedPool() {
|
||||
return threadPool;
|
||||
}
|
||||
private static ExecutorService getCachedPool() { return threadPool; }
|
||||
private final static ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(1);
|
||||
private static ScheduledExecutorService getScheduledPool() { return scheduledPool; }
|
||||
|
||||
// This pool is designed to parallel CPU or IO intensive tasks like parse cards or download images, assuming a load factor of 0.5
|
||||
public final static ExecutorService getComputingPool(float loadFactor) {
|
||||
@@ -115,5 +118,10 @@ public class FThreads {
|
||||
public static boolean isEDT() {
|
||||
return SwingUtilities.isEventDispatchThread();
|
||||
}
|
||||
|
||||
|
||||
public static void delay(int milliseconds, Runnable inputUpdater) {
|
||||
getScheduledPool().schedule(inputUpdater, milliseconds, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -58,6 +58,10 @@ public abstract class InputBase implements java.io.Serializable, Input {
|
||||
Singletons.getModel().getMatch().getInput().removeInput(this);
|
||||
afterStop(); // sync inputs will release their latch there
|
||||
}
|
||||
|
||||
protected final boolean isActive() {
|
||||
return Singletons.getModel().getMatch().getInput().getInput() == this;
|
||||
}
|
||||
|
||||
protected void afterStop() { }
|
||||
}
|
||||
@@ -64,7 +64,7 @@ public class InputControl extends MyObservable implements java.io.Serializable {
|
||||
* @return a {@link forge.control.input.InputBase} object.
|
||||
*/
|
||||
public final Input getInput() {
|
||||
return this.inputStack.peek();
|
||||
return inputStack.isEmpty() ? null : this.inputStack.peek();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package forge.control.input;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.view.ButtonUtil;
|
||||
|
||||
/**
|
||||
@@ -9,14 +12,40 @@ import forge.view.ButtonUtil;
|
||||
public class InputLockUI extends InputBase {
|
||||
private static final long serialVersionUID = 5777143577098597374L;
|
||||
|
||||
private final AtomicInteger iCall = new AtomicInteger();
|
||||
|
||||
public void showMessage() {
|
||||
ButtonUtil.disableAll();
|
||||
//showMessage("Waiting for actions...");
|
||||
int ixCall = 1 + iCall.getAndIncrement();
|
||||
FThreads.delay(500, new InputUpdater(ixCall));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "lockUI";
|
||||
}
|
||||
|
||||
private class InputUpdater implements Runnable {
|
||||
final int ixCall;
|
||||
|
||||
public InputUpdater(final int idxCall) {
|
||||
ixCall = idxCall;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if ( ixCall != iCall.get() || !isActive()) // cancel the message if it's not from latest call or input is gone already
|
||||
return;
|
||||
FThreads.invokeInEDT(showMessageFromEdt);
|
||||
}
|
||||
};
|
||||
|
||||
private final Runnable showMessageFromEdt = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
ButtonUtil.disableAll();
|
||||
showMessage("Waiting for actions...");
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ import forge.game.GameState;
|
||||
import forge.game.MatchController;
|
||||
import forge.game.phase.PhaseHandler;
|
||||
import forge.game.player.Player;
|
||||
import forge.view.ButtonUtil;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -49,7 +48,7 @@ public class InputProxy implements Observer {
|
||||
|
||||
@Override
|
||||
public final synchronized void update(final Observable observable, final Object obj) {
|
||||
ButtonUtil.disableAll();
|
||||
this.input = null;
|
||||
final GameState game = match.getCurrentGame();
|
||||
final PhaseHandler ph = game.getPhaseHandler();
|
||||
|
||||
@@ -81,7 +80,8 @@ public class InputProxy implements Observer {
|
||||
* </p>
|
||||
*/
|
||||
public final void selectButtonOK() {
|
||||
this.getInput().selectButtonOK();
|
||||
if ( null == input ) return;
|
||||
input.selectButtonOK();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,7 +90,8 @@ public class InputProxy implements Observer {
|
||||
* </p>
|
||||
*/
|
||||
public final void selectButtonCancel() {
|
||||
this.getInput().selectButtonCancel();
|
||||
if ( null == input ) return;
|
||||
input.selectButtonCancel();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,7 +103,8 @@ public class InputProxy implements Observer {
|
||||
* a {@link forge.game.player.Player} object.
|
||||
*/
|
||||
public final void selectPlayer(final Player player) {
|
||||
this.getInput().selectPlayer(player);
|
||||
if ( null == input ) return;
|
||||
input.selectPlayer(player);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -116,13 +118,15 @@ public class InputProxy implements Observer {
|
||||
* a {@link forge.game.zone.PlayerZone} object.
|
||||
*/
|
||||
public final void selectCard(final Card card) {
|
||||
this.getInput().selectCard(card);
|
||||
if ( null == input ) return;
|
||||
input.selectCard(card);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public final String toString() {
|
||||
return this.getInput().toString();
|
||||
if ( null == input ) return "(null)";
|
||||
return this.input.toString();
|
||||
}
|
||||
|
||||
/** @return {@link forge.gui.InputProxy.InputBase} */
|
||||
|
||||
@@ -426,7 +426,7 @@ public class CField implements ICDoc {
|
||||
((InputBlock) input).removeFromAllBlocking(c);
|
||||
CombatUtil.showCombat();
|
||||
}
|
||||
} else {
|
||||
} else if ( input != null ){
|
||||
//Yosei, the Morning Star required cards to be chosen on computer side
|
||||
//earlier it was enforced that cards must be in player zone
|
||||
//this can potentially break some other functionality
|
||||
|
||||
Reference in New Issue
Block a user