Merge remote-tracking branch 'origin/master'

This commit is contained in:
Him188moe 2019-08-09 00:07:03 +08:00
commit 9e21ebcb6f
13 changed files with 266 additions and 45 deletions

View File

@ -1,11 +1,45 @@
package net.mamoe.mirai;
import net.mamoe.mirai.event.MiraiEventHook;
import net.mamoe.mirai.event.events.server.ServerDisableEvent;
/**
* @author Him188moe @ Mirai Project
*/
public final class MiraiMain {
private static MiraiServer server;
public static void main(String[] args) {
server = new MiraiServer();
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
server.shutdown();
}));
server.getEventManager()
.onEvent(ServerDisableEvent.class)
.setHandler(a -> {
System.out.println("?");
});
server.getEventManager()
.onEventOnce(ServerDisableEvent.class)
.setHandler(a -> {
System.out.println("?");
});
server.getEventManager()
.onEvent(ServerDisableEvent.class)
.setHandler(a -> {
System.out.println("?");
})
.setValidWhile((a) -> true);
server.getEventManager()
.onEvent(ServerDisableEvent.class)
.setHandler(a -> {
System.out.println("?");
})
.setValidUntil((a) -> true);
}
}

View File

@ -0,0 +1,65 @@
package net.mamoe.mirai;
import lombok.Getter;
import net.mamoe.mirai.event.MiraiEventManager;
import net.mamoe.mirai.event.events.MiraiEvent;
import net.mamoe.mirai.event.events.server.ServerDisableEvent;
import net.mamoe.mirai.event.events.server.ServerEnableEvent;
import net.mamoe.mirai.network.Network;
import net.mamoe.mirai.task.MiraiTaskManager;
import java.io.IOException;
public class MiraiServer {
@Getter
private static MiraiServer instance;
protected MiraiServer(){
instance = this;
this.onLoad();
Thread.yield();
this.onEnable();
}
private boolean enabled;
protected void shutdown(){
if(this.enabled) {
this.getEventManager().boardcastEvent(new ServerDisableEvent());
}
}
@Getter
MiraiEventManager eventManager;
@Getter
MiraiTaskManager taskManager;
private void onLoad(){
this.eventManager = MiraiEventManager.getInstance();
this.taskManager = MiraiTaskManager.getInstance();
try {
Network.start(Network.getAvaliablePort());
} catch (InterruptedException | IOException e) {
e.printStackTrace();
this.shutdown();
}
}
private void onEnable(){
this.eventManager.boardcastEvent(new ServerEnableEvent());
this.enabled = true;
}
}

View File

@ -1,8 +1,11 @@
package net.mamoe.mirai.event;
import lombok.Getter;
import net.mamoe.mirai.event.events.Cancellable;
import net.mamoe.mirai.event.events.MiraiEvent;
import java.util.function.Consumer;
import java.util.function.Predicate;
public class MiraiEventHook<T extends MiraiEvent> {
@ -11,22 +14,26 @@ public class MiraiEventHook<T extends MiraiEvent> {
@Getter
private Consumer<T> handler;
@Getter
private MiraiHookPreferences preferences;
@Getter
private int priority = 0;
@Getter
private boolean ignoreCancelled = true;
/**
* return true -> this hook need to be removed
*/
@Getter
private Predicate<T> valid;
public MiraiEventHook(Class<T> eventClass) {
this(eventClass,a -> {});
}
public MiraiEventHook(Class<T> eventClass, Consumer<T> handler){
this(eventClass,handler,new MiraiHookPreferences());
}
public MiraiEventHook(Class<T> eventClass, Consumer<T> handler, MiraiHookPreferences preferences){
this.eventClass = eventClass;
this.setHandler(handler);
this.setPreferences(preferences);
}
public MiraiEventHook<T> setHandler(Consumer<T> handler){
@ -34,11 +41,38 @@ public class MiraiEventHook<T extends MiraiEvent> {
return this;
}
public MiraiEventHook<T> setPreferences(MiraiHookPreferences preferences){
this.preferences = preferences;
public MiraiEventHook<T> setPriority(int priority){
this.priority = priority;
return this;
}
public MiraiEventHook<T> setIgnoreCancelled(boolean ignoreCancelled){
this.ignoreCancelled = ignoreCancelled;
return this;
}
private MiraiEventHook<T> setValid(Predicate<T> valid) {
this.valid = valid;
return this;
}
public MiraiEventHook<T> setValidUntil(Predicate<T> valid) {
return this.setValid(valid);
}
public MiraiEventHook<T> setValidWhile(Predicate<T> valid) {
return this.setValid(valid.negate());
}
@SuppressWarnings("unchecked")
public boolean accept(MiraiEvent event) {
if(!(event instanceof Cancellable && event.isCancelled() && this.isIgnoreCancelled())){
this.getHandler().accept((T) event);
}
return this.valid.test((T)event);
}
}

View File

@ -2,11 +2,12 @@ package net.mamoe.mirai.event;
import lombok.AllArgsConstructor;
import lombok.Data;
import net.mamoe.mirai.event.events.Cancellable;
import net.mamoe.mirai.event.events.MiraiEvent;
import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@ -17,7 +18,7 @@ public class MiraiEventManager {
private static MiraiEventManager instance;
static MiraiEventManager getInstance(){
public static MiraiEventManager getInstance(){
if(MiraiEventManager.instance == null){
MiraiEventManager.instance = new MiraiEventManager();
}
@ -25,11 +26,16 @@ public class MiraiEventManager {
}
Lock hooksLock = new ReentrantLock();
private Map<Class<? extends MiraiEvent>, List<MiraiEventConsumer<? extends MiraiEvent>>> hooks = new HashMap<>();
private Map<Class<? extends MiraiEvent>, List<MiraiEventHook<? extends MiraiEvent>>> hooks = new HashMap<>();
public <D extends MiraiEvent> void registerUntil(MiraiEventHook<D> hook, Predicate<D> toRemove){
hooks.putIfAbsent(hook.getEventClass(),new ArrayList<>());
hooks.get(hook.getEventClass()).add(new MiraiEventConsumer<>(hook,toRemove));
hooks.get(hook.getEventClass()).add(hook.setValidUntil(toRemove));
}
public <D extends MiraiEvent> void registerWhile(MiraiEventHook<D> hook, Predicate<D> toKeep){
hooks.putIfAbsent(hook.getEventClass(),new ArrayList<>());
hooks.get(hook.getEventClass()).add(hook.setValidWhile(toKeep));
}
public <D extends MiraiEvent> void registerOnce(MiraiEventHook<D> hook){
@ -40,13 +46,39 @@ public class MiraiEventManager {
this.registerUntil(hook,(a) -> false);
}
public <D extends MiraiEvent> MiraiEventHook<D> onEvent(Class<D> event){
MiraiEventHook<D> hook = new MiraiEventHook<>(event);
this.register(hook);
return hook;
}
public <D extends MiraiEvent> MiraiEventHook<D> onEventOnce(Class<D> event){
MiraiEventHook<D> hook = new MiraiEventHook<>(event);
this.registerOnce(hook);
return hook;
}
public <D extends MiraiEvent> MiraiEventHook<D> onEventUntil(Class<D> event, Predicate<D> toRemove){
MiraiEventHook<D> hook = new MiraiEventHook<>(event);
this.registerUntil(hook,toRemove);
return hook;
}
public <D extends MiraiEvent> MiraiEventHook<D> onEventWhile(Class<D> event, Predicate<D> toKeep){
MiraiEventHook<D> hook = new MiraiEventHook<>(event);
this.registerWhile(hook,toKeep);
return hook;
}
public void boardcastEvent(MiraiEvent event){
hooksLock.lock();
if(hooks.containsKey(event.getClass())){
hooks.put(event.getClass(),
hooks.get(event.getClass())
.stream()
.sorted(Comparator.comparingInt(MiraiEventConsumer::getPriority))
.sorted(Comparator.comparingInt(MiraiEventHook::getPriority))
.dropWhile(a -> a.accept(event))
.collect(Collectors.toList())
);
@ -55,23 +87,5 @@ public class MiraiEventManager {
}
}
@Data
@AllArgsConstructor
class MiraiEventConsumer<T extends MiraiEvent>{
private MiraiEventHook<T> hook;
private Predicate<T> remove;
public int getPriority(){
return hook.getPreferences().getPriority();
}
@SuppressWarnings("unchecked")
public boolean accept(MiraiEvent event) {
if(!(event instanceof Cancelable && event.isCancelled() && hook.getPreferences().isIgnoreCanceled())){
hook.getHandler().accept((T) event);
}
return remove.test((T)event);
}
}

View File

@ -1,9 +0,0 @@
package net.mamoe.mirai.event;
import lombok.Data;
@Data
public class MiraiHookPreferences {
private int priority = 0;
private boolean ignoreCanceled = true;
}

View File

@ -1,8 +1,8 @@
package net.mamoe.mirai.event;
package net.mamoe.mirai.event.events;
import lombok.Getter;
interface Cancelable {
public interface Cancellable {
boolean isCancelled();

View File

@ -1,6 +1,6 @@
package net.mamoe.mirai.event;
package net.mamoe.mirai.event.events;
import net.mamoe.jpre.event.Cancellable;
import net.mamoe.mirai.event.events.Cancellable;
import net.mamoe.mirai.utils.EventException;
public abstract class MiraiEvent {
@ -25,4 +25,13 @@ public abstract class MiraiEvent {
this.cancelled = value;
}
protected String eventName;
public String getEventName() {
if(this.eventName == null){
return this.getClass().getSimpleName();
}
return this.eventName;
}
}

View File

@ -0,0 +1,6 @@
package net.mamoe.mirai.event.events.server;
import net.mamoe.mirai.event.events.MiraiEvent;
public class ServerDisableEvent extends MiraiEvent {
}

View File

@ -0,0 +1,7 @@
package net.mamoe.mirai.event.events.server;
import net.mamoe.mirai.event.events.MiraiEvent;
public class ServerEnableEvent extends MiraiEvent {
}

View File

@ -10,6 +10,9 @@ import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.bytes.ByteArrayDecoder;
import io.netty.handler.codec.bytes.ByteArrayEncoder;
import java.io.IOException;
import java.net.ServerSocket;
/**
* JPRE 网络层启动器.
* 本类用于启动网络服务器. 包接受器请参考 {@link NetworkPacketHandler}
@ -55,4 +58,12 @@ public final class Network {
workerGroup.shutdownGracefully();
}
}
public static int getAvaliablePort() throws IOException {
ServerSocket serverSocket = new ServerSocket(0); //读取空闲的可用端口
int port = serverSocket.getLocalPort();
serverSocket.close();
return port;
}
}

View File

@ -1,4 +1,20 @@
package net.mamoe.mirai.task;
public class MiraiTaskManager {
private static MiraiTaskManager instance;
public static MiraiTaskManager getInstance(){
if(MiraiTaskManager.instance == null){
MiraiTaskManager.instance = new MiraiTaskManager();
}
return MiraiTaskManager.instance;
}
private MiraiTaskPool pool;
private MiraiTaskManager(){
}
}

View File

@ -0,0 +1,28 @@
package net.mamoe.mirai.task;
import java.util.concurrent.*;
public class MiraiTaskPool {
ExecutorService service;
protected MiraiTaskPool(){
this.service = Executors.newCachedThreadPool();
}
public <D> Future<D> submit(Callable<D> callable, MiralTaskExceptionHandler handler) {
return this.service.submit(() -> {
try {
return callable.call();
} catch (Throwable e) {
handler.onHandle(e);
return null;
}
});
}
public <D> Future<D> submit(Callable<D> callable) {
return this.submit(callable, Throwable::printStackTrace);
}
}

View File

@ -0,0 +1,6 @@
package net.mamoe.mirai.task;
@FunctionalInterface
public interface MiralTaskExceptionHandler {
void onHandle(Throwable e);
}