[DEV] update esignal to support weak object ==> correct free model
This commit is contained in:
parent
7393095de5
commit
a851ede714
@ -5,6 +5,10 @@ import java.lang.ref.WeakReference;
|
|||||||
public class Connection implements AutoCloseable {
|
public class Connection implements AutoCloseable {
|
||||||
protected WeakReference<ConnectionRemoveInterface> connection;
|
protected WeakReference<ConnectionRemoveInterface> connection;
|
||||||
|
|
||||||
|
public void connectionIsRemovedBySignal() {
|
||||||
|
connection = null;
|
||||||
|
}
|
||||||
|
|
||||||
public void disconnect() {
|
public void disconnect() {
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
@ -7,105 +7,115 @@ import java.util.List;
|
|||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
class ConnectedElement<T> {
|
class ConnectedElement<T> {
|
||||||
protected final Consumer<T> consumer;
|
protected final WeakReference<Consumer<T>> consumer;
|
||||||
protected final WeakReference<Object> reference;
|
|
||||||
|
|
||||||
public ConnectedElement(final WeakReference<Object> reference, final Consumer<T> consumer) {
|
public ConnectedElement(final Consumer<T> consumer) {
|
||||||
this.reference = reference;
|
this.consumer = new WeakReference<Consumer<T>>(consumer);
|
||||||
this.consumer = consumer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Consumer<T> getConsumer() {
|
public Consumer<T> getConsumer() {
|
||||||
return this.consumer;
|
return this.consumer.get();
|
||||||
}
|
|
||||||
|
|
||||||
public WeakReference<Object> getReference() {
|
|
||||||
return this.reference;
|
|
||||||
}
|
|
||||||
public Object getIfAlive() {
|
|
||||||
return this.reference.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCompatibleWith(final Object elem) {
|
public boolean isCompatibleWith(final Object elem) {
|
||||||
|
/*
|
||||||
Object out = this.reference.get();
|
Object out = this.reference.get();
|
||||||
if (out == elem) {
|
if (out == elem) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
*/
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disconnect() {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ConnectedElementDynamic<T> extends ConnectedElement<T> {
|
class ConnectedElementDynamic<T> extends ConnectedElement<T> {
|
||||||
protected final WeakReference<Connection> connection;
|
protected final WeakReference<Object> linkedObject;
|
||||||
|
|
||||||
public ConnectedElementDynamic(final WeakReference<Connection> connection, final WeakReference<Object> reference, final Consumer<T> consumer) {
|
public ConnectedElementDynamic(Object linkedObject, final Consumer<T> consumer) {
|
||||||
super(reference, consumer);
|
super(consumer);
|
||||||
this.connection = connection;
|
this.linkedObject = new WeakReference<Object>(linkedObject);
|
||||||
}
|
|
||||||
|
|
||||||
public WeakReference<Connection> getConnection() {
|
|
||||||
return this.connection;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getIfAlive() {
|
public Consumer<T> getConsumer() {
|
||||||
Object out = this.reference.get();
|
if (this.linkedObject.get() == null) {
|
||||||
if (out == null) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Object outConnection = this.connection.get();
|
return this.consumer.get();
|
||||||
if (outConnection == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCompatibleWith(final Object elem) {
|
public boolean isCompatibleWith(final Object elem) {
|
||||||
if (super.isCompatibleWith(elem)) {
|
if (super.isCompatibleWith(elem)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Object outConnection = this.connection.get();
|
Object obj = this.linkedObject.get();
|
||||||
if (outConnection == elem) {
|
if (obj == elem) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disconnect() {
|
||||||
|
Object obj = this.linkedObject.get();
|
||||||
|
if (obj == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (obj instanceof Connection tmp) {
|
||||||
|
tmp.connectionIsRemovedBySignal();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Signal<T> implements ConnectionRemoveInterface {
|
public class Signal<T> implements ConnectionRemoveInterface {
|
||||||
List<ConnectedElement<T>> data = new ArrayList<>();
|
List<ConnectedElement<T>> data = new ArrayList<>();
|
||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
|
List<ConnectedElement<T>> data2 = data;
|
||||||
synchronized(this.data) {
|
synchronized(this.data) {
|
||||||
this.data = new ArrayList<>();
|
this.data = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
final Iterator<ConnectedElement<T>> iterator = this.data2.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
final ConnectedElement<T> elem = iterator.next();
|
||||||
|
elem.disconnect();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void connect(final Object reference, final Consumer<T> function) {
|
public void connect(final Consumer<T> function) {
|
||||||
synchronized(this.data) {
|
synchronized(this.data) {
|
||||||
WeakReference<Object> weakRef = new WeakReference<Object>(reference);
|
this.data.add(new ConnectedElement<T>(function));
|
||||||
this.data.add(new ConnectedElement<T>(weakRef, function));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void disconnect(final Object obj) {
|
// public void disconnect(final Consumer<T> obj) {
|
||||||
|
// synchronized(this.data) {
|
||||||
|
// final Iterator<ConnectedElement<T>> iterator = this.data.iterator();
|
||||||
|
// while (iterator.hasNext()) {
|
||||||
|
// final ConnectedElement<T> elem = iterator.next();
|
||||||
|
// if (elem.isCompatibleWith(obj)) {
|
||||||
|
// iterator.remove();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
public Connection connectDynamic(final Consumer<T> function) {
|
||||||
|
Connection out = new Connection(this);
|
||||||
synchronized(this.data) {
|
synchronized(this.data) {
|
||||||
final Iterator<ConnectedElement<T>> iterator = this.data.iterator();
|
this.data.add(new ConnectedElementDynamic<T>(out, function));
|
||||||
while (iterator.hasNext()) {
|
|
||||||
final ConnectedElement<T> elem = iterator.next();
|
|
||||||
if (elem.isCompatibleWith(obj)) {
|
|
||||||
iterator.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public Connection connectDynamic(final Object reference, final Consumer<T> function) {
|
|
||||||
WeakReference<Object> weakRef = new WeakReference<Object>(reference);
|
|
||||||
Connection out = new Connection(this);
|
|
||||||
WeakReference<Connection> weakConnection = new WeakReference<Connection>(out);
|
|
||||||
synchronized(this.data) {
|
|
||||||
this.data.add(new ConnectedElementDynamic<T>(weakConnection, weakRef, function));
|
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
public void connectAutoRemoveObject(Object reference, final Consumer<T> function) {
|
||||||
|
synchronized(this.data) {
|
||||||
|
this.data.add(new ConnectedElementDynamic<T>(reference, function));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disconnect(final Connection connection) {
|
public void disconnect(final Connection connection) {
|
||||||
@ -114,13 +124,13 @@ public class Signal<T> implements ConnectionRemoveInterface {
|
|||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
final ConnectedElement<T> elem = iterator.next();
|
final ConnectedElement<T> elem = iterator.next();
|
||||||
if (elem.isCompatibleWith(connection)) {
|
if (elem.isCompatibleWith(connection)) {
|
||||||
|
elem.disconnect();
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void emit(final T value) {
|
public void emit(final T value) {
|
||||||
List<ConnectedElement<T>> tmp;
|
List<ConnectedElement<T>> tmp;
|
||||||
// clean the list:
|
// clean the list:
|
||||||
@ -128,8 +138,9 @@ public class Signal<T> implements ConnectionRemoveInterface {
|
|||||||
final Iterator<ConnectedElement<T>> iterator = this.data.iterator();
|
final Iterator<ConnectedElement<T>> iterator = this.data.iterator();
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
final ConnectedElement<T> elem = iterator.next();
|
final ConnectedElement<T> elem = iterator.next();
|
||||||
Object tmpObject = elem.getIfAlive();
|
Object tmpObject = elem.getConsumer();
|
||||||
if (tmpObject == null) {
|
if (tmpObject == null) {
|
||||||
|
elem.disconnect();
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -142,14 +153,14 @@ public class Signal<T> implements ConnectionRemoveInterface {
|
|||||||
}
|
}
|
||||||
// real call elements
|
// real call elements
|
||||||
{
|
{
|
||||||
final Iterator<ConnectedElement<T>> iterator = tmp.iterator();
|
final Iterator<ConnectedElement<T>> iterator = tmp.iterator();
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
final ConnectedElement<T> elem = iterator.next();
|
final ConnectedElement<T> elem = iterator.next();
|
||||||
Object tmpObject = elem.getIfAlive();
|
Consumer<T> tmpObject = elem.getConsumer();
|
||||||
if (tmpObject == null) {
|
if (tmpObject == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
elem.getConsumer().accept(value);
|
tmpObject.accept(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -157,4 +168,5 @@ public class Signal<T> implements ConnectionRemoveInterface {
|
|||||||
public int size() {
|
public int size() {
|
||||||
return this.data.size();
|
return this.data.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
59
test/src/test/atriasoft/esignal/Log.java
Normal file
59
test/src/test/atriasoft/esignal/Log.java
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
package test.atriasoft.esignal;
|
||||||
|
|
||||||
|
import io.scenarium.logger.LogLevel;
|
||||||
|
import io.scenarium.logger.Logger;
|
||||||
|
|
||||||
|
public class Log {
|
||||||
|
private static final String LIB_NAME = "esignal-test";
|
||||||
|
private static final String LIB_NAME_DRAW = Logger.getDrawableName(LIB_NAME);
|
||||||
|
private static final boolean PRINT_CRITICAL = Logger.getNeedPrint(LIB_NAME, LogLevel.CRITICAL);
|
||||||
|
private static final boolean PRINT_ERROR = Logger.getNeedPrint(LIB_NAME, LogLevel.ERROR);
|
||||||
|
private static final boolean PRINT_WARNING = Logger.getNeedPrint(LIB_NAME, LogLevel.WARNING);
|
||||||
|
private static final boolean PRINT_INFO = Logger.getNeedPrint(LIB_NAME, LogLevel.INFO);
|
||||||
|
private static final boolean PRINT_DEBUG = Logger.getNeedPrint(LIB_NAME, LogLevel.DEBUG);
|
||||||
|
private static final boolean PRINT_VERBOSE = Logger.getNeedPrint(LIB_NAME, LogLevel.VERBOSE);
|
||||||
|
private static final boolean PRINT_TODO = Logger.getNeedPrint(LIB_NAME, LogLevel.TODO);
|
||||||
|
private static final boolean PRINT_PRINT = Logger.getNeedPrint(LIB_NAME, LogLevel.PRINT);
|
||||||
|
|
||||||
|
private Log() {}
|
||||||
|
|
||||||
|
public static void print(String data) {
|
||||||
|
if (PRINT_PRINT)
|
||||||
|
Logger.print(LIB_NAME_DRAW, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void critical(String data) {
|
||||||
|
if (PRINT_CRITICAL)
|
||||||
|
Logger.critical(LIB_NAME_DRAW, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void error(String data) {
|
||||||
|
if (PRINT_ERROR)
|
||||||
|
Logger.error(LIB_NAME_DRAW, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void warning(String data) {
|
||||||
|
if (PRINT_WARNING)
|
||||||
|
Logger.warning(LIB_NAME_DRAW, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void info(String data) {
|
||||||
|
if (PRINT_INFO)
|
||||||
|
Logger.info(LIB_NAME_DRAW, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void debug(String data) {
|
||||||
|
if (PRINT_DEBUG)
|
||||||
|
Logger.debug(LIB_NAME_DRAW, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void verbose(String data) {
|
||||||
|
if (PRINT_VERBOSE)
|
||||||
|
Logger.verbose(LIB_NAME_DRAW, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void todo(String data) {
|
||||||
|
if (PRINT_TODO)
|
||||||
|
Logger.todo(LIB_NAME_DRAW, data);
|
||||||
|
}
|
||||||
|
}
|
301
test/src/test/atriasoft/esignal/TestSignal.java
Normal file
301
test/src/test/atriasoft/esignal/TestSignal.java
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Edouard DUPIN - initial API and implementation
|
||||||
|
******************************************************************************/
|
||||||
|
package test.atriasoft.esignal;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import io.scenarium.logger.Logger;
|
||||||
|
|
||||||
|
import org.atriasoft.esignal.Connection;
|
||||||
|
import org.atriasoft.esignal.Signal;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
|
||||||
|
import org.junit.jupiter.api.Order;
|
||||||
|
//import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.TestMethodOrder;
|
||||||
|
|
||||||
|
@TestMethodOrder(OrderAnnotation.class)
|
||||||
|
public class TestSignal {
|
||||||
|
|
||||||
|
class EmiterSimple {
|
||||||
|
public Signal<String> signalEvent = new Signal<String>();
|
||||||
|
public void sendEvent(String value) {
|
||||||
|
signalEvent.emit(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class ReceiverSimple {
|
||||||
|
private String dataReceive = null;
|
||||||
|
ReceiverSimple() {
|
||||||
|
}
|
||||||
|
public void connect1(EmiterSimple other) {
|
||||||
|
WeakReference<ReceiverSimple> tmpp = new WeakReference<ReceiverSimple>(this);
|
||||||
|
other.signalEvent.connect(data -> {
|
||||||
|
tmpp.get().onData(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public void connect2(EmiterSimple other) {
|
||||||
|
// the solo lambda will not depend on the object => the remove must be done manually...
|
||||||
|
other.signalEvent.connect(data -> {
|
||||||
|
Log.error("lambda receive: " + data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public void connect3(EmiterSimple other) {
|
||||||
|
// we reference the local object, then the lambda is alive while the object is alive...
|
||||||
|
other.signalEvent.connect(data -> {
|
||||||
|
Log.error("lambda receive: " + data);
|
||||||
|
this.dataReceive = data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public void connect4(EmiterSimple other) {
|
||||||
|
other.signalEvent.connect(data -> {
|
||||||
|
onData(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public void connect5(EmiterSimple other) {
|
||||||
|
other.signalEvent.connect(this::onData);
|
||||||
|
}
|
||||||
|
// Does not work at all:
|
||||||
|
// public void disconnect5(EmiterSimple other) {
|
||||||
|
// other.signalEvent.disconnect(this::onData);
|
||||||
|
// }
|
||||||
|
|
||||||
|
public void connect6(EmiterSimple other) {
|
||||||
|
// the solo lambda will not depend on the object => the remove must be done manually...
|
||||||
|
other.signalEvent.connectAutoRemoveObject(this, data -> {
|
||||||
|
Log.error("lambda receive: " + data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
private Connection tmpConnect = null;
|
||||||
|
|
||||||
|
public void connect7(EmiterSimple other) {
|
||||||
|
tmpConnect = other.signalEvent.connectDynamic(this::onData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disconnect7(EmiterSimple other) {
|
||||||
|
other.signalEvent.disconnect(tmpConnect);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disconnect72() {
|
||||||
|
tmpConnect.disconnect();
|
||||||
|
}
|
||||||
|
public boolean isConnected() {
|
||||||
|
return tmpConnect.isConnected();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onData(String data) {
|
||||||
|
Log.error("Retrive data : " + data);
|
||||||
|
dataReceive = data;
|
||||||
|
}
|
||||||
|
public String getDataAndClean() {
|
||||||
|
String tmp = dataReceive;
|
||||||
|
dataReceive = null;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(1)
|
||||||
|
public void testConnectAndTransmit1() {
|
||||||
|
Log.warning("Test 1 [BEGIN]");
|
||||||
|
EmiterSimple sender = new EmiterSimple();
|
||||||
|
ReceiverSimple receiver = new ReceiverSimple();
|
||||||
|
receiver.connect1(sender);
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
String testData1 = "MUST receive this data...";
|
||||||
|
sender.sendEvent(testData1);
|
||||||
|
assertEquals(testData1, receiver.getDataAndClean());
|
||||||
|
receiver = null;
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
System.gc();
|
||||||
|
String testData2 = "MUST NOT receive this data...";
|
||||||
|
sender.sendEvent(testData2);
|
||||||
|
assertEquals(0, sender.signalEvent.size());
|
||||||
|
Log.warning("Test 1 [ END ]");
|
||||||
|
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
@Order(2)
|
||||||
|
public void testConnectAndTransmit2() {
|
||||||
|
Log.warning("Test 2 [BEGIN]");
|
||||||
|
EmiterSimple sender = new EmiterSimple();
|
||||||
|
ReceiverSimple receiver = new ReceiverSimple();
|
||||||
|
receiver.connect2(sender);
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
String testData1 = "MUST receive this data...";
|
||||||
|
sender.sendEvent(testData1);
|
||||||
|
// No data stored ... assertEquals(testData1, receiver.getDataAndClean());
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
receiver = null;
|
||||||
|
System.gc();
|
||||||
|
String testData2 = "Solo Lambda MUST receive this data...";
|
||||||
|
sender.sendEvent(testData2);
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
Log.warning("Test 2 [ END ]");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(3)
|
||||||
|
public void testConnectAndTransmit3() {
|
||||||
|
Log.warning("Test 3 [BEGIN]");
|
||||||
|
EmiterSimple sender = new EmiterSimple();
|
||||||
|
ReceiverSimple receiver = new ReceiverSimple();
|
||||||
|
receiver.connect3(sender);
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
String testData1 = "MUST receive this data...";
|
||||||
|
sender.sendEvent(testData1);
|
||||||
|
assertEquals(testData1, receiver.getDataAndClean());
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
receiver = null;
|
||||||
|
System.gc();
|
||||||
|
String testData2 = "MUST NOT receive this data...";
|
||||||
|
sender.sendEvent(testData2);
|
||||||
|
assertEquals(0, sender.signalEvent.size());
|
||||||
|
Log.warning("Test 3 [ END ]");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(4)
|
||||||
|
public void testConnectAndTransmit4() {
|
||||||
|
Log.warning("Test 4 [BEGIN]");
|
||||||
|
EmiterSimple sender = new EmiterSimple();
|
||||||
|
ReceiverSimple receiver = new ReceiverSimple();
|
||||||
|
receiver.connect4(sender);
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
String testData1 = "MUST receive this data...";
|
||||||
|
sender.sendEvent(testData1);
|
||||||
|
assertEquals(testData1, receiver.getDataAndClean());
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
receiver = null;
|
||||||
|
System.gc();
|
||||||
|
String testData2 = "MUST NOT receive this data...";
|
||||||
|
sender.sendEvent(testData2);
|
||||||
|
assertEquals(0, sender.signalEvent.size());
|
||||||
|
Log.warning("Test 4 [ END ]");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(5)
|
||||||
|
public void testConnectAndTransmit5() {
|
||||||
|
Log.warning("Test 5 [BEGIN]");
|
||||||
|
EmiterSimple sender = new EmiterSimple();
|
||||||
|
ReceiverSimple receiver = new ReceiverSimple();
|
||||||
|
//connect step 1
|
||||||
|
receiver.connect5(sender);
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
String testData1 = "MUST receive this data... 111";
|
||||||
|
sender.sendEvent(testData1);
|
||||||
|
assertEquals(testData1, receiver.getDataAndClean());
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
// remove connection
|
||||||
|
// receiver.disconnect5(sender);
|
||||||
|
// assertEquals(0, sender.signalEvent.size());
|
||||||
|
// System.gc();
|
||||||
|
// String testData2 = "MUST NOT receive this data... 222";
|
||||||
|
// sender.sendEvent(testData2);
|
||||||
|
// assertEquals(null, receiver.getDataAndClean());
|
||||||
|
// // reconnect (step 2
|
||||||
|
// receiver.connect5(sender);
|
||||||
|
// assertEquals(1, sender.signalEvent.size());
|
||||||
|
// String testData3 = "MUST receive this data... 333";
|
||||||
|
// sender.sendEvent(testData3);
|
||||||
|
// assertEquals(testData3, receiver.getDataAndClean());
|
||||||
|
// assertEquals(1, sender.signalEvent.size());
|
||||||
|
// check auto remove...
|
||||||
|
receiver = null;
|
||||||
|
System.gc();
|
||||||
|
String testData4 = "MUST NOT receive this data... 444";
|
||||||
|
sender.sendEvent(testData4);
|
||||||
|
assertEquals(0, sender.signalEvent.size());
|
||||||
|
Log.warning("Test 5 [ END ]");
|
||||||
|
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
@Order(6)
|
||||||
|
public void testConnectAndTransmit6() {
|
||||||
|
Log.warning("Test 6 [BEGIN]");
|
||||||
|
EmiterSimple sender = new EmiterSimple();
|
||||||
|
ReceiverSimple receiver = new ReceiverSimple();
|
||||||
|
receiver.connect6(sender);
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
String testData1 = "MUST receive this data...";
|
||||||
|
sender.sendEvent(testData1);
|
||||||
|
//assertEquals(testData1, receiver.getDataAndClean());
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
receiver = null;
|
||||||
|
System.gc();
|
||||||
|
String testData2 = "MUST NOT receive this data...";
|
||||||
|
sender.sendEvent(testData2);
|
||||||
|
assertEquals(0, sender.signalEvent.size());
|
||||||
|
Log.warning("Test 6 [ END ]");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(7)
|
||||||
|
public void testConnectAndTransmit7() {
|
||||||
|
Log.warning("Test 7 [BEGIN]");
|
||||||
|
EmiterSimple sender = new EmiterSimple();
|
||||||
|
ReceiverSimple receiver = new ReceiverSimple();
|
||||||
|
//connect step 1
|
||||||
|
receiver.connect7(sender);
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
String testData1 = "MUST receive this data... 111";
|
||||||
|
sender.sendEvent(testData1);
|
||||||
|
assertEquals(testData1, receiver.getDataAndClean());
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
assertEquals(true, receiver.isConnected());
|
||||||
|
// remove connection
|
||||||
|
receiver.disconnect7(sender);
|
||||||
|
assertEquals(false, receiver.isConnected());
|
||||||
|
System.gc();
|
||||||
|
String testData2 = "MUST NOT receive this data... 222";
|
||||||
|
sender.sendEvent(testData2);
|
||||||
|
assertEquals(0, sender.signalEvent.size());
|
||||||
|
assertEquals(null, receiver.getDataAndClean());
|
||||||
|
// reconnect (step 2
|
||||||
|
receiver.connect7(sender);
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
String testData3 = "MUST receive this data... 333";
|
||||||
|
sender.sendEvent(testData3);
|
||||||
|
assertEquals(testData3, receiver.getDataAndClean());
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
assertEquals(true, receiver.isConnected());
|
||||||
|
// remove connection
|
||||||
|
receiver.disconnect72();
|
||||||
|
assertEquals(false, receiver.isConnected());
|
||||||
|
assertEquals(0, sender.signalEvent.size());
|
||||||
|
System.gc();
|
||||||
|
String testData4 = "MUST NOT receive this data... 444";
|
||||||
|
sender.sendEvent(testData4);
|
||||||
|
assertEquals(null, receiver.getDataAndClean());
|
||||||
|
// reconnect (step 2
|
||||||
|
receiver.connect7(sender);
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
String testData5 = "MUST receive this data... 555";
|
||||||
|
sender.sendEvent(testData5);
|
||||||
|
assertEquals(testData5, receiver.getDataAndClean());
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
// check auto remove...
|
||||||
|
receiver = null;
|
||||||
|
System.gc();
|
||||||
|
String testData6 = "MUST NOT receive this data... 666";
|
||||||
|
sender.sendEvent(testData6);
|
||||||
|
assertEquals(0, sender.signalEvent.size());
|
||||||
|
Log.warning("Test 7 [ END ]");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
301
test/src/test/atriasoft/esignal/TestSignalType.java
Normal file
301
test/src/test/atriasoft/esignal/TestSignalType.java
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Edouard DUPIN - initial API and implementation
|
||||||
|
******************************************************************************/
|
||||||
|
package test.atriasoft.esignal;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import io.scenarium.logger.Logger;
|
||||||
|
|
||||||
|
import org.atriasoft.esignal.Connection;
|
||||||
|
import org.atriasoft.esignal.Signal;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
|
||||||
|
import org.junit.jupiter.api.Order;
|
||||||
|
//import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.TestMethodOrder;
|
||||||
|
|
||||||
|
@TestMethodOrder(OrderAnnotation.class)
|
||||||
|
public class TestSignalType {
|
||||||
|
|
||||||
|
class EmiterSimple {
|
||||||
|
public Signal<String> signalEvent = new Signal<String>();
|
||||||
|
public void sendEvent(String value) {
|
||||||
|
signalEvent.emit(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class ReceiverSimple {
|
||||||
|
private String dataReceive = null;
|
||||||
|
ReceiverSimple() {
|
||||||
|
}
|
||||||
|
public void connect1(EmiterSimple other) {
|
||||||
|
WeakReference<ReceiverSimple> tmpp = new WeakReference<ReceiverSimple>(this);
|
||||||
|
other.signalEvent.connect(data -> {
|
||||||
|
tmpp.get().onData(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public void connect2(EmiterSimple other) {
|
||||||
|
// the solo lambda will not depend on the object => the remove must be done manually...
|
||||||
|
other.signalEvent.connect(data -> {
|
||||||
|
Log.error("lambda receive: " + data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public void connect3(EmiterSimple other) {
|
||||||
|
// we reference the local object, then the lambda is alive while the object is alive...
|
||||||
|
other.signalEvent.connect(data -> {
|
||||||
|
Log.error("lambda receive: " + data);
|
||||||
|
this.dataReceive = data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public void connect4(EmiterSimple other) {
|
||||||
|
other.signalEvent.connect(data -> {
|
||||||
|
onData(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public void connect5(EmiterSimple other) {
|
||||||
|
other.signalEvent.connect(this::onData);
|
||||||
|
}
|
||||||
|
// Does not work at all:
|
||||||
|
// public void disconnect5(EmiterSimple other) {
|
||||||
|
// other.signalEvent.disconnect(this::onData);
|
||||||
|
// }
|
||||||
|
|
||||||
|
public void connect6(EmiterSimple other) {
|
||||||
|
// the solo lambda will not depend on the object => the remove must be done manually...
|
||||||
|
other.signalEvent.connectAutoRemoveObject(this, data -> {
|
||||||
|
Log.error("lambda receive: " + data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
private Connection tmpConnect = null;
|
||||||
|
|
||||||
|
public void connect7(EmiterSimple other) {
|
||||||
|
tmpConnect = other.signalEvent.connectDynamic(this::onData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disconnect7(EmiterSimple other) {
|
||||||
|
other.signalEvent.disconnect(tmpConnect);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disconnect72() {
|
||||||
|
tmpConnect.disconnect();
|
||||||
|
}
|
||||||
|
public boolean isConnected() {
|
||||||
|
return tmpConnect.isConnected();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onData(String data) {
|
||||||
|
Log.error("Retrive data : " + data);
|
||||||
|
dataReceive = data;
|
||||||
|
}
|
||||||
|
public String getDataAndClean() {
|
||||||
|
String tmp = dataReceive;
|
||||||
|
dataReceive = null;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(1)
|
||||||
|
public void testConnectAndTransmit1() {
|
||||||
|
Log.warning("Test 1 [BEGIN]");
|
||||||
|
EmiterSimple sender = new EmiterSimple();
|
||||||
|
ReceiverSimple receiver = new ReceiverSimple();
|
||||||
|
receiver.connect1(sender);
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
String testData1 = "MUST receive this data...";
|
||||||
|
sender.sendEvent(testData1);
|
||||||
|
assertEquals(testData1, receiver.getDataAndClean());
|
||||||
|
receiver = null;
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
System.gc();
|
||||||
|
String testData2 = "MUST NOT receive this data...";
|
||||||
|
sender.sendEvent(testData2);
|
||||||
|
assertEquals(0, sender.signalEvent.size());
|
||||||
|
Log.warning("Test 1 [ END ]");
|
||||||
|
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
@Order(2)
|
||||||
|
public void testConnectAndTransmit2() {
|
||||||
|
Log.warning("Test 2 [BEGIN]");
|
||||||
|
EmiterSimple sender = new EmiterSimple();
|
||||||
|
ReceiverSimple receiver = new ReceiverSimple();
|
||||||
|
receiver.connect2(sender);
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
String testData1 = "MUST receive this data...";
|
||||||
|
sender.sendEvent(testData1);
|
||||||
|
// No data stored ... assertEquals(testData1, receiver.getDataAndClean());
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
receiver = null;
|
||||||
|
System.gc();
|
||||||
|
String testData2 = "Solo Lambda MUST receive this data...";
|
||||||
|
sender.sendEvent(testData2);
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
Log.warning("Test 2 [ END ]");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(3)
|
||||||
|
public void testConnectAndTransmit3() {
|
||||||
|
Log.warning("Test 3 [BEGIN]");
|
||||||
|
EmiterSimple sender = new EmiterSimple();
|
||||||
|
ReceiverSimple receiver = new ReceiverSimple();
|
||||||
|
receiver.connect3(sender);
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
String testData1 = "MUST receive this data...";
|
||||||
|
sender.sendEvent(testData1);
|
||||||
|
assertEquals(testData1, receiver.getDataAndClean());
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
receiver = null;
|
||||||
|
System.gc();
|
||||||
|
String testData2 = "MUST NOT receive this data...";
|
||||||
|
sender.sendEvent(testData2);
|
||||||
|
assertEquals(0, sender.signalEvent.size());
|
||||||
|
Log.warning("Test 3 [ END ]");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(4)
|
||||||
|
public void testConnectAndTransmit4() {
|
||||||
|
Log.warning("Test 4 [BEGIN]");
|
||||||
|
EmiterSimple sender = new EmiterSimple();
|
||||||
|
ReceiverSimple receiver = new ReceiverSimple();
|
||||||
|
receiver.connect4(sender);
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
String testData1 = "MUST receive this data...";
|
||||||
|
sender.sendEvent(testData1);
|
||||||
|
assertEquals(testData1, receiver.getDataAndClean());
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
receiver = null;
|
||||||
|
System.gc();
|
||||||
|
String testData2 = "MUST NOT receive this data...";
|
||||||
|
sender.sendEvent(testData2);
|
||||||
|
assertEquals(0, sender.signalEvent.size());
|
||||||
|
Log.warning("Test 4 [ END ]");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(5)
|
||||||
|
public void testConnectAndTransmit5() {
|
||||||
|
Log.warning("Test 5 [BEGIN]");
|
||||||
|
EmiterSimple sender = new EmiterSimple();
|
||||||
|
ReceiverSimple receiver = new ReceiverSimple();
|
||||||
|
//connect step 1
|
||||||
|
receiver.connect5(sender);
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
String testData1 = "MUST receive this data... 111";
|
||||||
|
sender.sendEvent(testData1);
|
||||||
|
assertEquals(testData1, receiver.getDataAndClean());
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
// remove connection
|
||||||
|
// receiver.disconnect5(sender);
|
||||||
|
// assertEquals(0, sender.signalEvent.size());
|
||||||
|
// System.gc();
|
||||||
|
// String testData2 = "MUST NOT receive this data... 222";
|
||||||
|
// sender.sendEvent(testData2);
|
||||||
|
// assertEquals(null, receiver.getDataAndClean());
|
||||||
|
// // reconnect (step 2
|
||||||
|
// receiver.connect5(sender);
|
||||||
|
// assertEquals(1, sender.signalEvent.size());
|
||||||
|
// String testData3 = "MUST receive this data... 333";
|
||||||
|
// sender.sendEvent(testData3);
|
||||||
|
// assertEquals(testData3, receiver.getDataAndClean());
|
||||||
|
// assertEquals(1, sender.signalEvent.size());
|
||||||
|
// check auto remove...
|
||||||
|
receiver = null;
|
||||||
|
System.gc();
|
||||||
|
String testData4 = "MUST NOT receive this data... 444";
|
||||||
|
sender.sendEvent(testData4);
|
||||||
|
assertEquals(0, sender.signalEvent.size());
|
||||||
|
Log.warning("Test 5 [ END ]");
|
||||||
|
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
@Order(6)
|
||||||
|
public void testConnectAndTransmit6() {
|
||||||
|
Log.warning("Test 6 [BEGIN]");
|
||||||
|
EmiterSimple sender = new EmiterSimple();
|
||||||
|
ReceiverSimple receiver = new ReceiverSimple();
|
||||||
|
receiver.connect6(sender);
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
String testData1 = "MUST receive this data...";
|
||||||
|
sender.sendEvent(testData1);
|
||||||
|
//assertEquals(testData1, receiver.getDataAndClean());
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
receiver = null;
|
||||||
|
System.gc();
|
||||||
|
String testData2 = "MUST NOT receive this data...";
|
||||||
|
sender.sendEvent(testData2);
|
||||||
|
assertEquals(0, sender.signalEvent.size());
|
||||||
|
Log.warning("Test 6 [ END ]");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(7)
|
||||||
|
public void testConnectAndTransmit7() {
|
||||||
|
Log.warning("Test 7 [BEGIN]");
|
||||||
|
EmiterSimple sender = new EmiterSimple();
|
||||||
|
ReceiverSimple receiver = new ReceiverSimple();
|
||||||
|
//connect step 1
|
||||||
|
receiver.connect7(sender);
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
String testData1 = "MUST receive this data... 111";
|
||||||
|
sender.sendEvent(testData1);
|
||||||
|
assertEquals(testData1, receiver.getDataAndClean());
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
assertEquals(true, receiver.isConnected());
|
||||||
|
// remove connection
|
||||||
|
receiver.disconnect7(sender);
|
||||||
|
assertEquals(false, receiver.isConnected());
|
||||||
|
System.gc();
|
||||||
|
String testData2 = "MUST NOT receive this data... 222";
|
||||||
|
sender.sendEvent(testData2);
|
||||||
|
assertEquals(0, sender.signalEvent.size());
|
||||||
|
assertEquals(null, receiver.getDataAndClean());
|
||||||
|
// reconnect (step 2
|
||||||
|
receiver.connect7(sender);
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
String testData3 = "MUST receive this data... 333";
|
||||||
|
sender.sendEvent(testData3);
|
||||||
|
assertEquals(testData3, receiver.getDataAndClean());
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
assertEquals(true, receiver.isConnected());
|
||||||
|
// remove connection
|
||||||
|
receiver.disconnect72();
|
||||||
|
assertEquals(false, receiver.isConnected());
|
||||||
|
assertEquals(0, sender.signalEvent.size());
|
||||||
|
System.gc();
|
||||||
|
String testData4 = "MUST NOT receive this data... 444";
|
||||||
|
sender.sendEvent(testData4);
|
||||||
|
assertEquals(null, receiver.getDataAndClean());
|
||||||
|
// reconnect (step 2
|
||||||
|
receiver.connect7(sender);
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
String testData5 = "MUST receive this data... 555";
|
||||||
|
sender.sendEvent(testData5);
|
||||||
|
assertEquals(testData5, receiver.getDataAndClean());
|
||||||
|
assertEquals(1, sender.signalEvent.size());
|
||||||
|
// check auto remove...
|
||||||
|
receiver = null;
|
||||||
|
System.gc();
|
||||||
|
String testData6 = "MUST NOT receive this data... 666";
|
||||||
|
sender.sendEvent(testData6);
|
||||||
|
assertEquals(0, sender.signalEvent.size());
|
||||||
|
Log.warning("Test 7 [ END ]");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package test.atriasoft.etk;
|
package test.atriasoft.ewol;
|
||||||
|
|
||||||
import io.scenarium.logger.LogLevel;
|
import io.scenarium.logger.LogLevel;
|
||||||
import io.scenarium.logger.Logger;
|
import io.scenarium.logger.Logger;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package test.atriasoft.etk;
|
package test.atriasoft.ewol;
|
||||||
|
|
||||||
import io.scenarium.logger.LogLevel;
|
import io.scenarium.logger.LogLevel;
|
||||||
import io.scenarium.logger.Logger;
|
import io.scenarium.logger.Logger;
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* Contributors:
|
* Contributors:
|
||||||
* Edouard DUPIN - initial API and implementation
|
* Edouard DUPIN - initial API and implementation
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package test.atriasoft.etk;
|
package test.atriasoft.ewol;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user