main.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. package main
  2. import (
  3. "flag"
  4. "git.swzry.com/ProjectNagae/NagaeJSVM/ngjsvm"
  5. "git.swzry.com/zry/GoHiedaLogger/hiedabke_console"
  6. "git.swzry.com/zry/GoHiedaLogger/hiedalog"
  7. lazyquiter "git.swzry.com/zry/go-lazy-quiter"
  8. "github.com/oklog/run"
  9. "github.com/spf13/afero"
  10. "os"
  11. "path"
  12. "path/filepath"
  13. )
  14. var Logger *hiedalog.HiedaLogger
  15. var JsFile string
  16. var DebugMode bool
  17. var LazyQuiter *lazyquiter.RunGroupQuiter
  18. func main() {
  19. // Parse command line argument
  20. flag.StringVar(&JsFile, "j", "/main.js", "")
  21. flag.BoolVar(&DebugMode, "d", false, "")
  22. flag.Parse()
  23. // Init hiedalog logger with console output backend
  24. Logger = hiedalog.NewHiedaLogger()
  25. consoleBackend := hiedabke_console.NewConsoleBackend(os.Stdout)
  26. lvfil := hiedalog.DLN_INFO
  27. if DebugMode {
  28. lvfil = hiedalog.DLN_DEBUG
  29. }
  30. Logger.AddBackend(consoleBackend, Logger.LevelFilter.NameToID(lvfil))
  31. // Get path of js-dist
  32. selfPath, err := os.Executable()
  33. if err != nil {
  34. Logger.LogPrint("main", hiedalog.DLN_FATAL, "Couldn't get executable file path: ", err)
  35. return
  36. }
  37. execDir, err := filepath.Abs(filepath.Dir(selfPath))
  38. if err != nil {
  39. Logger.LogPrint("main", hiedalog.DLN_FATAL, "Couldn't get directory of executable file: ", err)
  40. return
  41. }
  42. jsPath := path.Join(execDir, "js-dist")
  43. // Init afero Os Filesystem
  44. osFs := afero.NewOsFs()
  45. bFs := afero.NewBasePathFs(osFs, jsPath)
  46. // Init NagaeJSVM engine
  47. cfg := &ngjsvm.JSVMConfig{
  48. Filesystem: bFs,
  49. Logger: Logger,
  50. EngineLogPrefix: "js-engine",
  51. RuntimeEnvLogPrefix: "js-env",
  52. UseStrictMode: true,
  53. }
  54. engine := ngjsvm.NewJSVM(cfg)
  55. // Ensure engine disposed before quit
  56. // Tips: EngineDispose can be call multiple times, if it is already disposed,
  57. // it will do nothing.
  58. defer engine.EngineDispose()
  59. // Init RtEnv
  60. jsenv := ngjsvm.NewJSEnv(engine, Logger, "js-env")
  61. jsenv.AddRt("runtime", &ngjsvm.JSRtRuntime{})
  62. jsenv.AddRt("logger", &ngjsvm.JSRtLogger{
  63. LogFunc: ngjsvm.JSRtLoggerLogFuncFromHiedaLogger(Logger, "js-log"),
  64. })
  65. jsenv.AddRt("scheduler", &ngjsvm.JSRtScheduler{})
  66. jsenv.AddRt("nest_test", ngjsvm.NewJSRtNest(map[string]ngjsvm.JsRtInterface{
  67. "logger1": &ngjsvm.JSRtLogger{
  68. LogFunc: ngjsvm.JSRtLoggerLogFuncFromHiedaLogger(Logger, "js-sub-log1"),
  69. },
  70. }))
  71. engine.SetRuntimeEnv(jsenv)
  72. // Load script
  73. err = engine.LoadScript(JsFile)
  74. if err != nil {
  75. Logger.LogPrint("main", hiedalog.DLN_FATAL, "Failed load script: ", err)
  76. return
  77. }
  78. // Run 'setup'
  79. err = engine.ExecSetup()
  80. if err != nil {
  81. Logger.LogPrint("main", hiedalog.DLN_ERROR, "Run 'setup' failed: ", err)
  82. // will continue even if 'setup' failed.
  83. // but you can end program when 'setup' failed.
  84. // don't forget to do engine dispose
  85. }
  86. // Init lazyquiter for catching `Ctrl+C`
  87. LazyQuiter = lazyquiter.NewRunGroupQuiter()
  88. LazyQuiter.SignalNotifyFunc = func(sig os.Signal) {
  89. Logger.LogPrint("main", hiedalog.DLN_INFO, "Quit by user Ctrl+C abort.")
  90. }
  91. // Run loop
  92. rg := &run.Group{}
  93. rg.Add(LazyQuiter.Run, LazyQuiter.Stop)
  94. rg.Add(engine.RunLoop, engine.StopLoop)
  95. err = rg.Run()
  96. if err != nil {
  97. if err == ngjsvm.Err_JSVMAbortByInterruit {
  98. // this means it exit by interrupt,
  99. // for example, a 'runtime.quit()' executed in script will cause this
  100. Logger.LogPrint("main", hiedalog.DLN_INFO, "JS VM interrupted")
  101. } else {
  102. Logger.LogPrint("main", hiedalog.DLN_FATAL, "Run 'loop' failed: ", err)
  103. return
  104. }
  105. }
  106. // Run 'cleanup'
  107. err = engine.ExecCleanup()
  108. if err != nil {
  109. Logger.LogPrint("main", hiedalog.DLN_ERROR, "Run 'cleanup' failed: ", err)
  110. }
  111. // because we set 'defer engine.Dispose()' so we don't need to do it.
  112. // but you can always call it here
  113. // engine.EngineDispose()
  114. }