Skip to content

Scheduling

MattMX edited this page Jul 7, 2024 · 8 revisions

KtGui now has it's own Scheduling system, found in scheduling.kt.

Note

This feature provides a lightweight wrapper for creating BukkitTasks. To avoid callback hell, I recommend using a library such as Skedule.

Usage

Simply call async, sync following the operation.

  • sync
  • syncDelayed
  • syncRepeating
  • async
  • asyncDelayed
  • asyncRepeating
asyncDelayed(20.seconds) {
  println("20s later")
}

// BukkitTask object is both returned and accepted into the code block.
var passed = 0
val task = asyncRepeating(1.minutes) {
  println("1 minute passed")
  passed++
  
  // Cancel after 10 minutes.
  if (passed == 10) {
    cancel()
  }
}

Utility functions

We can use the following functions to help enforce thread safety.

  • forceMainThread
  • forceAsync
  • isAync

For example, if we want to make sure we are running the body of a function on the main thread:

fun foo(player: Player) = forceMainThread {
  player.sendMessage(Component.text("Main thread execution"))
}

fun bar() = forceAsync {
  // some database calls or some bulkier task
}

fun fizz() {
  println("fizz")

  forceMainThread {
    println("main")
    forceAsync {
      println("async")
    }
  }
}

As well as this, we can also call sync methods to return a future.

async {
  // Example not the best application but it does have some uses.
  val methodResult = future {
    playersCollection.find(eq("username", "MattMX")).firstOrNull()
  }.await

}

Task Trackers

KtGui 2.0 introduces the class TaskTracker, allowing you to create tasks that are stored in a list, and removed when completed. Any tasks created in that object will be stored and can be later cancelled.

An example usage would be of if you are using a "game state" system.

class Game {
  val tasks = TaskTracker()
  var state = GameState.INACTIVE
    set(value) {
      tasks.cancelAll()
      field = value
    }

  fun countdown() {
    state = GameState.COUNTDOWN
    tasks.runAsyncRepeat(20L) {
      if (iterations == 10) {
        start()
      } else {
        Bukkit.getOnlinePlayers().forEach { it.sendMessage(Component.text("Countdown ${10 - iterations}s")) } 
      }
    }
  }

  fun start() {
    // Will automatically cancel the task in `coundown` and any others.
    state = GameState.ACTIVE

   // your code ...
  }

  fun cancelGame() {
    tasks.cancelAll()
  }
}
Clone this wiki locally