Button flickering eliminated, LockUI showMessage put on delay

This commit is contained in:
Maxmtg
2013-03-27 10:10:31 +00:00
parent 9b737b6ca7
commit 406e53d8ae
6 changed files with 60 additions and 15 deletions

View File

@@ -3,6 +3,8 @@ package forge;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
@@ -13,15 +15,16 @@ import forge.control.input.InputSynchronized;
* *
*/ */
public class FThreads { public class FThreads {
static { static {
System.out.printf("(FThreads static ctor): Running on a machine with %d cpu core(s)%n", Runtime.getRuntime().availableProcessors() ); 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(); private final static ExecutorService threadPool = Executors.newCachedThreadPool();
public static ExecutorService getCachedPool() { private static ExecutorService getCachedPool() { return threadPool; }
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 // 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) { public final static ExecutorService getComputingPool(float loadFactor) {
@@ -116,4 +119,9 @@ public class FThreads {
return SwingUtilities.isEventDispatchThread(); return SwingUtilities.isEventDispatchThread();
} }
public static void delay(int milliseconds, Runnable inputUpdater) {
getScheduledPool().schedule(inputUpdater, milliseconds, TimeUnit.MILLISECONDS);
}
} }

View File

@@ -59,5 +59,9 @@ public abstract class InputBase implements java.io.Serializable, Input {
afterStop(); // sync inputs will release their latch there afterStop(); // sync inputs will release their latch there
} }
protected final boolean isActive() {
return Singletons.getModel().getMatch().getInput().getInput() == this;
}
protected void afterStop() { } protected void afterStop() { }
} }

View File

@@ -64,7 +64,7 @@ public class InputControl extends MyObservable implements java.io.Serializable {
* @return a {@link forge.control.input.InputBase} object. * @return a {@link forge.control.input.InputBase} object.
*/ */
public final Input getInput() { public final Input getInput() {
return this.inputStack.peek(); return inputStack.isEmpty() ? null : this.inputStack.peek();
} }
/** /**

View File

@@ -1,5 +1,8 @@
package forge.control.input; package forge.control.input;
import java.util.concurrent.atomic.AtomicInteger;
import forge.FThreads;
import forge.view.ButtonUtil; import forge.view.ButtonUtil;
/** /**
@@ -9,9 +12,11 @@ import forge.view.ButtonUtil;
public class InputLockUI extends InputBase { public class InputLockUI extends InputBase {
private static final long serialVersionUID = 5777143577098597374L; private static final long serialVersionUID = 5777143577098597374L;
private final AtomicInteger iCall = new AtomicInteger();
public void showMessage() { public void showMessage() {
ButtonUtil.disableAll(); int ixCall = 1 + iCall.getAndIncrement();
//showMessage("Waiting for actions..."); FThreads.delay(500, new InputUpdater(ixCall));
} }
@Override @Override
@@ -19,4 +24,28 @@ public class InputLockUI extends InputBase {
return "lockUI"; 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...");
}
};
} }

View File

@@ -27,7 +27,6 @@ import forge.game.GameState;
import forge.game.MatchController; import forge.game.MatchController;
import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseHandler;
import forge.game.player.Player; import forge.game.player.Player;
import forge.view.ButtonUtil;
/** /**
* <p> * <p>
@@ -49,7 +48,7 @@ public class InputProxy implements Observer {
@Override @Override
public final synchronized void update(final Observable observable, final Object obj) { public final synchronized void update(final Observable observable, final Object obj) {
ButtonUtil.disableAll(); this.input = null;
final GameState game = match.getCurrentGame(); final GameState game = match.getCurrentGame();
final PhaseHandler ph = game.getPhaseHandler(); final PhaseHandler ph = game.getPhaseHandler();
@@ -81,7 +80,8 @@ public class InputProxy implements Observer {
* </p> * </p>
*/ */
public final void selectButtonOK() { public final void selectButtonOK() {
this.getInput().selectButtonOK(); if ( null == input ) return;
input.selectButtonOK();
} }
/** /**
@@ -90,7 +90,8 @@ public class InputProxy implements Observer {
* </p> * </p>
*/ */
public final void selectButtonCancel() { 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. * a {@link forge.game.player.Player} object.
*/ */
public final void selectPlayer(final Player player) { 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. * a {@link forge.game.zone.PlayerZone} object.
*/ */
public final void selectCard(final Card card) { public final void selectCard(final Card card) {
this.getInput().selectCard(card); if ( null == input ) return;
input.selectCard(card);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public final String toString() { public final String toString() {
return this.getInput().toString(); if ( null == input ) return "(null)";
return this.input.toString();
} }
/** @return {@link forge.gui.InputProxy.InputBase} */ /** @return {@link forge.gui.InputProxy.InputBase} */

View File

@@ -426,7 +426,7 @@ public class CField implements ICDoc {
((InputBlock) input).removeFromAllBlocking(c); ((InputBlock) input).removeFromAllBlocking(c);
CombatUtil.showCombat(); CombatUtil.showCombat();
} }
} else { } else if ( input != null ){
//Yosei, the Morning Star required cards to be chosen on computer side //Yosei, the Morning Star required cards to be chosen on computer side
//earlier it was enforced that cards must be in player zone //earlier it was enforced that cards must be in player zone
//this can potentially break some other functionality //this can potentially break some other functionality