123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 |
- package me.hammerle.snuviscript.code;
- import java.util.ArrayList;
- import me.hammerle.snuviscript.inputprovider.InputProvider;
- import java.util.Collection;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.function.Consumer;
- import me.hammerle.snuviscript.exceptions.PreScriptException;
- public class ScriptManager
- {
- private final ISnuviLogger logger;
- private final ISnuviScheduler scheduler;
-
- private final HashMap<Integer, Script> scripts = new HashMap<>();
- private final HashMap<String, HashSet<Script>> loadedEvents = new HashMap<>();
-
- private boolean isIterating = false;
- private final ArrayList<Script> addList = new ArrayList<>();
- private final ArrayList<Script> removeList = new ArrayList<>();
- private final ArrayList<Runnable> eventAddList = new ArrayList<>();
-
- public ScriptManager(ISnuviLogger logger, ISnuviScheduler scheduler)
- {
- this.logger = logger;
- this.scheduler = scheduler;
- }
- public ISnuviLogger getLogger()
- {
- return logger;
- }
- public ISnuviScheduler getScheduler()
- {
- return scheduler;
- }
-
- // -------------------------------------------------------------------------
- // function registry
- // -------------------------------------------------------------------------
- public void registerFunction(String s, ExceptionBiFunction<Script, InputProvider[], Object> f)
- {
- FunctionRegistry.registerFunction(s, f);
- }
-
- public void registerAlias(String original, String alias)
- {
- FunctionRegistry.registerAlias(original, alias);
- }
-
- // -------------------------------------------------------------------------
- // script controller
- // -------------------------------------------------------------------------
-
- public Script getScript(int id)
- {
- return scripts.get(id);
- }
-
- private void removeScriptUnsafe(Script sc)
- {
- sc.term();
- sc.onTerm();
- scripts.remove(sc.getId());
- loadedEvents.values().forEach(list -> list.remove(sc));
- }
-
- private void addScript(Script sc)
- {
- scripts.put(sc.getId(), sc);
- sc.onStart();
- sc.run();
- if(sc.shouldTerm())
- {
- removeScriptUnsafe(sc);
- }
- }
-
- private void handleQueues()
- {
- if(!removeList.isEmpty())
- {
- removeList.forEach(sc -> removeScriptUnsafe(sc));
- removeList.clear();
- }
- if(!addList.isEmpty())
- {
- addList.forEach(sc -> addScript(sc));
- addList.clear();
- }
- if(!eventAddList.isEmpty())
- {
- eventAddList.forEach(r -> r.run());
- eventAddList.clear();
- }
- }
-
- public void removeScriptSafe(Script sc)
- {
- if(isIterating)
- {
- removeList.add(sc);
- }
- else
- {
- removeScriptUnsafe(sc);
- }
- }
-
- public boolean removeScriptsSafe()
- {
- if(isIterating)
- {
- return false;
- }
- scripts.values().forEach(sc ->
- {
- sc.term();
- sc.onTerm();
- });
- scripts.clear();
- loadedEvents.values().forEach(list -> list.clear());
- return true;
- }
-
- public Collection<Script> getScripts()
- {
- return scripts.values();
- }
-
- public Script startScript(boolean rEventBroadcast, Consumer<Script> onStart, Consumer<Script> onTerm, String name, String... paths)
- {
- if(paths.length == 0)
- {
- return null;
- }
- try
- {
- Script sc = new Script(this, onStart, onTerm, name, paths);
- sc.setEventBroadcast(rEventBroadcast);
- if(isIterating)
- {
- addList.add(sc);
- }
- else
- {
- addScript(sc);
- }
- return sc;
- }
- catch(PreScriptException ex)
- {
- logger.print(null, ex, null, paths[0], null, ex.getLine());
- return null;
- }
- }
-
- public Script startScript(boolean rEventBroadcast, String name, String... paths)
- {
- return startScript(rEventBroadcast, null, null, name, paths);
- }
-
- // -------------------------------------------------------------------------
- // event
- // -------------------------------------------------------------------------
-
- private void loadEventUnsafe(String event, Script sc)
- {
- HashSet<Script> set = loadedEvents.get(event);
- if(set == null)
- {
- set = new HashSet<>();
- loadedEvents.put(event, set);
- }
- set.add(sc);
- }
-
- private void unloadEventUnsafe(String event, Script sc)
- {
- HashSet<Script> set = loadedEvents.get(event);
- if(set != null)
- {
- set.remove(sc);
- }
- }
-
- public void loadEventSafe(String event, Script sc)
- {
- if(isIterating)
- {
- eventAddList.add(() -> loadEventUnsafe(event, sc));
- }
- else
- {
- loadEventUnsafe(event, sc);
- }
- }
-
- public void unloadEventSafe(String event, Script sc)
- {
- if(isIterating)
- {
- eventAddList.add(() -> unloadEventUnsafe(event, sc));
- }
- else
- {
- unloadEventUnsafe(event, sc);
- }
- }
-
- public void callEvent(String name, Consumer<Script> before, Consumer<Script> after)
- {
- /*if(isIterating)
- {
- logger.print(String.format("'%s' called while executing another event", name), null, null, null, null, -1);
- return;
- }*/
- HashSet<Script> set = loadedEvents.get(name);
- if(set == null)
- {
- return;
- }
-
- isIterating = true;
- try
- {
- set.stream().filter(sc -> sc.shouldReceiveEventBroadcast() && !sc.isHolded() && sc.isWaiting())
- .forEach(sc ->
- {
- sc.setVar("event", name);
- if(before != null)
- {
- before.accept(sc);
- }
- sc.run();
- if(after != null)
- {
- after.accept(sc);
- }
- });
- }
- catch(Exception ex)
- {
- ex.printStackTrace();
- }
- isIterating = false;
- handleQueues();
- }
-
- public boolean callEvent(String name, Script sc, Consumer<Script> before, Consumer<Script> after)
- {
- if(sc.isEventLoaded(name) && !sc.isHolded() && sc.isWaiting())
- {
- sc.setVar("event", name);
- if(before != null)
- {
- before.accept(sc);
- }
- sc.run();
- if(after != null)
- {
- after.accept(sc);
- }
- if(sc.shouldTerm())
- {
- removeScriptUnsafe(sc);
- }
- return true;
- }
- return false;
- }
- }
|