package wow.doge.mygame.state import ammonite.runtime.Storage.Folder import ammonite.main.Defaults import ammonite.Main import javax.script.ScriptEngine import com.jme3.app.Application import com.jme3.app.state.AppState import akka.actor.typed.scaladsl.AbstractBehavior import akka.actor.typed.scaladsl.ActorContext import akka.actor.typed.Behavior import akka.actor.typed.ActorRef import ammonite.util.Res.Success import akka.actor.typed.scaladsl.Behaviors import akka.actor.typed.SpawnProtocol class ScriptingEngineState( sse: ScalaScriptingEngine, kse: KotlinScriptingEngine ) extends MyBaseState { // implicit val actorSystem = // ActorSystem.create(MyActorSystem(), "rootActor") // implicit val timeout: Timeout = Timeout(3.seconds) // val scalaScriptActor: Future[ActorRef[ScalaScriptBehavior.Command]] = // actorSystem.ask( // SpawnProtocol.Spawn( // ScalaScriptBehavior(sse.runner), // name = "ScalaScriptCompilerActor", // Props.empty, // _ // ) // ) override protected def cleanup(app: Application): Unit = { // actorSystem.terminate() } // override protected def initialize(app: Application): Unit = { // super.initialize(app) // } override def init() = { // Future { // while (true) { // // super.update(tpf) // val (res, k) = sse.runner.runScript( // // os.Path(getClass().getResource("/hello.sc").getPath), // os.pwd / "src" / "main" / "resources" / "hello.sc", // Seq.empty // // Seq(("start", None)) // // Scripts.groupArgs(List("")) // ) // val ms = res.map(_.asInstanceOf[GameScript]) // ms.map(_.start()) // val res2 = kse.engine.eval( // os.read(os.pwd / "src" / "main" / "resources" / "hello.main.kts") // ) // // val res2 = engine.eval(getClass().getResource("/hello.main.kts").getPath) // // val invoker = engine.asInstanceOf[Invocable] // // val scr = invoker.getInterface(res2, classOf[GameScript]) // val scr = res2.asInstanceOf[GameScript] // scr.start() // Thread.sleep(2000) // } // } // Future { // sse.runner // .runScript( // os.pwd / "src" / "main" / "resources" / "hello2.sc", // Seq.empty // ) // ._1 // .map(_.asInstanceOf[MyBaseState]) // .map(s => stateManager.attach(s)) // () // } // val res = scalaScriptActor // .map( // _.ask(ref => // ScalaScriptBehavior.Compile( // ref, // os.pwd / "src" / "main" / "resources" / "hello2.sc" // // os.Path(getClass().getResource("/hello2.sc").getPath) // ) // )(Timeout(10.seconds), actorSystem.scheduler) // ) // .flatten // res.foreach(_ match { // case AppStateResult(state) => { // stateManager.attach(state) // } // case wow.doge.mygame.state.ScalaScriptBehavior.Error(reason) => // println("error") // }) } override def update(tpf: Float): Unit = {} override protected def onEnable(): Unit = {} override protected def onDisable(): Unit = {} } object MyActorSystem { def apply(): Behavior[SpawnProtocol.Command] = Behaviors.setup { context => // Start initial tasks // context.spawn(...) SpawnProtocol() } } class ScalaScriptingEngine( val runner: Main = ammonite .Main( // predefCode = """ // import coursierapi.MavenRepository // interp.repositories.update( // interp.repositories() ::: List( // MavenRepository.of("file://home/rohan/.m2/repository") // ) // ) // @ // """, defaultPredef = false, storageBackend = new Folder(Defaults.ammoniteHome, isRepl = false) ) ) {} class KotlinScriptingEngine(val engine: ScriptEngine) { // val manager = new ScriptEngineManager() // val engine = manager.getEngineByExtension("main.kts") } object ScalaScriptBehavior { sealed trait Result final case class AppStateResult(state: AppState) extends Result final case class Error(reason: String) extends Result sealed trait Command final case class Compile(sender: ActorRef[Result], path: os.Path) extends Command // final case class CompileScripts(sender: ActorRef[Result], paths: os.Path*) // extends Command def apply( runner: Main = ammonite .Main( storageBackend = new Folder( // os.pwd / "target" Defaults.ammoniteHome, isRepl = false ) ) ) = Behaviors.setup(ctx => new ScalaScriptActor(runner, ctx)) private class ScalaScriptActor( val runner: Main, context: ActorContext[Command] ) extends AbstractBehavior[Command](context) { override def onMessage(msg: Command): Behavior[Command] = { msg match { case Compile(sender, path) => context.log.debug(s"Received $path") val res = getScript(path) println(res) sender ! res Behaviors.same // case CompileScripts(sender, paths) => } } def getScript(path: os.Path): Result = { runner .runScript( path, Seq.empty ) ._1 match { case ammonite.util.Res.Exception(t, msg) => Error(msg) case Success(obj) => obj match { case s: MyBaseState => AppStateResult(s) case _ => Error("Unknown script type") // AppStateResult(s.asInstanceOf[AppState]) } case _ => Error("Failed to run script") } } } }