Added proxies for USARTListener and StateChangeListener to support multiple listeners

This commit is contained in:
Niclas Finne 2012-04-13 18:28:38 +02:00
parent eb10168150
commit 6ab9662686
16 changed files with 113 additions and 79 deletions

View File

@ -45,7 +45,6 @@ package se.sics.mspsim.chip;
import se.sics.mspsim.core.Chip;
import se.sics.mspsim.core.MSP430Core;
import se.sics.mspsim.core.StateChangeListener;
import se.sics.mspsim.util.ArrayUtils;
import se.sics.mspsim.util.Utils;
public class Leds extends Chip {
@ -53,7 +52,7 @@ public class Leds extends Chip {
private final int[] ledColors;
private int leds;
private StateChangeListener[] stateListeners;
private StateChangeListener stateListener;
public Leds(MSP430Core cpu, int[] ledColors) {
super("Leds", cpu);
@ -89,20 +88,18 @@ public class Leds extends Chip {
}
private void fireStateChanged(int oldState, int newState) {
StateChangeListener[] listeners = this.stateListeners;
if (listeners != null) {
for(StateChangeListener listener : listeners) {
listener.stateChanged(this, oldState, newState);
}
StateChangeListener listener = this.stateListener;
if (listener != null) {
listener.stateChanged(this, oldState, newState);
}
}
public synchronized void addStateChangeListener(StateChangeListener l) {
this.stateListeners = (StateChangeListener[]) ArrayUtils.add(StateChangeListener.class, this.stateListeners, l);
public synchronized void addStateChangeListener(StateChangeListener listener) {
stateListener = StateChangeListener.Proxy.INSTANCE.add(stateListener, listener);
}
public synchronized void removeStateChangeListener(StateChangeListener l) {
this.stateListeners = (StateChangeListener[]) ArrayUtils.remove(this.stateListeners, l);
public synchronized void removeStateChangeListener(StateChangeListener listener) {
stateListener = StateChangeListener.Proxy.INSTANCE.remove(stateListener, listener);
}
public int getModeMax() {

View File

@ -61,7 +61,7 @@ public class TR1001 extends Chip implements RFListener, RFSource {
this.usart = usart;
setModeNames(MODE_NAMES);
setMode(MODE_TXRX_OFF);
usart.setUSARTListener(new USARTListener() {
usart.addUSARTListener(new USARTListener() {
public void dataReceived(USARTSource source, int data) {
RFListener listener = rfListener;

View File

@ -57,7 +57,7 @@ public abstract class Chip implements Loggable, EventSource {
protected final MSP430Core cpu;
private OperatingModeListener[] omListeners;
private StateChangeListener[] scListeners;
private StateChangeListener stateListener;
private ConfigurationChangeListener[] ccListeners;
private EventListener eventListener;
@ -86,27 +86,27 @@ public abstract class Chip implements Loggable, EventSource {
}
public void addOperatingModeListener(OperatingModeListener listener) {
omListeners = (OperatingModeListener[]) ArrayUtils.add(OperatingModeListener.class, omListeners, listener);
omListeners = ArrayUtils.add(OperatingModeListener.class, omListeners, listener);
}
public void removeOperatingModeListener(OperatingModeListener listener) {
omListeners = (OperatingModeListener[]) ArrayUtils.remove(omListeners, listener);
omListeners = ArrayUtils.remove(omListeners, listener);
}
public void addStateChangeListener(StateChangeListener listener) {
scListeners = (StateChangeListener[]) ArrayUtils.add(StateChangeListener.class, scListeners, listener);
}
public void removeStateChangeListener(StateChangeListener listener) {
scListeners = (StateChangeListener[]) ArrayUtils.remove(scListeners, listener);
public synchronized void addStateChangeListener(StateChangeListener listener) {
stateListener = StateChangeListener.Proxy.INSTANCE.add(stateListener, listener);
}
public synchronized void removeStateChangeListener(StateChangeListener listener) {
stateListener = StateChangeListener.Proxy.INSTANCE.remove(stateListener, listener);
}
public void addConfigurationChangeListener(ConfigurationChangeListener listener) {
ccListeners = (ConfigurationChangeListener[]) ArrayUtils.add(ConfigurationChangeListener.class, ccListeners, listener);
}
ccListeners = ArrayUtils.add(ConfigurationChangeListener.class, ccListeners, listener);
}
public void removeConfigurationChangeListener(ConfigurationChangeListener listener) {
ccListeners = (ConfigurationChangeListener[]) ArrayUtils.remove(ccListeners, listener);
ccListeners = ArrayUtils.remove(ccListeners, listener);
}
@ -172,11 +172,9 @@ public abstract class Chip implements Loggable, EventSource {
int oldState = chipState;
chipState = newState;
/* inform listeners */
StateChangeListener[] listeners = scListeners;
if (listeners != null) {
for (int i = 0, n = listeners.length; i < n; i++) {
listeners[i].stateChanged(this, oldState, chipState);
}
StateChangeListener listener = stateListener;
if (listener != null) {
listener.stateChanged(this, oldState, chipState);
}
}
}

View File

@ -29,7 +29,7 @@ public class GenericUSCI extends IOUnit implements DMATrigger, USARTSource {
public static final int SWRST = 0x01;
private USARTListener listener;
private USARTListener usartListener;
private int ubr0;
private int ubr1;
@ -148,6 +148,7 @@ public class GenericUSCI extends IOUnit implements DMATrigger, USARTSource {
if (transmitting) {
/* in this case we have shifted out the last character */
USARTListener listener = this.usartListener;
if (listener != null && txShiftReg != -1) {
listener.dataReceived(this, txShiftReg);
}
@ -331,8 +332,14 @@ public class GenericUSCI extends IOUnit implements DMATrigger, USARTSource {
}
/* reuse USART listener API for USCI */
public void setUSARTListener(USARTListener listener) {
this.listener = listener;
@Override
public synchronized void addUSARTListener(USARTListener listener) {
usartListener = USARTListener.Proxy.INSTANCE.add(usartListener, listener);
}
@Override
public synchronized void removeUSARTListener(USARTListener listener) {
usartListener = USARTListener.Proxy.INSTANCE.remove(usartListener, listener);
}
/* default behavior assumes UART/SPI config */

View File

@ -43,8 +43,6 @@ package se.sics.mspsim.core;
import java.io.PrintStream;
import se.sics.mspsim.util.ArrayUtils;
public abstract class IOUnit implements InterruptHandler, Loggable {
int[] memory;
@ -53,7 +51,7 @@ public abstract class IOUnit implements InterruptHandler, Loggable {
protected final String id;
protected final String name;
private StateChangeListener[] scListeners;
private StateChangeListener stateListener;
private int ioState;
protected EmulationLogger logger;
@ -72,11 +70,11 @@ public abstract class IOUnit implements InterruptHandler, Loggable {
}
public void addStateChangeListener(StateChangeListener listener) {
scListeners = (StateChangeListener[]) ArrayUtils.add(StateChangeListener.class, scListeners, listener);
}
stateListener = StateChangeListener.Proxy.INSTANCE.add(stateListener, listener);
}
public void removeStateChangeListener(StateChangeListener listener) {
scListeners = (StateChangeListener[]) ArrayUtils.remove(scListeners, listener);
stateListener = StateChangeListener.Proxy.INSTANCE.remove(stateListener, listener);
}
@ -84,16 +82,14 @@ public abstract class IOUnit implements InterruptHandler, Loggable {
stateChanged(newState, false);
}
/* Called by subclasses to inform about changes of state */
protected void stateChanged(int newState, boolean forceCallback) {
protected void stateChanged(int newState, boolean forceCallback) {
if (forceCallback || ioState != newState) {
int oldState = ioState;
ioState = newState;
/* inform listeners */
StateChangeListener[] listeners = scListeners;
if (listeners != null) {
for (int i = 0, n = listeners.length; i < n; i++) {
listeners[i].stateChanged(this, oldState, ioState);
}
StateChangeListener listener = stateListener;
if (listener != null) {
listener.stateChanged(this, oldState, ioState);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, Swedish Institute of Computer Science.
* Copyright (c) 2010-2012, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -28,19 +28,16 @@
*
* This file is part of MSPSim.
*
* $Id$
*
* -----------------------------------------------------------------
*
* StateChangeListener
*
* Authors : Joakim Eriksson, Niclas Finne
* Created : 17 jul 2010
* Updated : $Date$
* $Revision$
*/
package se.sics.mspsim.core;
import se.sics.mspsim.util.ProxySupport;
/**
*
@ -49,4 +46,16 @@ public interface StateChangeListener {
public void stateChanged(Object source, int oldState, int newState);
public static class Proxy extends ProxySupport<StateChangeListener> implements StateChangeListener {
public static final Proxy INSTANCE = new Proxy();
@Override
public void stateChanged(Object source, int oldState, int newState) {
StateChangeListener[] listeners = this.listeners;
for(StateChangeListener listener : listeners) {
listener.stateChanged(source, oldState, newState);
}
}
}
}

View File

@ -1,5 +1,5 @@
/**
* Copyright (c) 2007, Swedish Institute of Computer Science.
* Copyright (c) 2007-2012, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -27,16 +27,12 @@
*
* This file is part of MSPSim.
*
* $Id$
*
* -----------------------------------------------------------------
*
* USART
*
* Author : Joakim Eriksson
* Created : Sun Oct 21 22:00:00 2007
* Updated : $Date$
* $Revision$
*/
package se.sics.mspsim.core;
@ -82,7 +78,7 @@ public class USART extends IOUnit implements SFRModule, DMATrigger, USARTSource
public static final int UTCTL_TXEMPTY = 0x01;
public static final int UTCTL_URXSE = 0x08;
private USARTListener listener;
private USARTListener usartListener;
private int utxifg;
private int urxifg;
@ -208,8 +204,14 @@ public class USART extends IOUnit implements SFRModule, DMATrigger, USARTSource
return sfr.isIEBitsSet(uartID, bits);
}
public void setUSARTListener(USARTListener listener) {
this.listener = listener;
@Override
public synchronized void addUSARTListener(USARTListener listener) {
usartListener = USARTListener.Proxy.INSTANCE.add(usartListener, listener);
}
@Override
public synchronized void removeUSARTListener(USARTListener listener) {
usartListener = USARTListener.Proxy.INSTANCE.remove(usartListener, listener);
}
// Only 8 bits / read!
@ -371,6 +373,7 @@ public class USART extends IOUnit implements SFRModule, DMATrigger, USARTSource
if (transmitting) {
/* in this case we have shifted out the last character */
USARTListener listener = this.usartListener;
if (listener != null && txShiftReg != -1) {
listener.dataReceived(this, txShiftReg);
}

View File

@ -1,5 +1,5 @@
/**
* Copyright (c) 2007, Swedish Institute of Computer Science.
* Copyright (c) 2007-2012, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -27,21 +27,33 @@
*
* This file is part of MSPSim.
*
* $Id$
*
* -----------------------------------------------------------------
*
* USARTListener
*
* Author : Joakim Eriksson
* Created : Sun Oct 21 22:00:00 2007
* Updated : $Date$
* $Revision$
*/
package se.sics.mspsim.core;
import se.sics.mspsim.util.ProxySupport;
public interface USARTListener {
public static final int RXFLAG_CLEARED = 1;
public void dataReceived(USARTSource source, int data);
public static final int RXFLAG_CLEARED = 1;
public void dataReceived(USARTSource source, int data);
public static class Proxy extends ProxySupport<USARTListener> implements USARTListener {
public static final Proxy INSTANCE = new Proxy();
@Override
public void dataReceived(USARTSource source, int data) {
USARTListener[] listeners = this.listeners;
for(USARTListener listener : listeners) {
listener.dataReceived(source, data);
}
}
}
}

View File

@ -2,8 +2,12 @@ package se.sics.mspsim.core;
public interface USARTSource {
public void setUSARTListener(USARTListener listener);
public void addUSARTListener(USARTListener listener);
public void removeUSARTListener(USARTListener listener);
public void addStateChangeListener(StateChangeListener listener);
public void removeStateChangeListener(StateChangeListener listener);
/* for input into this UART */
public boolean isReceiveFlagCleared();
public void byteReceived(int b);

View File

@ -87,7 +87,7 @@ public class USCI extends IOUnit implements SFRModule, DMATrigger, USARTSource {
public static final int UTCTL_URXSE = 0x08;
public static final int USCI_BUSY = 0x01;
private USARTListener listener;
private USARTListener usartListener;
private int utxifg;
private int urxifg;
@ -235,8 +235,14 @@ public class USCI extends IOUnit implements SFRModule, DMATrigger, USARTSource {
}
/* reuse USART listener API for USCI */
public void setUSARTListener(USARTListener listener) {
this.listener = listener;
@Override
public synchronized void addUSARTListener(USARTListener listener) {
usartListener = USARTListener.Proxy.INSTANCE.add(usartListener, listener);
}
@Override
public synchronized void removeUSARTListener(USARTListener listener) {
usartListener = USARTListener.Proxy.INSTANCE.remove(usartListener, listener);
}
// Only 8 bits / read!
@ -414,6 +420,7 @@ public class USCI extends IOUnit implements SFRModule, DMATrigger, USARTSource {
if (transmitting) {
/* in this case we have shifted out the last character */
USARTListener listener = this.usartListener;
if (listener != null && txShiftReg != -1) {
listener.dataReceived(this, txShiftReg);
}

View File

@ -104,7 +104,7 @@ public abstract class CC2420Node extends GenericNode implements PortListener, US
radio.setFIFOPPort(port1, CC2420_FIFOP);
radio.setFIFOPort(port1, CC2420_FIFO);
((USART) usart0).setUSARTListener(this);
((USART) usart0).addUSARTListener(this);
if (port4 != null) {
radio.setSFDPort(port4, CC2420_SFD);
}

View File

@ -108,7 +108,7 @@ public class Exp5438Node extends GenericNode implements PortListener, USARTListe
radio.setFIFOPPort(port1, CC2420_FIFOP);
radio.setFIFOPort(port1, CC2420_FIFO);
((USARTSource) usart0).setUSARTListener(this);
((USARTSource) usart0).addUSARTListener(this);
if (port1 != null) {
radio.setSFDPort(port1, CC2420_SFD);
}

View File

@ -135,7 +135,7 @@ public class TyndallNode extends GenericNode implements PortListener, USARTListe
radio.setFIFOPPort(port8, CC2420_FIFOP);
radio.setFIFOPort(port8, CC2420_FIFO);
((USARTSource) usart0).setUSARTListener(this);
((USARTSource) usart0).addUSARTListener(this);
if (port4 != null) {
radio.setSFDPort(port8, CC2420_SFD);
}

View File

@ -120,7 +120,7 @@ public class Z1Node extends GenericNode implements PortListener, USARTListener {
radio.setFIFOPPort(port1, CC2420_FIFOP);
radio.setFIFOPort(port1, CC2420_FIFO);
((USARTSource) usart0).setUSARTListener(this);
((USARTSource) usart0).addUSARTListener(this);
if (port4 != null) {
radio.setSFDPort(port4, CC2420_SFD);
}

View File

@ -51,7 +51,6 @@ import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import se.sics.mspsim.core.IOUnit;
import se.sics.mspsim.core.StateChangeListener;
import se.sics.mspsim.core.USARTListener;
import se.sics.mspsim.core.USARTSource;
@ -194,8 +193,8 @@ public class SerialMon implements USARTListener, StateChangeListener, ServiceCom
public void start() {
if (window == null) {
initGUI();
usart.setUSARTListener(this);
((IOUnit) usart).addStateChangeListener(this);
usart.addUSARTListener(this);
usart.addStateChangeListener(this);
}
window.setVisible(true);
status = Status.STARTED;
@ -206,6 +205,8 @@ public class SerialMon implements USARTListener, StateChangeListener, ServiceCom
if (window != null) {
window.setVisible(false);
}
usart.removeUSARTListener(this);
usart.removeStateChangeListener(this);
}
public void dataReceived(USARTSource source, int data) {

View File

@ -57,7 +57,7 @@ public class Test implements USARTListener {
this.cpu = cpu;
IOUnit usart = cpu.getIOUnit("USART 1");
if (usart instanceof USART) {
((USART) usart).setUSARTListener(this);
((USART) usart).addUSARTListener(this);
}
}