Skip to content

Commit

Permalink
Prepare for korlibs 6.0.0-beta1 (#2273)
Browse files Browse the repository at this point in the history
* Prepare for korlibs 6.0.0-beta1

* Do not scope to views.mouse.coroutineContext by default. Create new onClickSuspend*/onMouseStuffSuspend* variants allowing suspending, while making the older ones non-suspending so we don't have problem with the coroutineContext Job scope
Unify QView and View mouse events

* Fixes SyncEventLoop

* Upgrades xcodeGen

* Use .korge folder instead of .korlibs folder

* Some ios fixes

* Send KeyEvent.Type.TYPE events too on iOS

* Some iOS Key mapping improvements

* Add CoroutineName to several coroutines

* Avoid double initialization of scenes in korge-sandbox

* Enable corutine debug in korge-sandbox

* Allow to debug coroutines via flag

* Update MainAudioScene to test more things

* Update gradle.properties with configureondemand and configuration-cache

* More work

* Moved AudioChannel to Korge

* Minor

* Updated to 6.0.0-beta1

* Fix tests

* Fix tests

* Use Java 21
  • Loading branch information
soywiz authored Jul 22, 2024
1 parent 6f2c3ee commit 4edeb8b
Show file tree
Hide file tree
Showing 44 changed files with 314 additions and 128 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/DEPLOY.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ env:
ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.ORG_GRADLE_PROJECT_SIGNINGPASSWORD }}
SONATYPE_USERNAME: ${{ secrets.SONATYPEUSERNAME }}
SONATYPE_PASSWORD: ${{ secrets.SONATYPEPASSWORD }}
JAVA_VERSION: 17
JAVA_VERSION: 21
JAVA_DISTRIBUTION: zulu

jobs:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/TEST.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ env:
CI: true
SKIP_KORGE_SAMPLES: true
DISPLAY: ":99"
JAVA_VERSION: 17
JAVA_VERSION: 21
JAVA_DISTRIBUTION: zulu
ENABLE_BENCHMARKS: false

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ fun Project.configureNativeIosTvosRun(targetName: String) {
simulator -> if (isArm) "SimulatorArm64" else "X64"
else -> "Arm64"
}
val archNoSim = when {
simulator -> "X64"
else -> "Arm64"
}
val arch2 = when {
simulator -> if (isArm) "arm64" else "x86_64"
else -> "arm64"
Expand All @@ -229,6 +233,7 @@ fun Project.configureNativeIosTvosRun(targetName: String) {
//}
workingDir(xcodeProjDir)
doFirst {
//commandLine("xcrun", "xcodebuild", "-allowProvisioningUpdates", "-scheme", "app-$archNoSim-$debugSuffix", "-project", ".", "-configuration", debugSuffix, "-derivedDataPath", "build", "-arch", arch2, "-sdk", iosSdkExt.appleFindSdk(sdkName))
commandLine("xcrun", "xcodebuild", "-allowProvisioningUpdates", "-scheme", "app-$arch-$debugSuffix", "-project", ".", "-configuration", debugSuffix, "-derivedDataPath", "build", "-arch", arch2, "-sdk", iosSdkExt.appleFindSdk(sdkName))
println("COMMAND: ${commandLine.joinToString(" ")}")
}
Expand Down Expand Up @@ -275,7 +280,8 @@ fun Project.configureNativeIosTvosRun(targetName: String) {
val device = iosSdkExt.appleGetInstallDevice(iphoneVersion)
// xcrun simctl launch --console 7F49203A-1F16-4DEE-B9A2-7A1BB153DF70 com.sample.demo.app-X64-Debug
//logger.info(params.joinToString(" "))
execLogger { it.commandLine("xcrun", "simctl", "launch", "--console", device.udid, "${korge.id}.app-X64-$debugSuffix") }
val arch = if (isArm) "SimulatorArm64" else "X64"
execLogger { it.commandLine("xcrun", "simctl", "launch", "--console", device.udid, "${korge.id}.app-$arch-$debugSuffix") }
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,12 +243,12 @@ object IosProjectTools {
indent {
for (debug in listOf(false, true)) {
val debugSuffix = if (debug) "Debug" else "Release"
for (arch in listOf("X64", "Arm64")) {
for (arch in listOf("X64", "SimulatorArm64", "Arm64")) {
line("app-$arch-$debugSuffix:")
indent {
line("platform: ${if (targetName == "ios") "iOS" else "tvOS"}")
line("type: application")
line("deploymentTarget: \"10.0\"")
line("deploymentTarget: \"15.0\"")
line("sources:")
indent {
line("- app")
Expand All @@ -275,7 +275,7 @@ object IosProjectTools {
line(" DEVELOPMENT_TEAM: $team")
}
line("dependencies:")
line(" - framework: ../../bin/${targetName}$arch/${debugSuffix.toLowerCase()}Framework/GameMain.framework")
line(" - framework: ../../bin/${targetName}$arch/${debugSuffix.lowercase()}Framework/GameMain.framework")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ val Project.iosXcodegenExt by projectExtension {
}

class IosXcodegen(val project: Project) {
val xcodeGenGitTag = "2.37.0"
val korlibsFolder = File(System.getProperty("user.home") + "/.korlibs").apply { mkdirs() }
val xcodeGenGitTag = "2.42.0"
val korlibsFolder = File(System.getProperty("user.home") + "/.korge").apply { mkdirs() }
val xcodeGenFolder = File(korlibsFolder, "XcodeGen-$xcodeGenGitTag")
val xcodeGenLocalExecutable = File("/usr/local/bin/xcodegen")
val xcodeGenExecutable = FileList(
Expand Down
7 changes: 4 additions & 3 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,6 @@ kotlin.mpp.androidSourceSetLayoutVersion1.nowarn=true

org.gradle.daemon=true
#org.gradle.caching=true
#org.gradle.configureondemand=true
#org.gradle.unsafe.configuration-cache=true
#org.gradle.unsafe.configuration-cache-problems=warn

# https://kotlinlang.org/docs/whatsnew17.html#a-new-approach-to-incremental-compilation
kotlin.incremental.useClasspathSnapshot=true
Expand All @@ -76,3 +73,7 @@ org.gradle.parallel=true
enableMFVC=false

kotlin.mpp.applyDefaultHierarchyTemplate=false

#org.gradle.configureondemand=true
#org.gradle.unsafe.configuration-cache=true
#org.gradle.unsafe.configuration-cache-problems=warn
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ kotlinx-coroutines = "1.9.0-RC"
kotlinx-serialization = "1.7.0"
kotlinx-atomicfu = "0.24.0"

korlibs = "6.0.0-alpha9"
korlibs = "6.0.0-beta1"
#korlibs = "999.0.0.999"

kotlinx-benchmark = "0.4.7"
Expand Down
21 changes: 6 additions & 15 deletions korge-core/src/korlibs/datastructure/_Datastructure_event.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,9 @@ package korlibs.datastructure.event
import korlibs.concurrent.lock.*
import korlibs.concurrent.thread.*
import korlibs.datastructure.*
import korlibs.datastructure.lock.*
import korlibs.datastructure.lock.Lock
import korlibs.datastructure.pauseable.*
import korlibs.datastructure.thread.*
import korlibs.datastructure.thread.NativeThread
import korlibs.datastructure.thread.nativeThread
import korlibs.logger.*
import korlibs.time.*
import kotlinx.atomicfu.locks.*
import kotlin.time.*

expect fun createPlatformEventLoop(precise: Boolean = true): SyncEventLoop
Expand All @@ -24,25 +18,22 @@ interface EventLoop : Pauseable, AutoCloseable {
fun setImmediate(task: () -> Unit)
fun setTimeout(time: Duration, task: () -> Unit): AutoCloseable
fun setInterval(time: Duration, task: () -> Unit): AutoCloseable
fun setIntervalFrame(task: () -> Unit): AutoCloseable = setInterval(60.hz.timeSpan, task)
fun setIntervalFrame(task: () -> Unit): AutoCloseable = setInterval(60.hz.duration, task)
}

fun EventLoop.setInterval(time: Frequency, task: () -> Unit): AutoCloseable = setInterval(time.timeSpan, task)
fun EventLoop.setInterval(time: Frequency, task: () -> Unit): AutoCloseable = setInterval(time.duration, task)

abstract class BaseEventLoop : EventLoop, Pauseable {
val runLock = Lock()
}

open class SyncEventLoop(
/** precise=true will have better precision at the cost of more CPU-usage (busy waiting) */
//var precise: Boolean = true,
var precise: Boolean = false,
/** Execute timers immediately instead of waiting. Useful for testing. */
var immediateRun: Boolean = false,
) : BaseEventLoop(), Pauseable {
private val pauseable = SyncPauseable()
override var paused: Boolean by pauseable::paused
private val lock = korlibs.concurrent.lock.Lock()
private val lock = Lock()
private var running = true

protected class TimedTask(val eventLoop: SyncEventLoop, var now: Duration, val time: Duration, var interval: Boolean, val callback: () -> Unit) :
Expand Down Expand Up @@ -126,7 +117,7 @@ open class SyncEventLoop(

protected fun wait(waitTime: Duration) {
if (immediateRun) return
lock { lock.wait(waitTime, precise) }
lock { lock.wait(waitTime) }
}

fun runAvailableNextTasks(runTimers: Boolean = true): Int {
Expand Down Expand Up @@ -232,12 +223,12 @@ open class SyncEventLoop(
open fun start(): Unit {
if (thread != null) return
thread = nativeThread {
runTasksForever { thread?.threadSuggestRunning == true }
runTasksForever { running }
}
}

open fun stop(): Unit {
thread?.threadSuggestRunning = false
running = false
thread = null
}
}
6 changes: 4 additions & 2 deletions korge-core/src/korlibs/datastructure/thread/ThreadAlias.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package korlibs.datastructure.thread

import korlibs.concurrent.thread.*

@Deprecated("", ReplaceWith("korlibs.concurrent.thread.NativeThread"))
typealias NativeThread = korlibs.concurrent.thread.NativeThread

Expand All @@ -8,6 +10,6 @@ public fun nativeThread(
start: Boolean = true,
isDaemon: Boolean = false,
name: String? = null,
priority: Int = -1,
priority: NativeThreadPriority = NativeThreadPriority.NORMAL,
block: (NativeThread) -> Unit
): NativeThread = korlibs.concurrent.thread.nativeThread(start, isDaemon, name, priority, block)
): NativeThread = korlibs.concurrent.thread.nativeThread(isDaemon = isDaemon, name = name, priority = priority, start = start, block = block)
2 changes: 1 addition & 1 deletion korge-core/src/korlibs/render/GameWindow.kt
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ open class GameWindow :
}

open suspend fun loop(entry: suspend GameWindow.() -> Unit) {
launchImmediately(getCoroutineDispatcherWithCurrentContext()) {
launchImmediately(getCoroutineDispatcherWithCurrentContext() + CoroutineName("GameWindow.loop")) {
entry()
}
//withContext(getCoroutineDispatcherWithCurrentContext()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import kotlin.coroutines.*

@OptIn(InternalCoroutinesApi::class)
class SyncEventLoopCoroutineDispatcher(val eventLoop: SyncEventLoop) : CoroutineDispatcher(), Delay, AutoCloseable {
constructor(precise: Boolean = true, immediateRun: Boolean = false) : this(SyncEventLoop(precise, immediateRun))
constructor(immediateRun: Boolean = false) : this(SyncEventLoop(immediateRun))

override fun close() {
eventLoop.close()
Expand Down
29 changes: 14 additions & 15 deletions korge-core/src@darwin/korlibs/render/DefaultGameWindowIos.kt
Original file line number Diff line number Diff line change
Expand Up @@ -152,26 +152,25 @@ class ViewController(
@Suppress("RemoveRedundantCallsOfConversionMethods")
@OptIn(UnsafeNumber::class)
private fun pressesHandler(type: KeyEvent.Type, presses: Set<*>, withEvent: UIPressesEvent?) {
super.pressesBegan(presses, withEvent)
for (press in presses) {
if (press !is UIPress) continue
val uiKey = press.key ?: continue
val keyCode = uiKey.keyCode.toInt()
val modifierFlags = uiKey.modifierFlags.toInt()
val key = IosKeyMap.KEY_MAP[keyCode.toInt()] ?: Key.UNKNOWN
//println("pressesHandler[$type]: ${keyCode}, ${modifierFlags}, $key, ${uiKey.charactersIgnoringModifiers}")

gameWindow.dispatchKeyEventEx(
type,
0,
uiKey.charactersIgnoringModifiers.firstOrNull() ?: '\u0000',
key,
keyCode.toInt(),
shift = modifierFlags.hasFlags(UIKeyModifierShift.toInt()),
ctrl = modifierFlags.hasFlags(UIKeyModifierControl.toInt()),
alt = modifierFlags.hasFlags(UIKeyModifierAlternate.toInt()),
meta = modifierFlags.hasFlags(UIKeyModifierCommand.toInt()),
)

val char = uiKey.charactersIgnoringModifiers.firstOrNull() ?: '\u0000'

//println("pressesHandler[$type]: ${keyCode}, ${modifierFlags}, $key, char='$char', char.code=${char.code}, uiKey.characters='${uiKey.characters}'")

val shift = modifierFlags.hasFlags(UIKeyModifierShift.toInt())
val ctrl = modifierFlags.hasFlags(UIKeyModifierControl.toInt())
val alt = modifierFlags.hasFlags(UIKeyModifierAlternate.toInt())
val meta = modifierFlags.hasFlags(UIKeyModifierCommand.toInt())
if (type == KeyEvent.Type.DOWN && char >= '\u0020' && uiKey.characters.length == 1) {
gameWindow.dispatchKeyEventEx(KeyEvent.Type.TYPE, 0, char, key, keyCode.toInt(), shift = shift, ctrl = ctrl, alt = alt, meta = meta,)
}
gameWindow.dispatchKeyEventEx(type, 0, char, key, keyCode.toInt(), shift = shift, ctrl = ctrl, alt = alt, meta = meta,)
}
}

Expand All @@ -181,7 +180,7 @@ class ViewController(
}

override fun pressesEnded(presses: Set<*>, withEvent: UIPressesEvent?) {
super.pressesBegan(presses, withEvent)
super.pressesEnded(presses, withEvent)
pressesHandler(KeyEvent.Type.UP, presses, withEvent)
}

Expand Down
1 change: 1 addition & 0 deletions korge-core/src@darwin/korlibs/render/IosKeyMap.kt
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ object IosKeyMap {
put(UIKeyboardHIDUsageKeyboardEscape, Key.ESCAPE)
put(UIKeyboardHIDUsageKeyboardInsert, Key.INSERT)
put(UIKeyboardHIDUsageKeyboardReturn, Key.RETURN)
put(UIKeyboardHIDUsageKeyboardReturnOrEnter, Key.RETURN)
put(UIKeyboardHIDUsageKeyboardTab, Key.TAB)

// Function Keys
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ actual fun createPlatformEventLoop(precise: Boolean): SyncEventLoop =
open class LocalJsEventLoop(
precise: Boolean = false,
immediateRun: Boolean = false,
) : SyncEventLoop(precise, immediateRun) {
) : SyncEventLoop(precise) {
private var closeable: AutoCloseable? = null

override fun start() {
Expand Down
2 changes: 1 addition & 1 deletion korge-core/src@jvm/korlibs/render/awt/BaseAwtGameWindow.kt
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ abstract class BaseAwtGameWindow(
protected var mouseY: Int = 0

override suspend fun loop(entry: suspend GameWindow.() -> Unit) {
launchImmediately(getCoroutineDispatcherWithCurrentContext()) {
launchImmediately(getCoroutineDispatcherWithCurrentContext() + CoroutineName("BaseAwtGameWindow.loop")) {
entry()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
package korlibs.datastructure.event

actual fun createPlatformEventLoop(precise: Boolean): SyncEventLoop =
SyncEventLoop(precise = precise)
SyncEventLoop()
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
package korlibs.datastructure.event

import korlibs.datastructure.closeable.*
import korlibs.time.*
import kotlinx.browser.*

actual fun createPlatformEventLoop(precise: Boolean): SyncEventLoop =
LocalJsEventLoop(precise)
LocalJsEventLoop()

open class LocalJsEventLoop(
precise: Boolean = false,
immediateRun: Boolean = false,
) : SyncEventLoop(precise, immediateRun) {
) : SyncEventLoop(immediateRun) {
private var closeable: AutoCloseable? = null

override fun start() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class SyncEventLoopTest {
fun test() = suspendTest({ NativeThread.isSupported }) {
//fun test() = suspendTest {
repeat(2) {
val ep = SyncEventLoop(precise = true)
val ep = SyncEventLoop()
val start = TimeSource.Monotonic.markNow()
fun log(msg: String) {
println("${start.elapsedNow().milliseconds}: $msg")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import kotlin.test.*
class SyncEventLoopCoroutineDispatcherTest {
@Test
fun test() {
val dispatcher = SyncEventLoopCoroutineDispatcher(precise = true, immediateRun = true)
val dispatcher = SyncEventLoopCoroutineDispatcher(immediateRun = true)
launchImmediately(dispatcher) {
println("${DateTime.now()}: a")
delay(1000.milliseconds)
Expand Down
2 changes: 2 additions & 0 deletions korge-sandbox/src/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ suspend fun main() = Korge(
backgroundColor = DEFAULT_KORGE_BG_COLOR,
displayMode = KorgeDisplayMode.CENTER_NO_CLIP,
debug = false,
debugCoroutines = true,
//forceRenderEveryFrame = false
) {
//sceneContainer().changeTo({MainSprites10k()}); return@start
Expand Down Expand Up @@ -133,6 +134,7 @@ suspend fun main() = Korge(
//Demo(::MainShape2dScene),
//Demo(::MainUIStacks),
Demo(::MainAudioScene),
//Demo(::MainAsteroids),
//Demo(::MainSprites10k),
//Demo(::MainStressMatrixMultiplication),
//Demo(::MainSDF),
Expand Down
7 changes: 6 additions & 1 deletion korge-sandbox/src/helpers.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,21 @@ class Demo(val sceneBuilder: () -> Scene, val name: String = sceneBuilder()::cla
suspend fun Stage.demoSelector(default: Demo, all: List<Demo>) {
val container = sceneContainer(size = Size(width, height - 48f)) { }.xy(0, 48)
val containerFocus = container.makeFocusable()
var currentDemo: Demo? = null

lateinit var comboBox: UIComboBox<Demo>

suspend fun setDemo(demo: Demo?) {
if (currentDemo != demo) currentDemo = demo else return

//container.removeChildren()
//println("setDemo: demo=$demo")
if (demo != null) {
comboBox.selectedItem = demo
views.clearColor = DEFAULT_KORGE_BG_COLOR
container.changeTo {
containerFocus.focus()
demo.sceneBuilder().also { it.init(this) }
demo.sceneBuilder()
}
}
}
Expand All @@ -33,6 +37,7 @@ suspend fun Stage.demoSelector(default: Demo, all: List<Demo>) {
this.viewportHeight = 600
this.onSelectionUpdate.add {
//println(it)
//CoroutineScope([email protected]).launchImmediately { setDemo(it.selectedItem!!) }
launchImmediately { setDemo(it.selectedItem!!) }
}
}
Expand Down
Loading

0 comments on commit 4edeb8b

Please sign in to comment.