Fix prompting mechanics

Signed-off-by: Emmanuel Bigeon <emmanuel@bigeon.fr>
This commit is contained in:
Emmanuel Bigeon 2018-05-10 11:29:11 -04:00
parent 926a8d72fa
commit eae7e0d69f

View File

@ -60,28 +60,28 @@ import fr.bigeon.gclc.tools.StringProvider;
public final class SWTConsole extends Composite
implements ConsoleDelayIO, ConsoleInput, ConsoleOutput {
/** The number of columns of the layout. */
private static final int LAYOUT_NB_COLUMNS = 2;
private static final int LAYOUT_NB_COLUMNS = 2;
/** The cmd prefix in the output console. */
private static final String CMD_PREFIX = "[CMD] "; //$NON-NLS-1$
private static final String CMD_PREFIX = "[CMD] "; //$NON-NLS-1$
/** The class logger. */
private static final Logger LOGGER = Logger
private static final Logger LOGGER = Logger
.getLogger(SWTConsole.class.getName());
/** The empty string constant. */
private static final String EMPTY = ""; //$NON-NLS-1$
private static final String EMPTY = ""; //$NON-NLS-1$
/** The console output text field. */
private final Text consoleOutput;
private final Text consoleOutput;
/** The console input text field. */
private final Text consoleInput;
private final Text consoleInput;
/** The prompt label. */
private final Label lblPromptlabel;
private final Label lblPromptlabel;
/** The prompt text. */
private StringProvider prompt = new ConstantString("> "); //$NON-NLS-1$
private StringProvider prompt = new ConstantString("> "); //$NON-NLS-1$
/** The command entered by the user. */
private String command = null;
private String command = null;
/** If the prompt should be active. */
private boolean prompting = false;
private boolean prompting = false;
/** The object for thread synchronization with the prompt. */
private final Object promptLock = new Object();
private final Object promptLock = new Object();
/** Create the composite.
*
@ -92,18 +92,17 @@ public final class SWTConsole extends Composite
setLayout(new GridLayout(LAYOUT_NB_COLUMNS, false));
consoleOutput = new Text(this, SWT.BORDER | SWT.READ_ONLY | SWT.WRAP |
SWT.V_SCROLL | SWT.MULTI);
consoleOutput.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true,
LAYOUT_NB_COLUMNS, 1));
consoleOutput = new Text(this,
SWT.BORDER | SWT.READ_ONLY | SWT.WRAP | SWT.V_SCROLL | SWT.MULTI);
consoleOutput.setLayoutData(
new GridData(SWT.FILL, SWT.FILL, true, true, LAYOUT_NB_COLUMNS, 1));
consoleOutput.setRedraw(true);
lblPromptlabel = new Label(this, SWT.NONE);
lblPromptlabel.setText(prompt.apply());
consoleInput = new Text(this, SWT.BORDER);
consoleInput.setLayoutData(
new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
consoleInput.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
consoleInput.addKeyListener(new HistoryTextKeyListener(this));
}
@ -213,22 +212,24 @@ public final class SWTConsole extends Composite
}
try {
Display.getDefault().syncExec(new Runnable() {
@SuppressWarnings("synthetic-access")
@Override
public void run() {
if (!consoleInput.isDisposed()) {
consoleInput.setEnabled(true);
lblPromptlabel.setText(prompt.apply());
// relayout
SWTConsole.this.layout();
consoleInput.setFocus();
}
}
});
prompting = true;
promptLock.notifyAll();
promptLock.wait();
while (prompting) {
promptLock.wait();
}
} catch (final InterruptedException e) {
LOGGER.log(Level.WARNING,
"Error in synchronization of prompting", e); //$NON-NLS-1$
LOGGER.log(Level.WARNING, "Error in synchronization of prompting", e); //$NON-NLS-1$
command = null;
Thread.currentThread().interrupt();
}
@ -240,13 +241,45 @@ public final class SWTConsole extends Composite
}
/* (non-Javadoc)
* @see fr.bigeon.gclc.manager.ConsoleInput#prompt(long)
*/
* @see fr.bigeon.gclc.manager.ConsoleInput#prompt(long) */
@Override
public String prompt(final long timeout) throws IOException {
// TODO Auto-generated method stub
// return null;
throw new RuntimeException("Not implemented yet");
synchronized (promptLock) {
if (isDisposed()) {
throw new IOException();
}
try {
Display.getDefault().syncExec(new Runnable() {
@Override
public void run() {
if (!consoleInput.isDisposed()) {
consoleInput.setEnabled(true);
lblPromptlabel.setText(prompt.apply());
// relayout
SWTConsole.this.layout();
consoleInput.setFocus();
}
}
});
prompting = true;
command = null;
promptLock.notifyAll();
long start = System.currentTimeMillis();
long cur = start;
while (prompting && start + timeout>cur) {
promptLock.wait((cur-start-timeout)/2);
cur = System.currentTimeMillis();
}
} catch (final InterruptedException e) {
LOGGER.log(Level.WARNING, "Error in synchronization of prompting", e); //$NON-NLS-1$
command = null;
Thread.currentThread().interrupt();
}
}
if (isDisposed()) {
throw new IOException("Input closed"); //$NON-NLS-1$
}
return command;
}
/* (non-Javadoc)
@ -277,8 +310,7 @@ public final class SWTConsole extends Composite
throw new IOException();
}
} catch (final InterruptedException e) {
LOGGER.log(Level.WARNING,
"Error in synchronization of prompting", e); //$NON-NLS-1$
LOGGER.log(Level.WARNING, "Error in synchronization of prompting", e); //$NON-NLS-1$
command = null;
Thread.currentThread().interrupt();
} finally {
@ -299,8 +331,7 @@ public final class SWTConsole extends Composite
}
/* (non-Javadoc)
* @see fr.bigeon.gclc.manager.ConsoleInput#prompt(java.lang.String, long)
*/
* @see fr.bigeon.gclc.manager.ConsoleInput#prompt(java.lang.String, long) */
@Override
public String prompt(final String message, final long timeout) throws IOException {
// TODO Auto-generated method stub
@ -340,10 +371,10 @@ public final class SWTConsole extends Composite
}
});
}
@Override
public void setPrompt(String prompt) {
setPrompt(new ConstantString(prompt));
setPrompt(new ConstantString(prompt));
}
/** @param string the text */
@ -375,8 +406,7 @@ public final class SWTConsole extends Composite
try {
promptLock.wait();
} catch (final InterruptedException e) {
LOGGER.log(Level.SEVERE,
"Interruption while waiting prompt", e); //$NON-NLS-1$
LOGGER.log(Level.SEVERE, "Interruption while waiting prompt", e); //$NON-NLS-1$
}
}
Display.getDefault().syncExec(new Runnable() {
@ -386,8 +416,7 @@ public final class SWTConsole extends Composite
command = consoleInput.getText();
prompting = false;
consoleInput.setText(EMPTY);
consoleOutput.append(
CMD_PREFIX + command + System.lineSeparator());
consoleOutput.append(CMD_PREFIX + command + System.lineSeparator());
}
});
promptLock.notifyAll();