|
1 | 1 | package mill.main.graphviz
|
2 | 2 |
|
| 3 | +import com.caoccao.javet.annotations.V8Function |
| 4 | +import com.caoccao.javet.interception.logging.JavetStandardConsoleInterceptor |
| 5 | +import com.caoccao.javet.interop.{V8Host, V8Runtime} |
3 | 6 | import guru.nidi.graphviz.attribute.Rank.RankDir
|
4 | 7 | import guru.nidi.graphviz.attribute.{Rank, Shape, Style}
|
| 8 | +import guru.nidi.graphviz.engine.{AbstractJavascriptEngine, AbstractJsGraphvizEngine, ResultHandler} |
5 | 9 | import mill.api.PathRef
|
6 | 10 | import mill.define.NamedTask
|
7 | 11 | import org.jgrapht.graph.{DefaultEdge, SimpleDirectedGraph}
|
| 12 | +import org.slf4j.LoggerFactory |
| 13 | +import org.slf4j.Logger |
8 | 14 |
|
9 | 15 | object GraphvizTools {
|
10 | 16 |
|
@@ -61,17 +67,58 @@ object GraphvizTools {
|
61 | 67 |
|
62 | 68 | g = g.graphAttr().`with`(Rank.dir(RankDir.LEFT_TO_RIGHT))
|
63 | 69 |
|
64 |
| - val gv = Graphviz.fromGraph(g).totalMemory(100 * 1000 * 1000) |
| 70 | + Graphviz.useEngine(new AbstractJsGraphvizEngine(true, () => new V8JavascriptEngine()) {}) |
| 71 | + val gv = Graphviz.fromGraph(g).totalMemory(128 * 1024 * 1024) |
65 | 72 | val outputs = Seq(
|
66 | 73 | Format.PLAIN -> "out.txt",
|
67 | 74 | Format.XDOT -> "out.dot",
|
68 | 75 | Format.JSON -> "out.json",
|
69 | 76 | Format.PNG -> "out.png",
|
70 | 77 | Format.SVG -> "out.svg"
|
71 | 78 | )
|
| 79 | + |
72 | 80 | for ((fmt, name) <- outputs) {
|
73 | 81 | gv.render(fmt).toFile((dest / name).toIO)
|
74 | 82 | }
|
75 | 83 | outputs.map(x => mill.PathRef(dest / x._2))
|
76 | 84 | }
|
77 | 85 | }
|
| 86 | + |
| 87 | +class V8JavascriptEngine() extends AbstractJavascriptEngine { |
| 88 | + val LOG: Logger = LoggerFactory.getLogger(classOf[V8JavascriptEngine]) |
| 89 | + val v8Runtime: V8Runtime = V8Host.getV8Instance().createV8Runtime() |
| 90 | + LOG.info("Starting V8 runtime...") |
| 91 | + LOG.info("Started V8 runtime. Initializing javascript...") |
| 92 | + val resultHandler = new ResultHandler |
| 93 | + val javetStandardConsoleInterceptor = new JavetStandardConsoleInterceptor(v8Runtime) |
| 94 | + javetStandardConsoleInterceptor.register(v8Runtime.getGlobalObject) |
| 95 | + |
| 96 | + class ResultHandlerInterceptor(resultHandler: ResultHandler) { |
| 97 | + @V8Function |
| 98 | + def result(s: String): Unit = resultHandler.setResult(s) |
| 99 | + |
| 100 | + @V8Function |
| 101 | + def error(s: String): Unit = resultHandler.setError(s) |
| 102 | + |
| 103 | + @V8Function |
| 104 | + def log(s: String): Unit = resultHandler.log(s) |
| 105 | + } |
| 106 | + val v8ValueObject = v8Runtime.createV8ValueObject |
| 107 | + v8Runtime.getGlobalObject.set("resultHandlerInterceptor", v8ValueObject) |
| 108 | + v8ValueObject.bind(new ResultHandlerInterceptor(resultHandler)) |
| 109 | + |
| 110 | + v8Runtime.getExecutor( |
| 111 | + "var result = resultHandlerInterceptor.result; " + |
| 112 | + "var error = resultHandlerInterceptor.error; " + |
| 113 | + "var log = resultHandlerInterceptor.log; " |
| 114 | + ).execute() |
| 115 | + |
| 116 | + LOG.info("Initialized javascript.") |
| 117 | + |
| 118 | + override protected def execute(js: String): String = { |
| 119 | + v8Runtime.getExecutor(js).execute() |
| 120 | + resultHandler.waitFor |
| 121 | + } |
| 122 | + |
| 123 | + override def close(): Unit = v8Runtime.close() |
| 124 | +} |
0 commit comments