package wow.doge.mygame.game import scala.collection.immutable.Queue import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.Future import com.jme3.app.SimpleApplication import com.jme3.app.state.AppState import com.jme3.bullet.BulletAppState import monix.bio.Task import monix.execution.CancelableFuture import monix.execution.CancelablePromise import monix.execution.Scheduler import monix.execution.atomic.Atomic import wow.doge.mygame.executors.GUIExecutorService import wow.doge.mygame.executors.Schedulers class SimpleAppExt( schedulers: Schedulers, val bulletAppState: BulletAppState, appStates: AppState* ) extends SimpleApplication(appStates: _*) { import SimpleAppExt._ /** * A non blocking synchronized queue using an immutable scala queue and monix's atomic class */ private val taskQueue2 = Atomic(Queue.empty[MyTask[_]]) private val startSignal: CancelablePromise[Unit] = CancelablePromise() private val terminationSignal: CancelablePromise[Unit] = CancelablePromise() var cancelToken: Option[() => Future[Unit]] = None def started: CancelableFuture[Unit] = startSignal.future def whenTerminated: CancelableFuture[Unit] = terminationSignal.future // override def physicsSpace: PhysicsSpace = ??? override def simpleInitApp(): Unit = { stateManager.attach(bulletAppState) startSignal.success(()) } override def simpleUpdate(tpf: Float): Unit = {} override def stop(waitFor: Boolean): Unit = cancelToken match { case Some(value) => value().foreach { _ => pprint.log("Called cancel in simpleapp") super.stop(true) terminationSignal.success(()) } case None => pprint.log("Called cancel in simpleapp") super.stop(true) terminationSignal.success(()) } def enqueueFuture[T](cb: () => T): CancelableFuture[T] = { val p = CancelablePromise[T]() taskQueue2.transform(_ :+ MyTask(p, cb)) p.future } def enqueueL[T](cb: () => T): Task[T] = Task.deferFuture(enqueueFuture(cb)) override protected def runQueuedTasks(): Unit = { taskQueue2.transform { current => current.dequeueOption.fold(current) { case (MyTask(p, cb), updated) => p.success(cb()) updated } } super.runQueuedTasks() } object JMEExecutorService extends GUIExecutorService { override def execute(command: Runnable): Unit = enqueue(command) } val scheduler = Scheduler(JMEExecutorService) } object SimpleAppExt { private[game] case class MyTask[T](p: CancelablePromise[T], cb: () => T) } // val ship = ed.createEntity() // val mbState = stateManager().state[EntityDataState]().map(_.getEntityData()) // val mbState = Try( // stateManager() // .state[TestAppState]() // .entity // ).toOption.flatten.toRight(println("empty")) // // .flatMap(_.entity) // val x = mbState.flatMap( // _.query // .filter[TestComponent]("name", new Object()) // // .filterOr[TestEntity]( // // Filters // // .fieldEquals(classOf[TestEntity], "", null) // // ) // .component[Tag]() // .component[TestComponent]() // .result // .toRight(println("failed")) // ) // rootNode // .child(geom) // .child(geom) // .child(geom) // .child(geom) // .child(geom) // .child(geom) // .child(geom) // .child(geom) // Future(println("hello"))(jmeEC(this)) // val wbActor: Future[ActorRef[Greeter.Greet]] = actorSystem.ask( // SpawnProtocol.Spawn( // behavior = Greeter(), // name = "listener", // DispatcherSelector.fromConfig("jme-dispatcher"), // _ // ) // ) // wbActor.map(a => a.ask(Greeter.Greet("hello", _)).map(println)) // Task(Promise[T]()).flatMap { p => // Task(taskQueue2.transform(_ :+ MyTask(p, cb))) >> // Task.fromCancelablePromise(p) // } // Task.fromCancelablePromise { // val p = Promise[T]() // taskQueue2.transform(_ :+ MyTask(p, cb)) // p // }