SnuviParser.java 5.7 KB

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