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.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 def stop(): Unit = {} // 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") } } } }