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