diff --git a/se/sics/mspsim/chip/Leds.java b/se/sics/mspsim/chip/Leds.java index 0e9d1bc..8a13711 100644 --- a/se/sics/mspsim/chip/Leds.java +++ b/se/sics/mspsim/chip/Leds.java @@ -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() { diff --git a/se/sics/mspsim/chip/TR1001.java b/se/sics/mspsim/chip/TR1001.java index 2ed13f3..00e5d9c 100644 --- a/se/sics/mspsim/chip/TR1001.java +++ b/se/sics/mspsim/chip/TR1001.java @@ -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; diff --git a/se/sics/mspsim/core/Chip.java b/se/sics/mspsim/core/Chip.java index 857c434..250e78d 100644 --- a/se/sics/mspsim/core/Chip.java +++ b/se/sics/mspsim/core/Chip.java @@ -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); } } } diff --git a/se/sics/mspsim/core/GenericUSCI.java b/se/sics/mspsim/core/GenericUSCI.java index ff9c795..7c09c43 100644 --- a/se/sics/mspsim/core/GenericUSCI.java +++ b/se/sics/mspsim/core/GenericUSCI.java @@ -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 */ diff --git a/se/sics/mspsim/core/IOUnit.java b/se/sics/mspsim/core/IOUnit.java index 8aad85f..7efb39c 100644 --- a/se/sics/mspsim/core/IOUnit.java +++ b/se/sics/mspsim/core/IOUnit.java @@ -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); } } } diff --git a/se/sics/mspsim/core/StateChangeListener.java b/se/sics/mspsim/core/StateChangeListener.java index ee221b3..cd43794 100644 --- a/se/sics/mspsim/core/StateChangeListener.java +++ b/se/sics/mspsim/core/StateChangeListener.java @@ -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 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); + } + } + + } } diff --git a/se/sics/mspsim/core/USART.java b/se/sics/mspsim/core/USART.java index dfedc95..d27f621 100644 --- a/se/sics/mspsim/core/USART.java +++ b/se/sics/mspsim/core/USART.java @@ -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); } diff --git a/se/sics/mspsim/core/USARTListener.java b/se/sics/mspsim/core/USARTListener.java index fef17d2..0d02805 100644 --- a/se/sics/mspsim/core/USARTListener.java +++ b/se/sics/mspsim/core/USARTListener.java @@ -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 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); + } + } + + } + } diff --git a/se/sics/mspsim/core/USARTSource.java b/se/sics/mspsim/core/USARTSource.java index a84e8f8..fd62e59 100644 --- a/se/sics/mspsim/core/USARTSource.java +++ b/se/sics/mspsim/core/USARTSource.java @@ -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); diff --git a/se/sics/mspsim/core/USCI.java b/se/sics/mspsim/core/USCI.java index 1faba12..03de583 100644 --- a/se/sics/mspsim/core/USCI.java +++ b/se/sics/mspsim/core/USCI.java @@ -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); } diff --git a/se/sics/mspsim/platform/sky/CC2420Node.java b/se/sics/mspsim/platform/sky/CC2420Node.java index b2a6815..22c9f9c 100644 --- a/se/sics/mspsim/platform/sky/CC2420Node.java +++ b/se/sics/mspsim/platform/sky/CC2420Node.java @@ -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); } diff --git a/se/sics/mspsim/platform/ti/Exp5438Node.java b/se/sics/mspsim/platform/ti/Exp5438Node.java index faad0d0..887933b 100644 --- a/se/sics/mspsim/platform/ti/Exp5438Node.java +++ b/se/sics/mspsim/platform/ti/Exp5438Node.java @@ -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); } diff --git a/se/sics/mspsim/platform/tyndall/TyndallNode.java b/se/sics/mspsim/platform/tyndall/TyndallNode.java index 21b86b7..26bac29 100644 --- a/se/sics/mspsim/platform/tyndall/TyndallNode.java +++ b/se/sics/mspsim/platform/tyndall/TyndallNode.java @@ -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); } diff --git a/se/sics/mspsim/platform/z1/Z1Node.java b/se/sics/mspsim/platform/z1/Z1Node.java index 2a52bc3..6816418 100644 --- a/se/sics/mspsim/platform/z1/Z1Node.java +++ b/se/sics/mspsim/platform/z1/Z1Node.java @@ -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); } diff --git a/se/sics/mspsim/ui/SerialMon.java b/se/sics/mspsim/ui/SerialMon.java index f61d472..1099ae7 100644 --- a/se/sics/mspsim/ui/SerialMon.java +++ b/se/sics/mspsim/ui/SerialMon.java @@ -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) { diff --git a/se/sics/mspsim/util/Test.java b/se/sics/mspsim/util/Test.java index 56ff977..eca6e36 100644 --- a/se/sics/mspsim/util/Test.java +++ b/se/sics/mspsim/util/Test.java @@ -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); } }