Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
ziqian zhang
Grasscutter
Commits
82bca7a6
Commit
82bca7a6
authored
Apr 26, 2022
by
KingRainbow44
Browse files
Overhaul event handling (designed by WetABQ#3417)
parent
33426fb7
Changes
4
Show whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/plugin/PluginManager.java
View file @
82bca7a6
...
...
@@ -3,9 +3,8 @@ package emu.grasscutter.plugin;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.server.event.Event
;
import
emu.grasscutter.server.event.EventHandler
;
import
emu.grasscutter.server.event.
Listener
;
import
emu.grasscutter.server.event.
HandlerPriority
;
import
emu.grasscutter.utils.Utils
;
import
org.reflections.Reflections
;
import
java.io.File
;
import
java.io.InputStreamReader
;
...
...
@@ -15,13 +14,14 @@ import java.net.URLClassLoader;
import
java.util.*
;
import
java.util.jar.JarEntry
;
import
java.util.jar.JarFile
;
import
java.util.stream.Stream
;
/**
* Manages the server's plugins & the event system.
*/
public
final
class
PluginManager
{
private
final
Map
<
String
,
Plugin
>
plugins
=
new
HashMap
<>();
private
final
Map
<
Plugin
,
List
<
Listener
>>
listeners
=
new
HashMap
<>();
private
final
List
<
EventHandler
<?
>>
listeners
=
new
LinkedList
<>();
public
PluginManager
()
{
this
.
loadPlugins
();
// Load all plugins from the plugins directory.
...
...
@@ -68,7 +68,7 @@ public final class PluginManager {
JarEntry
entry
=
entries
.
nextElement
();
if
(
entry
.
isDirectory
()
||
!
entry
.
getName
().
endsWith
(
".class"
))
continue
;
String
className
=
entry
.
getName
().
replace
(
".class"
,
""
).
replace
(
"/"
,
"."
);
Class
<?>
clazz
=
loader
.
loadClass
(
className
);
loader
.
loadClass
(
className
);
}
Class
<?>
pluginClass
=
loader
.
loadClass
(
pluginConfig
.
mainClass
);
...
...
@@ -129,11 +129,10 @@ public final class PluginManager {
/**
* Registers a plugin's event listener.
* @param plugin The plugin instance.
* @param listener The event listener.
*/
public
void
registerListener
(
Plugin
plugin
,
Listener
listener
)
{
this
.
listeners
.
computeIfAbsent
(
plugin
,
k
->
new
ArrayList
<>()).
add
(
listener
);
public
void
registerListener
(
EventHandler
<?>
listener
)
{
this
.
listeners
.
add
(
listener
);
}
/**
...
...
@@ -141,23 +140,24 @@ public final class PluginManager {
* @param event The event to invoke.
*/
public
void
invokeEvent
(
Event
event
)
{
this
.
listeners
.
values
().
stream
()
.
flatMap
(
Collection:
:
stream
)
.
forEach
(
listener
->
this
.
invokeOnListener
(
listener
,
event
));
Stream
<
EventHandler
<?>>
handlers
=
this
.
listeners
.
stream
()
.
filter
(
handler
->
event
.
getClass
().
isInstance
(
event
));
handlers
.
filter
(
handler
->
handler
.
getPriority
()
==
HandlerPriority
.
HIGH
)
.
toList
().
forEach
(
handler
->
this
.
invokeHandler
(
event
,
handler
));
handlers
.
filter
(
handler
->
handler
.
getPriority
()
==
HandlerPriority
.
NORMAL
)
.
toList
().
forEach
(
handler
->
this
.
invokeHandler
(
event
,
handler
));
handlers
.
filter
(
handler
->
handler
.
getPriority
()
==
HandlerPriority
.
LOW
)
.
toList
().
forEach
(
handler
->
this
.
invokeHandler
(
event
,
handler
));
}
/**
* Attempts to invoke the event on the provided listener.
* Performs logic checks then invokes the provided event handler.
* @param event The event passed through to the handler.
* @param handler The handler to invoke.
*/
private
void
invokeOnListener
(
Listener
listener
,
Event
event
)
{
try
{
Class
<?>
listenerClass
=
listener
.
getClass
();
Method
[]
methods
=
listenerClass
.
getMethods
();
for
(
Method
method
:
methods
)
{
if
(!
method
.
isAnnotationPresent
(
EventHandler
.
class
))
return
;
if
(!
method
.
getParameterTypes
()[
0
].
isAssignableFrom
(
event
.
getClass
()))
return
;
method
.
invoke
(
listener
,
event
);
}
}
catch
(
Exception
ignored
)
{
}
private
void
invokeHandler
(
Event
event
,
EventHandler
<?>
handler
)
{
if
(!
event
.
isCanceled
()
||
(
event
.
isCanceled
()
&&
handler
.
ignoresCanceled
())
)
handler
.
getCallback
().
accept
(
event
);
}
}
\ No newline at end of file
src/main/java/emu/grasscutter/server/event/EventHandler.java
View file @
82bca7a6
package
emu.grasscutter.server.event
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
emu.grasscutter.Grasscutter
;
/**
* Declares a class as an event listener/handler.
import
java.util.function.Consumer
;
public
final
class
EventHandler
<
E
extends
Event
>
{
private
E
event
;
private
Consumer
<
Event
>
listener
;
private
HandlerPriority
priority
;
private
boolean
handleCanceled
;
/**
* Gets which event this handler is handling.
* @return An event class.
*/
public
Event
handles
()
{
return
this
.
event
;
}
/**
* Returns the callback for the handler.
* @return A consumer callback.
*/
public
Consumer
<
Event
>
getCallback
()
{
return
this
.
listener
;
}
/**
* Returns the handler's priority.
* @return The priority of the handler.
*/
public
HandlerPriority
getPriority
()
{
return
this
.
priority
;
}
/**
* Returns if the handler will ignore cancelled events.
* @return The ignore cancelled state.
*/
public
boolean
ignoresCanceled
()
{
return
this
.
handleCanceled
;
}
/**
* Sets the callback method for when the event is invoked.
* @param listener An event handler method.
* @return Method chaining.
*/
public
EventHandler
<
E
>
listener
(
Consumer
<
Event
>
listener
)
{
this
.
listener
=
listener
;
return
this
;
}
/**
* Changes the handler's priority in handling events.
* @param priority The priority of the handler.
* @return Method chaining.
*/
public
EventHandler
<
E
>
priority
(
HandlerPriority
priority
)
{
this
.
priority
=
priority
;
return
this
;
}
/**
* Sets if the handler will ignore cancelled events.
* @param ignore If the handler should ignore cancelled events.
* @return Method chaining.
*/
public
EventHandler
<
E
>
ignore
(
boolean
ignore
)
{
this
.
handleCanceled
=
ignore
;
return
this
;
}
/**
* Registers the handler into the PluginManager.
*/
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
EventHandler
{
public
void
register
()
{
Grasscutter
.
getPluginManager
().
registerListener
(
this
);
}
}
\ No newline at end of file
src/main/java/emu/grasscutter/server/event/HandlerPriority.java
0 → 100644
View file @
82bca7a6
package
emu.grasscutter.server.event
;
public
enum
HandlerPriority
{
/**
* The handler will be called before every other handler.
*/
HIGH
,
/**
* The handler will be called the same time as other handlers.
*/
NORMAL
,
/**
* The handler will be called after every other handler.
*/
LOW
}
src/main/java/emu/grasscutter/server/event/Listener.java
deleted
100644 → 0
View file @
33426fb7
package
emu.grasscutter.server.event
;
/**
* Implementing this interface declares a class as an event listener.
*/
public
interface
Listener
{
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment