[DEV] add some generic code
This commit is contained in:
parent
722e6fe5cf
commit
70755dbbf4
@ -13,8 +13,8 @@ import org.atriasoft.esignal.internal.ConnectedElementDynamic;
|
||||
* @param <T> generic Runnable, Consumer, or BiConsumer template...
|
||||
*/
|
||||
public class GenericSignal<T> implements ConnectionRemoveInterface {
|
||||
List<ConnectedElement<T>> data = new ArrayList<>();
|
||||
|
||||
protected List<ConnectedElement<T>> data = new ArrayList<>();
|
||||
public void clear() {
|
||||
List<ConnectedElement<T>> data2 = this.data;
|
||||
synchronized(this.data) {
|
||||
@ -50,9 +50,9 @@ public class GenericSignal<T> implements ConnectionRemoveInterface {
|
||||
}
|
||||
return out;
|
||||
}
|
||||
public void connectAutoRemoveObject(final Object reference, final T function) {
|
||||
public void connectAutoRemoveObject(final Object object, final T function) {
|
||||
synchronized(this.data) {
|
||||
this.data.add(new ConnectedElementDynamic<T>(reference, function));
|
||||
this.data.add(new ConnectedElementDynamic<T>(object, function));
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,8 +70,42 @@ public class GenericSignal<T> implements ConnectionRemoveInterface {
|
||||
}
|
||||
}
|
||||
|
||||
protected List<ConnectedElement<T>> getACleanedList() {
|
||||
// first clean the list
|
||||
cleanedList();
|
||||
// get a copy of elements
|
||||
List<ConnectedElement<T>> out = null;
|
||||
// clean the list:
|
||||
synchronized(this.data) {
|
||||
// simple optimization:
|
||||
if (this.data.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
// clone the list to permit to have asynchronous remove call
|
||||
out = new ArrayList<>(this.data);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
protected void cleanedList() {
|
||||
// clean the list:
|
||||
synchronized(this.data) {
|
||||
final Iterator<ConnectedElement<T>> iterator = this.data.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final ConnectedElement<T> elem = iterator.next();
|
||||
Object tmpObject = elem.getConsumer();
|
||||
if (tmpObject == null) {
|
||||
elem.disconnect();
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public int size() {
|
||||
return this.data.size();
|
||||
}
|
||||
public int sizeCleaned() {
|
||||
cleanedList();
|
||||
return this.data.size();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -53,42 +53,20 @@ import org.atriasoft.esignal.internal.ConnectedElement;
|
||||
*/
|
||||
public class Signal<T> extends GenericSignal<Consumer<T>> {
|
||||
public void emit(final T value) {
|
||||
List<ConnectedElement<Consumer<T>>> tmp;
|
||||
// clean the list:
|
||||
synchronized(this.data) {
|
||||
final Iterator<ConnectedElement<Consumer<T>>> iterator = this.data.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final ConnectedElement<Consumer<T>> elem = iterator.next();
|
||||
Object tmpObject = elem.getConsumer();
|
||||
if (tmpObject == null) {
|
||||
elem.disconnect();
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
// simple optimization:
|
||||
if (this.data.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// clone the list to permit to have asynchronous remove call
|
||||
tmp = new ArrayList<>(this.data);
|
||||
List<ConnectedElement<Consumer<T>>> tmp = getACleanedList();
|
||||
if (tmp == null) {
|
||||
return;
|
||||
}
|
||||
// real call elements
|
||||
{
|
||||
final Iterator<ConnectedElement<Consumer<T>>> iterator = tmp.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final ConnectedElement<Consumer<T>> elem = iterator.next();
|
||||
Consumer<T> tmpObject = elem.getConsumer();
|
||||
if (tmpObject == null) {
|
||||
continue;
|
||||
}
|
||||
tmpObject.accept(value);
|
||||
final Iterator<ConnectedElement<Consumer<T>>> iterator = tmp.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final ConnectedElement<Consumer<T>> elem = iterator.next();
|
||||
Consumer<T> tmpObject = elem.getConsumer();
|
||||
if (tmpObject == null) {
|
||||
// Not a dead code, but very hard to simply test it.
|
||||
continue;
|
||||
}
|
||||
tmpObject.accept(value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return this.data.size();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -55,36 +55,19 @@ import org.atriasoft.esignal.internal.ConnectedElement;
|
||||
*/
|
||||
public class Signal2<T, U> extends GenericSignal<BiConsumer<T, U>> {
|
||||
public void emit(final T valueT, final U valueU) {
|
||||
List<ConnectedElement<BiConsumer<T, U>>> tmp;
|
||||
// clean the list:
|
||||
synchronized(this.data) {
|
||||
final Iterator<ConnectedElement<BiConsumer<T, U>>> iterator = this.data.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final ConnectedElement<BiConsumer<T, U>> elem = iterator.next();
|
||||
Object tmpObject = elem.getConsumer();
|
||||
if (tmpObject == null) {
|
||||
elem.disconnect();
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
// simple optimization:
|
||||
if (this.data.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// clone the list to permit to have asynchronous remove call
|
||||
tmp = new ArrayList<>(this.data);
|
||||
List<ConnectedElement<BiConsumer<T, U>>> tmp = getACleanedList();
|
||||
if (tmp == null) {
|
||||
return;
|
||||
}
|
||||
// real call elements
|
||||
{
|
||||
final Iterator<ConnectedElement<BiConsumer<T, U>>> iterator = tmp.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final ConnectedElement<BiConsumer<T, U>> elem = iterator.next();
|
||||
BiConsumer<T, U> tmpObject = elem.getConsumer();
|
||||
if (tmpObject == null) {
|
||||
continue;
|
||||
}
|
||||
tmpObject.accept(valueT, valueU);
|
||||
final Iterator<ConnectedElement<BiConsumer<T, U>>> iterator = tmp.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final ConnectedElement<BiConsumer<T, U>> elem = iterator.next();
|
||||
BiConsumer<T, U> tmpObject = elem.getConsumer();
|
||||
if (tmpObject == null) {
|
||||
continue;
|
||||
}
|
||||
tmpObject.accept(valueT, valueU);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,36 +51,19 @@ import org.atriasoft.esignal.internal.ConnectedElement;
|
||||
public class SignalEmpty extends GenericSignal<Runnable> {
|
||||
|
||||
public void emit() {
|
||||
List<ConnectedElement<Runnable>> tmp;
|
||||
// clean the list:
|
||||
synchronized(this.data) {
|
||||
final Iterator<ConnectedElement<Runnable>> iterator = this.data.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final ConnectedElement<Runnable> elem = iterator.next();
|
||||
Object tmpObject = elem.getConsumer();
|
||||
if (tmpObject == null) {
|
||||
elem.disconnect();
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
// simple optimization:
|
||||
if (this.data.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// clone the list to permit to have asynchronous remove call
|
||||
tmp = new ArrayList<>(this.data);
|
||||
List<ConnectedElement<Runnable>> tmp = getACleanedList();
|
||||
if (tmp == null) {
|
||||
return;
|
||||
}
|
||||
// real call elements
|
||||
{
|
||||
final Iterator<ConnectedElement<Runnable>> iterator = tmp.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final ConnectedElement<Runnable> elem = iterator.next();
|
||||
Runnable tmpObject = elem.getConsumer();
|
||||
if (tmpObject == null) {
|
||||
continue;
|
||||
}
|
||||
tmpObject.run();
|
||||
final Iterator<ConnectedElement<Runnable>> iterator = tmp.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final ConnectedElement<Runnable> elem = iterator.next();
|
||||
Runnable tmpObject = elem.getConsumer();
|
||||
if (tmpObject == null) {
|
||||
continue;
|
||||
}
|
||||
tmpObject.run();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,9 +117,7 @@ public class TestSignalEmpty {
|
||||
receiver = null;
|
||||
Assertions.assertEquals(1, sender.signalEvent.size());
|
||||
System.gc();
|
||||
|
||||
sender.sendEvent();
|
||||
Assertions.assertEquals(0, sender.signalEvent.size());
|
||||
Assertions.assertEquals(0, sender.signalEvent.sizeCleaned());
|
||||
Log.warning("Test 1 [ END ]");
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user