SnuviParser.java 5.5 KB

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