SnuviParser.java 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. package me.hammerle.snuviscript.code;
  2. import java.util.Collection;
  3. import java.util.HashMap;
  4. import java.util.LinkedList;
  5. import java.util.List;
  6. import java.util.function.BiFunction;
  7. import java.util.function.Consumer;
  8. import java.util.function.Predicate;
  9. import me.hammerle.snuviscript.exceptions.PreScriptException;
  10. public class SnuviParser
  11. {
  12. private final ISnuviLogger logger;
  13. private final ISnuviScheduler scheduler;
  14. private int idCounter;
  15. private final HashMap<Integer, Script> scripts;
  16. private final LinkedList<Integer> termQueue;
  17. public SnuviParser(ISnuviLogger logger, ISnuviScheduler scheduler)
  18. {
  19. this.logger = logger;
  20. this.scheduler = scheduler;
  21. scripts = new HashMap<>();
  22. termQueue = new LinkedList<>();
  23. idCounter = 0;
  24. }
  25. // -----------------------------------------------------------------------------------
  26. // function registry
  27. // -----------------------------------------------------------------------------------
  28. public void registerFunction(String s, BiFunction<Script, InputProvider[], Object> f)
  29. {
  30. FunctionLoader.registerFunction(s, f);
  31. }
  32. public void registerAlias(String original, String alias)
  33. {
  34. FunctionLoader.registerAlias(original, alias);
  35. }
  36. // -----------------------------------------------------------------------------------
  37. // script controller
  38. // -----------------------------------------------------------------------------------
  39. public Script getScript(int id)
  40. {
  41. return scripts.get(id);
  42. }
  43. public boolean termUnsafe(Script sc)
  44. {
  45. if(sc == null)
  46. {
  47. return false;
  48. }
  49. sc.isValid = false;
  50. sc.onTerm();
  51. return scripts.remove(sc.id) != null;
  52. }
  53. public void termSafe(Script sc)
  54. {
  55. if(sc == null)
  56. {
  57. return;
  58. }
  59. sc.isValid = false;
  60. termQueue.add(sc.id);
  61. }
  62. private void term()
  63. {
  64. if(!termQueue.isEmpty())
  65. {
  66. termQueue.forEach(i ->
  67. {
  68. Script sc = scripts.remove(i);
  69. if(sc != null)
  70. {
  71. sc.onTerm();
  72. }
  73. });
  74. termQueue.clear();
  75. }
  76. }
  77. public void termAllUnsafe()
  78. {
  79. scripts.values().forEach(sc ->
  80. {
  81. sc.onTerm();
  82. sc.isValid = false;
  83. });
  84. scripts.clear();
  85. }
  86. public Collection<Script> getScripts()
  87. {
  88. return scripts.values();
  89. }
  90. private Script startScript(String path, String end, boolean rEventBroadcast, Runnable onStart, Runnable onTerm)
  91. {
  92. try
  93. {
  94. List<String> code = Utils.readCode(path, end);
  95. Script sc = new Script(logger, scheduler, code, path, idCounter++, onStart, onTerm, rEventBroadcast);
  96. scripts.put(sc.id, sc);
  97. sc.onStart();
  98. sc.run();
  99. term();
  100. return sc;
  101. }
  102. catch(PreScriptException ex)
  103. {
  104. logger.print(ex.getLocalizedMessage(), ex, null, path, null, ex.getLine());
  105. return null;
  106. }
  107. }
  108. public Script startScript(String path, String end, boolean rEventBroadcast)
  109. {
  110. return startScript(path, end, rEventBroadcast, null, null);
  111. }
  112. // -----------------------------------------------------------------------------------
  113. // event
  114. // -----------------------------------------------------------------------------------
  115. public void callEvent(String name, Consumer<Script> before, Consumer<Script> after, Predicate<Script> check)
  116. {
  117. scripts.values().stream()
  118. .filter(sc -> sc.receiveEventBroadcast && !sc.isHolded && sc.isWaiting)
  119. .filter(sc -> sc.isEventLoaded(name))
  120. .filter(check)
  121. .forEach(sc ->
  122. {
  123. sc.setVar("event", name);
  124. if(before != null)
  125. {
  126. before.accept(sc);
  127. }
  128. sc.run();
  129. if(after != null)
  130. {
  131. after.accept(sc);
  132. }
  133. });
  134. term();
  135. }
  136. public void callEvent(String name, Consumer<Script> before, Consumer<Script> after)
  137. {
  138. callEvent(name, before, after, sc -> true);
  139. }
  140. public boolean callEvent(String name, Script sc, Consumer<Script> before, Consumer<Script> after, boolean check)
  141. {
  142. if(sc.isEventLoaded(name) && !sc.isHolded && sc.isWaiting && check)
  143. {
  144. sc.setVar("event", name);
  145. if(before != null)
  146. {
  147. before.accept(sc);
  148. }
  149. sc.run();
  150. if(after != null)
  151. {
  152. after.accept(sc);
  153. }
  154. term();
  155. return true;
  156. }
  157. return false;
  158. }
  159. public boolean callEvent(String name, Script sc, Consumer<Script> before, Consumer<Script> after)
  160. {
  161. return callEvent(name, sc, before, after, true);
  162. }
  163. }