Skip to content

Commit 36bfc6a

Browse files
Simplify event registration and deregistration
Since Nashorn-created implementations of the org.bukkit.event.Listener interface correctly implement Object.equals() (which was not the case with Rhino), we can go back to instantiating a different Listener instance per event handler and let the Bukkit API worry about the details of RegisteredListeners. Also, Nashorn automatically implements "functional interfaces" so there is no need to explicitly create an EventExecutor.
1 parent d05448d commit 36bfc6a

2 files changed

Lines changed: 34 additions & 47 deletions

File tree

src/main/java/bukkit/org/scriptcraftjs/bukkit/ScriptCraftPlugin.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import org.bukkit.command.Command;
44
import org.bukkit.command.CommandSender;
5-
import org.bukkit.event.Listener;
65
import org.bukkit.plugin.java.JavaPlugin;
76

87
import javax.script.Invocable;
@@ -12,7 +11,7 @@
1211
import java.util.ArrayList;
1312
import java.util.List;
1413

15-
public class ScriptCraftPlugin extends JavaPlugin implements Listener
14+
public class ScriptCraftPlugin extends JavaPlugin
1615
{
1716
public boolean canary = false;
1817
public boolean bukkit = true;

src/main/js/lib/events-bukkit.js

Lines changed: 33 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
/*global Java, exports, org, __plugin */
22
var bkEventPriority = org.bukkit.event.EventPriority,
3-
bkEventExecutor = org.bukkit.plugin.EventExecutor,
4-
bkRegisteredListener = org.bukkit.plugin.RegisteredListener;
3+
bkHandlerList = org.bukkit.event.HandlerList,
4+
bkPluginManager = org.bukkit.Bukkit.pluginManager;
55

6-
function getHandlerListForEventType(eventType) {
7-
// Nashorn doesn't make inherited static methods accessible on derived
8-
// classes (see https://stackoverflow.com/a/38258630), e.g.
9-
// org.bukkit.event.block.BlockBreakEvent.getHandlerList() does not work.
10-
// So to avoid this problem, call getHandlerList using java.lang.reflect
11-
// methods.
12-
return eventType.class.getMethod('getHandlerList').invoke(null);
13-
}
6+
// Ask Nashorn to generate a class implementing the Listener
7+
// interface, so that we may instantiate it to tag our event
8+
// handlers.
9+
var ScriptCraftListener = Java.extend(org.bukkit.event.Listener, {});
1410

1511
exports.on = function(
1612
/* Java Class */
@@ -21,53 +17,45 @@ exports.on = function(
2117
/* (optional) String (HIGH, HIGHEST, LOW, LOWEST, NORMAL, MONITOR), */
2218
priority
2319
) {
24-
var handlerList, regd, eventExecutor;
25-
2620
if (typeof priority == 'undefined') {
2721
priority = bkEventPriority.HIGHEST;
2822
} else {
2923
priority = bkEventPriority[priority.toUpperCase().trim()];
3024
}
31-
handlerList = getHandlerListForEventType(eventType);
3225

3326
var result = {};
34-
eventExecutor = new bkEventExecutor({
35-
execute: function(l, evt) {
36-
function cancel() {
37-
if (evt instanceof org.bukkit.event.Cancellable) {
38-
evt.setCancelled(true);
39-
}
40-
}
41-
/*
42-
let handlers use this.cancel() to cancel the current event
43-
or this.unregister() to unregister from future events.
44-
*/
45-
var bound = {};
46-
for (var i in result) {
47-
bound[i] = result[i];
27+
var eventExecutor = function(l, evt) {
28+
function cancel() {
29+
if (evt instanceof org.bukkit.event.Cancellable) {
30+
evt.setCancelled(true);
4831
}
49-
bound.cancel = cancel;
50-
handler.call(bound, evt, cancel);
5132
}
52-
});
53-
/*
54-
wph 20130222 issue #64 bad interaction with Essentials plugin
55-
if another plugin tries to unregister a Listener (not a Plugin or a RegisteredListener)
56-
then BOOM! the other plugin will throw an error because Rhino can't coerce an
57-
equals() method from an Interface.
58-
The workaround is to make the ScriptCraftPlugin java class a Listener.
59-
Should only unregister() registered plugins in ScriptCraft js code.
60-
*/
61-
regd = new bkRegisteredListener(
62-
__plugin,
63-
eventExecutor,
33+
/*
34+
let handlers use this.cancel() to cancel the current event
35+
or this.unregister() to unregister from future events.
36+
*/
37+
var bound = {};
38+
for (var i in result) {
39+
bound[i] = result[i];
40+
}
41+
bound.cancel = cancel;
42+
handler.call(bound, evt, cancel);
43+
};
44+
45+
// Create an instance of our empty Listener implementation to track the handler
46+
var listener = new ScriptCraftListener();
47+
48+
bkPluginManager.registerEvent(
49+
eventType.class,
50+
listener,
6451
priority,
65-
__plugin,
66-
false
52+
eventExecutor,
53+
__plugin
6754
);
68-
handlerList.register(regd);
55+
6956
result.unregister = function() {
70-
handlerList.unregister(regd);
57+
bkHandlerList.unregisterAll(listener);
7158
};
59+
7260
return result;
7361
};

0 commit comments

Comments
 (0)