Skip to content

Commit 6c59af2

Browse files
committed
Improve scripting eval
1 parent 8cf98d4 commit 6c59af2

File tree

5 files changed

+70
-69
lines changed

5 files changed

+70
-69
lines changed

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
<repositories>
2828
<repository>
2929
<id>ci</id>
30-
<url>http://ci.mengcraft.com:8080/plugin/repository/everything/</url>
30+
<url>http://ci.mengcraft.com:8081/plugin/repository/everything/</url>
3131
</repository>
3232
<repository>
3333
<id>placeholder</id>
@@ -40,7 +40,7 @@
4040
<groupId>org.spigotmc</groupId>
4141
<artifactId>spigot</artifactId>
4242
<version>1.12.2-R0.1-SNAPSHOT</version>
43-
<!--<scope>provided</scope>-->
43+
<scope>provided</scope>
4444
</dependency>
4545
<dependency>
4646
<groupId>me.clip</groupId>

src/main/java/com/mengcraft/script/ScriptBootstrap.java

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -45,35 +45,39 @@
4545
*/
4646
public final class ScriptBootstrap extends JavaPlugin {
4747

48+
private static ScriptBootstrap plugin;
49+
private Map<String, Object> scripts;
50+
private ScriptEngine jsEngine;
4851
private final Map<String, HandledExecutor> executor = new HashMap<>();
49-
private Map<String, Object> plugin;
50-
private ScriptLoader loader;
52+
private ScriptLoader scriptLoader;
5153
private Unsafe unsafe;
52-
private final ThreadLocal<ScriptEngine> jsEngine = ThreadLocal.withInitial(() -> new ScriptEngineManager().getEngineByExtension("js"));
53-
private static ScriptBootstrap instance;
5454

5555
public static ScriptBootstrap get() {
56-
return instance;
56+
return plugin;
5757
}
5858

5959
@SneakyThrows
60-
public static Object require(ScriptEngine ctx, File jsFile) {
60+
public static Object require(File jsFile) {
61+
ScriptEngine ctx = jsEngine();
6162
Bindings bindings = ctx.createBindings();
6263
ctx.eval("exports = {}", bindings);
6364
ctx.eval(Files.newReader(jsFile, StandardCharsets.UTF_8), bindings);
6465
return ctx.eval("exports", bindings);
6566
}
6667

67-
public ScriptEngine jsEngine() {
68-
return jsEngine.get();
68+
public static ScriptEngine jsEngine() {
69+
return plugin.jsEngine;
6970
}
7071

7172
@Override
72-
public void onEnable() {
73-
instance = this;
74-
75-
loader = new ScriptLoader(this);
73+
public void onLoad() {
74+
plugin = this;
75+
jsEngine = new ScriptEngineManager(getClassLoader()).getEngineByExtension("js");
76+
}
7677

78+
@Override
79+
public void onEnable() {
80+
scriptLoader = new ScriptLoader();
7781
getServer().getConsoleSender().sendMessage(ArrayHelper.toArray(
7882
ChatColor.GREEN + "梦梦家高性能服务器出租店",
7983
ChatColor.GREEN + "shop105595113.taobao.com"));
@@ -103,14 +107,14 @@ protected void reload() {
103107
@Override
104108
@SneakyThrows
105109
public void onDisable() {
106-
for (Map.Entry<String, Object> i : new HashMap<>(plugin).entrySet()) {
110+
for (Map.Entry<String, Object> i : new HashMap<>(scripts).entrySet()) {
107111
((Closeable) i.getValue()).close();
108112
}
109-
plugin = null;
113+
scripts = null;
110114
}
111115

112116
private void loadAll() {
113-
plugin = new HashMap<>();
117+
scripts = new HashMap<>();
114118
for (File obj : getDataFolder().listFiles()) {
115119
if (obj.isFile() && obj.getName().matches(".+\\.js")) {
116120
try {
@@ -126,10 +130,10 @@ private void loadAll() {
126130

127131
private void loadEx(File obj) {
128132
ScriptingLoader scripting = new ScriptingLoader(obj);
129-
if (plugin.containsKey(scripting.getName())) {
130-
getLogger().warning(String.format("!!! name conflict between %s and %s", scripting.getId(), ((Named) plugin.get(scripting.getName())).getId()));
133+
if (scripts.containsKey(scripting.getName())) {
134+
getLogger().warning(String.format("!!! name conflict between %s and %s", scripting.getId(), ((Named) scripts.get(scripting.getName())).getId()));
131135
} else {
132-
plugin.put(scripting.getName(), scripting);
136+
scripts.put(scripting.getName(), scripting);
133137
Bukkit.getPluginManager().enablePlugin(scripting);
134138
}
135139
}
@@ -158,15 +162,15 @@ private boolean isLoaded(File file) {
158162
}
159163

160164
private void load(ScriptLoader.ScriptInfo info) throws ScriptPluginException {
161-
ScriptLoader.ScriptBinding binding = loader.load(info);
165+
ScriptLoader.ScriptBinding binding = scriptLoader.load(info);
162166
ScriptPlugin loaded = binding.getPlugin();
163167
if (loaded.isHandled() && !loaded.isIdled()) {
164168
String name = loaded.getDescription("name");
165-
Named i = (Named) plugin.get(name);
169+
Named i = (Named) scripts.get(name);
166170
if (!nil(i)) {
167171
ScriptPluginException.thr(loaded, "Name conflict with " + i.getId());
168172
}
169-
plugin.put(name, binding);
173+
scripts.put(name, binding);
170174
}
171175
}
172176

@@ -175,7 +179,7 @@ public static boolean nil(Object i) {
175179
}
176180

177181
Named lookById(String id) {
178-
for (Object obj : plugin.values()) {
182+
for (Object obj : scripts.values()) {
179183
Named named = (Named) obj;
180184
if (named.getId().equals(id)) {
181185
return named;
@@ -185,7 +189,7 @@ Named lookById(String id) {
185189
}
186190

187191
public ImmutableList<String> list() {
188-
return ImmutableList.copyOf(plugin.keySet());
192+
return ImmutableList.copyOf(scripts.keySet());
189193
}
190194

191195
@SuppressWarnings("unchecked")
@@ -232,29 +236,29 @@ protected boolean remove(HandledExecutor handled) {
232236
boolean unload(ScriptPlugin i) {
233237
String id = i.getDescription("name");
234238
if (nil(id)) return false;
235-
Object obj = plugin.get(id);
239+
Object obj = scripts.get(id);
236240
ScriptLoader.ScriptBinding binding = obj instanceof ScriptLoader.ScriptBinding ? (ScriptLoader.ScriptBinding) obj : null;
237-
return !nil(binding) && binding.getPlugin() == i && plugin.remove(id, binding);
241+
return !nil(binding) && binding.getPlugin() == i && scripts.remove(id, binding);
238242
}
239243

240244
public void unload(ScriptingLoader scripting) {
241-
if (plugin.remove(scripting.getName(), scripting)) {
245+
if (scripts.remove(scripting.getName(), scripting)) {
242246
Bukkit.getPluginManager().disablePlugin(scripting);
243247
}
244248
}
245249

246250
@SneakyThrows
247251
boolean unload(String id) {
248-
if (plugin.containsKey(id)) {
249-
((Closeable) plugin.get(id)).close();
252+
if (scripts.containsKey(id)) {
253+
((Closeable) scripts.get(id)).close();
250254
return true;
251255
}
252256
val binding = getSBinding(id);
253257
return !nil(binding) && binding.getPlugin().unload();
254258
}
255259

256260
public ScriptLoader.ScriptBinding getSBinding(String name) {
257-
Object binding = plugin.get(name);
261+
Object binding = scripts.get(name);
258262
if (nil(binding) && name.startsWith("file:")) {
259263
binding = lookById(name);
260264
}
@@ -282,9 +286,9 @@ public Plugin getPlugin(String id) {
282286
return main.getServer().getPluginManager().getPlugin(id);
283287
}
284288

285-
public ScriptEngine getScript(String id) {
289+
public Object getScript(String id) {
286290
ScriptLoader.ScriptBinding binding = main.getSBinding(id);
287-
return !nil(binding) ? binding.getEngine() : null;
291+
return !nil(binding) ? binding.getScriptObj() : null;
288292
}
289293

290294
public BossBar createBossBar(String text) {

src/main/java/com/mengcraft/script/ScriptPlugin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ public String format(Player p, String input) {
279279
}
280280

281281
public Object require(String path) {
282-
return ScriptBootstrap.require(ScriptBootstrap.get().jsEngine(), new File(ScriptBootstrap.get().getDataFolder(), path));
282+
return ScriptBootstrap.require(new File(ScriptBootstrap.get().getDataFolder(), path));
283283
}
284284

285285
public EventMapping getMapping() {

src/main/java/com/mengcraft/script/loader/ScriptLoader.java

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@
99
import lombok.experimental.Delegate;
1010
import org.bukkit.command.CommandSender;
1111

12+
import javax.script.Bindings;
1213
import javax.script.Invocable;
14+
import javax.script.ScriptContext;
1315
import javax.script.ScriptEngine;
14-
import javax.script.ScriptEngineManager;
1516
import javax.script.ScriptException;
1617
import java.io.Closeable;
1718
import java.io.Reader;
@@ -24,37 +25,38 @@
2425
*/
2526
public class ScriptLoader {
2627

27-
private final ScriptBootstrap main;
28-
29-
public ScriptLoader(ScriptBootstrap main) {
30-
this.main = main;
31-
}
32-
3328
@SuppressWarnings("unchecked")
3429
public ScriptBinding load(ScriptInfo info) throws ScriptPluginException {
35-
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
36-
ScriptPlugin plugin = new ScriptPlugin(main, info.id);
37-
engine.put("plugin", plugin);
38-
engine.put("arg", info.arg);
39-
engine.put("loader", info.loader);
30+
ScriptBootstrap bootstrap = ScriptBootstrap.get();
31+
ScriptPlugin plugin = new ScriptPlugin(bootstrap, info.id);
32+
ScriptEngine ctx = ScriptBootstrap.jsEngine();
33+
Bindings bindings = ctx.getBindings(ScriptContext.ENGINE_SCOPE);
34+
ctx.setBindings(ctx.createBindings(), ScriptContext.ENGINE_SCOPE);
35+
ctx.put("plugin", plugin);
36+
ctx.put("arg", info.arg);
37+
ctx.put("loader", info.loader);
38+
Object scriptObj = null;
4039
try {
41-
engine.eval(info.contend);
40+
ctx.eval(info.contend);
41+
scriptObj = ctx.eval("this");
4242
} catch (ScriptException e) {
43+
ctx.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
4344
ScriptPluginException.thr(plugin, e.getMessage());
4445
}
45-
Object description = engine.get("description");
46-
if (Map.class.isInstance(description)) {
46+
Object description = ctx.get("description");
47+
if (description instanceof Map) {
4748
plugin.setDescription((Map) description);
4849
if (nil(plugin.getDescription("name"))) {
4950
plugin.setDescription("name", info.id);
5051
}
51-
loadListener(plugin, engine);
52-
main.getLogger().info(load(plugin));
52+
loadListener(plugin, ctx);
53+
bootstrap.getLogger().info(load(plugin));
5354
} else {
5455
plugin.setDescription("name", info.id);
55-
main.getLogger().info("Load script " + info.id);
56+
bootstrap.getLogger().info("Load script " + info.id);
5657
}
57-
return ScriptBinding.bind(plugin, engine);
58+
ctx.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
59+
return ScriptBinding.bind(plugin, scriptObj);
5860
}
5961

6062
private static String load(ScriptPlugin plugin) {
@@ -73,20 +75,16 @@ private static String load(ScriptPlugin plugin) {
7375
return b.toString();
7476
}
7577

76-
private static void loadListener(ScriptPlugin plugin, ScriptEngine engine) {
78+
private static void loadListener(ScriptPlugin plugin, ScriptEngine ctx) {
7779
String handle = plugin.getDescription("handle");
7880
if (!nil(handle) && EventMapping.INSTANCE.initialized(handle)) {
79-
ScriptListener listener = getInterface(engine, ScriptListener.class);
81+
ScriptListener listener = ((Invocable) ctx).getInterface(ScriptListener.class);
8082
if (!nil(listener)) {
8183
plugin.addListener(handle, listener);
8284
}
8385
}
8486
}
8587

86-
private static <T> T getInterface(ScriptEngine engine, Class<T> i) {
87-
return Invocable.class.cast(engine).getInterface(i);
88-
}
89-
9088
@Builder
9189
public final static class ScriptInfo {
9290

@@ -100,19 +98,19 @@ public final static class ScriptBinding implements Closeable, Named {
10098

10199
@Delegate(types = Named.class)
102100
private final ScriptPlugin plugin;
103-
private final ScriptEngine engine;
101+
private final Object scriptObj;
104102

105-
private ScriptBinding(ScriptPlugin plugin, ScriptEngine engine) {
103+
private ScriptBinding(ScriptPlugin plugin, Object scriptObj) {
106104
this.plugin = plugin;
107-
this.engine = engine;
105+
this.scriptObj = scriptObj;
108106
}
109107

110108
public ScriptPlugin getPlugin() {
111109
return plugin;
112110
}
113111

114-
public ScriptEngine getEngine() {
115-
return engine;
112+
public Object getScriptObj() {
113+
return scriptObj;
116114
}
117115

118116
@Override
@@ -125,8 +123,8 @@ public void close() {
125123
plugin.unload();
126124
}
127125

128-
private static ScriptBinding bind(ScriptPlugin plugin, ScriptEngine engine) {
129-
return new ScriptBinding(plugin, engine);
126+
private static ScriptBinding bind(ScriptPlugin plugin, Object scriptObj) {
127+
return new ScriptBinding(plugin, scriptObj);
130128
}
131129

132130
}

src/main/java/com/mengcraft/script/plugin/ScriptingLoader.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
import javax.script.Bindings;
3434
import javax.script.Invocable;
3535
import javax.script.ScriptEngine;
36-
import javax.script.ScriptEngineManager;
3736
import java.io.Closeable;
3837
import java.io.File;
3938
import java.io.FileInputStream;
@@ -165,7 +164,7 @@ public void onLoad() {
165164
@Override
166165
@SneakyThrows
167166
public void onEnable() {
168-
ScriptEngine ctx = ScriptBootstrap.get().jsEngine();
167+
ScriptEngine ctx = ScriptBootstrap.jsEngine();
169168
Bindings bindings = ctx.createBindings();
170169
Object global = ctx.eval("this", bindings);
171170
Object jsObject = ctx.eval("Object", bindings);
@@ -284,7 +283,7 @@ public void close() {
284283
}
285284

286285
public Object require(String path) {
287-
return ScriptBootstrap.require(ScriptBootstrap.get().jsEngine(), new File(dataFolder, path));
286+
return ScriptBootstrap.require(new File(dataFolder, path));
288287
}
289288

290289
//===== Scripting Logic

0 commit comments

Comments
 (0)