Commit 197216de authored by Vincent van Beveren's avatar Vincent van Beveren

added stateful task for asynchronous data stuff

parent 010e9bbf
TODO:
MUST
- Fix float conversiona
Cosmetics:
Saving of window state, file locations, etc..
Internal improvement:
Better appContext, disallow cloning while editing
SHOULD
- Benchmark I2C library. EEPROM access is *very* slow... may need own bindings (Oh no...)
NICE TO HAVE
- Use depdency injection instead of singletons
nl.nikhef.sfp.MultiSFPProvider
nl.nikhef.sfp.SimSFPProvider
nl.nikhef.sfp.VirtualSFPProvider
# nl.nikhef.sfp.SimSFPProvider
# nl.nikhef.sfp.VirtualSFPProvider
......@@ -54,7 +54,7 @@ public class PageDataSource extends DataSource {
void writeMedia(DDMIContext ctx, int off, byte[] data)
{
selectPage(ctx);
Utils.dumpHex("Page: " + _pageNo + ", Writign " + off + ":" + data.length, data);
// Utils.dumpHex("Page: " + _pageNo + ", Writign " + off + ":" + data.length, data);
_parent.writeMedia(ctx, off, data);
}
......
......@@ -22,15 +22,22 @@ public class ActiveLogArea extends TextArea {
@Override
public void publish(final LogRecord record) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
String txt = String.format("[%s] %s (%s)\n", record.getLevel(), _format.formatMessage(record), record.getLoggerName());
append(txt);
}
});
if (SwingUtilities.isEventDispatchThread()) {
String txt = String.format("[%s] %s (%s)\n", record.getLevel(), _format.formatMessage(record), record.getLoggerName());
append(txt);
} else {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
String txt = String.format("[%s] %s (%s)\n", record.getLevel(), _format.formatMessage(record), record.getLoggerName());
append(txt);
}
});
}
}
......
package nl.nikhef.safaripark;
import javax.inject.Inject;
import nl.nikhef.sfp.SFPManager;
import nl.nikhef.sfp.ddmi.DDMILoader;
......@@ -10,6 +12,7 @@ public class AppContext {
public final OverlayManager ovlMgr;
public final ContextCache ctxCache;
@Inject
public AppContext(SFPManager sfpMgr, DDMILoader ddmiLdr, OverlayManager ovlMgr) {
this.sfpMgr = sfpMgr;
this.ddmiLdr = ddmiLdr;
......
......@@ -48,6 +48,7 @@ import nl.nikhef.safaripark.dolly.DollyPanel;
import nl.nikhef.safaripark.editpane.EditPane;
import nl.nikhef.safaripark.extra.ExtendedAbstractAction;
import nl.nikhef.safaripark.extra.GuiUtils;
import nl.nikhef.safaripark.extra.StatefulTask;
import nl.nikhef.safaripark.monitor.Monitor;
import nl.nikhef.safaripark.res.Resources;
import nl.nikhef.sfp.SFPDevice;
......@@ -92,6 +93,8 @@ public class SaFariPark extends JFrame implements BaySelectionListener, WindowLi
_modMgr.exportBinary(SaFariPark.this);
}
};
private StatefulTask _task;
......@@ -125,7 +128,7 @@ public class SaFariPark extends JFrame implements BaySelectionListener, WindowLi
_devMgr.addDeviceSelectedListener(_modMgr);
DollyModel dm = new DollyModel(appCtx.ctxCache);
appCtx.sfpMgr.addSFPProviderListener(dm);
_dp = new DollyPanel(appCtx.ddmiLdr, dm);
_dp = new DollyPanel(appCtx.ddmiLdr, dm, this);
makeToolbar();
JSplitPane splitTop = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
splitTop.setDividerLocation(300);
......@@ -232,6 +235,30 @@ public class SaFariPark extends JFrame implements BaySelectionListener, WindowLi
return loader;
}
}
private Runnable _taskRunner = new Runnable() {
@Override
public void run()
{
if (_task.execute()) {
_task = null;
_status.setProgress(0, 100);
} else {
_status.setProgress(_task.getProgress(), 100);
SwingUtilities.invokeLater(this);
}
}
};
public void executeTask(StatefulTask task)
{
if (_task != null) return;
_task = task;
SwingUtilities.invokeLater(_taskRunner);
}
public static void main(String[] args)
......
......@@ -48,19 +48,28 @@ public class StatusBar extends JPanel {
@Override
public void publish(final LogRecord record) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
if (record.getLevel().intValue() < Level.INFO.intValue()) return;
String txt = _format.formatMessage(record);
setStatus(txt);
}
});
if (SwingUtilities.isEventDispatchThread()) {
if (record.getLevel().intValue() < Level.INFO.intValue()) return;
String txt = _format.formatMessage(record);
setStatus(txt);
} else {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
if (record.getLevel().intValue() < Level.INFO.intValue()) return;
String txt = _format.formatMessage(record);
setStatus(txt);
}
});
}
}
......
......@@ -11,9 +11,11 @@ import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListModel;
import javax.swing.ListModel;
import javax.swing.SwingUtilities;
import nl.nikhef.safaripark.ContextCache;
import nl.nikhef.safaripark.extra.Module;
import nl.nikhef.safaripark.extra.StatefulTask;
import nl.nikhef.sfp.SFPDevice;
import nl.nikhef.sfp.SFPDeviceListener;
import nl.nikhef.sfp.SFPProvider;
......@@ -150,6 +152,115 @@ public class DollyModel implements SFPDeviceListener, SFPProviderListener {
}
private enum CloneState {
PREPARE, CLONE, FINISH
}
private class CloneTask implements StatefulTask
{
private CloneState _state = CloneState.PREPARE;
private ValueGetter _vg;
private List<ValueSetter> _vs = new ArrayList<ValueSetter>();
private int _counter = 0;
public CloneTask()
{
}
@Override
public int getProgress() {
switch (_state) {
case PREPARE:
return 0;
case CLONE:
return (_counter * 100) / _selectedValues.size();
case FINISH:
return 100;
default:
return -1;
}
}
@Override
public boolean execute() {
switch (_state)
{
case PREPARE:
if (_sourceFile != null) {
try {
_vg = new FileValueGetter(_sourceFile);
} catch (IOException e) {
LOG.severe(String.format("Clone failed, could not load file %s: %s", _sourceFile.getPath(), e));
return true;
}
} else {
_vg = new ModuleValueGetter(_cc, _sourceModule);
}
for (Module m : _targetModules) {
_vs.add(new ModuleValueSetter(_cc, m));
}
if (_targetFile != null) {
_vs.add(new FileValueSetter(_targetFile));
}
_state = CloneState.CLONE;
break;
case CLONE:
DDMIValue v = _selectedValues.get(_counter);
LOG.info("Copying value " + v.getLabel());
byte[] value;
try {
value = _vg.getValue(v);
} catch (IOException e) {
LOG.severe("Clone failed : " + e);
break;
}
if (value != null && value.length > 0) {
for (ValueSetter setter : _vs) {
try {
setter.setValue(v, value);
} catch (IOException e) {
LOG.warning(String.format("Failed to set value %s to %s: %s", v, setter, e));
}
}
}
_counter++;
if (_counter >= _selectedValues.size()) {
_state = CloneState.FINISH;
}
break;
case FINISH:
for (ValueSetter setter : _vs) {
try {
setter.finished();
} catch (IOException e) {
LOG.warning(String.format("Failed to finish %s: %s", setter, e));
}
}
LOG.info(String.format("Cloned %d value(s) to %d output(s)", _selectedValues.size(), _vs.size()));
return true;
}
return false;
}
}
public StatefulTask getCloneTask()
{
return new CloneTask();
}
public void doClone() {
ValueGetter vg;
......@@ -167,6 +278,7 @@ public class DollyModel implements SFPDeviceListener, SFPProviderListener {
List<ValueSetter> vs = new ArrayList<ValueSetter>();
for (Module m : _targetModules) {
vs.add(new ModuleValueSetter(_cc, m));
}
......@@ -178,6 +290,7 @@ public class DollyModel implements SFPDeviceListener, SFPProviderListener {
for (DDMIValue v : _selectedValues)
{
LOG.info("Copying value " + v.getLabel());
byte[] value;
try {
value = vg.getValue(v);
......
......@@ -23,8 +23,10 @@ import javax.swing.JTextField;
import javax.swing.filechooser.FileNameExtensionFilter;
import net.miginfocom.swing.MigLayout;
import nl.nikhef.safaripark.SaFariPark;
import nl.nikhef.safaripark.Title;
import nl.nikhef.safaripark.extra.CheckableList;
import nl.nikhef.safaripark.extra.GuiUtils;
import nl.nikhef.safaripark.extra.Module;
import nl.nikhef.safaripark.res.Resources;
import nl.nikhef.safaripark.vsp.ValueSelectionPane;
......@@ -57,11 +59,13 @@ public class DollyPanel extends JPanel implements ActionListener, ItemListener {
private DollyModel _model;
private JFileChooser _fileChooser;
private SaFariPark _sfp;
public DollyPanel(DDMILoader loader, DollyModel model) {
public DollyPanel(DDMILoader loader, DollyModel model, SaFariPark sfp) {
_model = model;
_sfp = sfp;
setLayout(new BorderLayout());
add(new Title("Clone Tool", Resources.getIcon("emblem-documents")), BorderLayout.NORTH);
......@@ -178,7 +182,7 @@ public class DollyPanel extends JPanel implements ActionListener, ItemListener {
@Override
public void actionPerformed(ActionEvent e) {
_model.doClone();
_sfp.executeTask(_model.getCloneTask());
}
});
......
......@@ -6,6 +6,7 @@ import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JToolBar;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
public final class GuiUtils {
......@@ -30,5 +31,28 @@ public final class GuiUtils {
}
}
private static class StatefulRunner implements Runnable
{
private StatefulTask _task;
public StatefulRunner(StatefulTask task) {
_task = task;
}
@Override
public void run() {
if (_task.execute()) return;
SwingUtilities.invokeLater(this);
}
}
public static void executeStatefulTask(final StatefulTask cloneTask)
{
SwingUtilities.invokeLater(new StatefulRunner(cloneTask));
}
}
package nl.nikhef.safaripark.extra;
public interface StatefulTask {
/**
* Does one iteration of a task.
*
* @return true if completed, false otherwise.
*/
public boolean execute();
/**
* Returns the progress as a value between 0 and 100, or -1 if unknown.
*/
public int getProgress();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment