org.rx.core.EventTarget Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rxlib Show documentation
Show all versions of rxlib Show documentation
A set of utilities for Java
package org.rx.core;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.rx.bean.FlagsEnum;
import org.rx.bean.NEnum;
import org.rx.core.exception.InvalidException;
import java.lang.reflect.Field;
import java.util.List;
import java.util.concurrent.*;
import java.util.function.BiConsumer;
import static org.rx.core.App.*;
public interface EventTarget> {
@Slf4j
class Delegate, TArgs extends EventArgs> implements BiConsumer {
@Getter
private final List> invocationList = new CopyOnWriteArrayList<>();
@SuppressWarnings(NON_WARNING)
@Override
public void accept(TSender target, TArgs args) {
require(target, args);
FlagsEnum flags = target.eventFlags();
if (flags.has(EventTarget.EventFlags.ThreadSafe)) {
synchronized (target) {
innerRaise(target, args, flags);
}
return;
}
innerRaise(target, args, flags);
}
private void innerRaise(TSender target, TArgs args, FlagsEnum flags) {
for (BiConsumer biConsumer : invocationList) {
try {
biConsumer.accept(target, args);
} catch (Exception e) {
if (!flags.has(EventTarget.EventFlags.Quietly)) {
throw e;
}
log.warn("innerRaise", e);
}
}
}
}
@RequiredArgsConstructor
enum EventFlags implements NEnum {
None(0),
DynamicAttach(1),
ThreadSafe(1 << 1),
Quietly(1 << 2);
@Getter
private final int value;
}
default FlagsEnum eventFlags() {
return EventFlags.DynamicAttach.flags();
}
default void attachEvent(String eventName, BiConsumer event) {
attachEvent(eventName, event, true);
}
@SuppressWarnings(NON_WARNING)
@SneakyThrows
default void attachEvent(String eventName, BiConsumer event, boolean combine) {
require(eventName);
Field field = Reflects.getFields(this.getClass()).firstOrDefault(p -> p.getName().equals(eventName));
if (field == null) {
if (!eventFlags().has(EventFlags.DynamicAttach)) {
throw new InvalidException("Event %s not defined", eventName);
}
EventListener.getInstance().attach(this, eventName, event, combine);
return;
}
field.set(this, combine ? combine((BiConsumer) field.get(this), event) : event);
}
@SuppressWarnings(NON_WARNING)
@SneakyThrows
default void detachEvent(String eventName, BiConsumer event) {
require(eventName);
Field field = Reflects.getFields(this.getClass()).firstOrDefault(p -> p.getName().equals(eventName));
if (field == null) {
if (!eventFlags().has(EventFlags.DynamicAttach)) {
throw new InvalidException("Event %s not defined", eventName);
}
EventListener.getInstance().detach(this, eventName, event);
return;
}
field.set(this, remove((BiConsumer) field.get(this), event));
}
@SuppressWarnings(NON_WARNING)
@SneakyThrows
default void raiseEvent(String eventName, TArgs args) {
require(eventName);
Field field = Reflects.getFields(this.getClass()).firstOrDefault(p -> p.getName().equals(eventName));
if (field == null) {
if (!eventFlags().has(EventFlags.DynamicAttach)) {
throw new InvalidException("Event %s not defined", eventName);
}
EventListener.getInstance().raise(this, eventName, args);
return;
}
raiseEvent((BiConsumer) field.get(this), args);
}
@SuppressWarnings(NON_WARNING)
default void raiseEvent(BiConsumer event, TArgs args) {
require(args);
if (event == null) {
return;
}
event.accept((TSender) this, args);
}
//Java 11 and ForkJoinPool.commonPool() class loading issue
// ThreadPoolExecutor threadPool = new ThreadPoolExecutor(ThreadPool.CPU_THREADS, ThreadPool.CPU_THREADS,
// 0L, TimeUnit.MILLISECONDS,
// new LinkedTransferQueue<>(), Tasks.getExecutor().getThreadFactory());
default CompletableFuture raiseEventAsync(String eventName, TArgs args) {
return Tasks.run(() -> raiseEvent(eventName, args));
// return CompletableFuture.runAsync(() -> raiseEvent(eventName, args), threadPool);
}
default CompletableFuture raiseEventAsync(BiConsumer event, TArgs args) {
return Tasks.run(() -> raiseEvent(event, args));
// return CompletableFuture.runAsync(() -> raiseEvent(event, args), threadPool);
}
}