diff --git a/korgw/src/macosMain/kotlin/com/soywiz/korgw/DefaultGameWindowMacos.kt b/korgw/src/macosMain/kotlin/com/soywiz/korgw/DefaultGameWindowMacos.kt index 960b06f654..9041e5010c 100644 --- a/korgw/src/macosMain/kotlin/com/soywiz/korgw/DefaultGameWindowMacos.kt +++ b/korgw/src/macosMain/kotlin/com/soywiz/korgw/DefaultGameWindowMacos.kt @@ -600,22 +600,24 @@ class MyDefaultGameWindow : GameWindow() { val arena = Arena() val displayLink = arena.alloc() + private fun checkDisplayLink(code: Int) { + if (code != kCVReturnSuccess) internalException(code) + } + fun createDisplayLink(): Boolean { //println("createDisplayLink[1]") - val displayID = CGMainDisplayID() - val error = CVDisplayLinkCreateWithCGDisplay(displayID, displayLink.ptr) - //println("createDisplayLink[2]") - if (error == kCVReturnSuccess) { - //println("createDisplayLink[3]") - - CVDisplayLinkSetOutputCallback(displayLink.value, staticCFunction(::displayCallback), gameWindowStableRef.asCPointer()) - CVDisplayLinkStart(displayLink.value) - //println("createDisplayLink[4]") - return true - } else { - return false + return try { + checkDisplayLink(CVDisplayLinkCreateWithCGDisplay(CGMainDisplayID(), displayLink.ptr)) + checkDisplayLink(CVDisplayLinkSetOutputCallback(displayLink.value, staticCFunction(::displayCallback), gameWindowStableRef.asCPointer())) + checkDisplayLink(CVDisplayLinkStart(displayLink.value)) + true + } catch (e: InternalException) { + if (displayLink.value != null) { + CVDisplayLinkRelease(displayLink.value) + } + e.printStackTrace() + false } - //println("createDisplayLink[5]") } private fun timer(timer: NSTimer?) { @@ -645,7 +647,7 @@ class MyDefaultGameWindow : GameWindow() { override suspend fun clipboardRead(): ClipboardData? { val pasteboard = NSPasteboard.generalPasteboard val items = pasteboard.pasteboardItems as? List? - if (items == null || items.isEmpty()) return null + if (items.isNullOrEmpty()) return null return items.last().stringForType(NSPasteboardTypeString)?.let { TextClipboardData(it) } } } @@ -656,8 +658,13 @@ private val atomicDisplayLinkContext = AtomicReference(null) @SharedImmutable val doDisplayCallbackRender: () -> Unit = { - val gameWindow = atomicDisplayLinkContext.value?.asStableRef() - gameWindow?.get()?.doRender(update = true) + try { + initRuntimeIfNeeded() + val gameWindow = atomicDisplayLinkContext.value?.asStableRef() + gameWindow?.get()?.doRender(update = true) + } catch (e: Throwable) { + e.printStackTrace() + } } @Suppress("UNUSED_PARAMETER") diff --git a/korio/src/commonMain/kotlin/com/soywiz/korio/lang/Exceptions.kt b/korio/src/commonMain/kotlin/com/soywiz/korio/lang/Exceptions.kt index 08d929038a..82ed10d7b4 100644 --- a/korio/src/commonMain/kotlin/com/soywiz/korio/lang/Exceptions.kt +++ b/korio/src/commonMain/kotlin/com/soywiz/korio/lang/Exceptions.kt @@ -1,6 +1,7 @@ package com.soywiz.korio.lang import com.soywiz.klogger.Console +import com.soywiz.krypto.encoding.* expect open class IOException(msg: String) : Exception expect open class EOFException(msg: String) : IOException @@ -11,6 +12,7 @@ open class MalformedInputException(msg: String) : Exception(msg) { class FileAlreadyExistsException(msg: String) : IOException(msg) +class InternalException(val code: Int) : Exception("Internal Exception with code $code (0x${code.hex})") class InvalidOperationException(str: String = "Invalid Operation") : Exception(str) class OutOfBoundsException(index: Int = -1, str: String = "Out Of Bounds") : Exception(str) class KeyNotFoundException(str: String = "Key Not Found") : Exception(str) @@ -32,6 +34,7 @@ val invalidArg: Nothing get() = throw InvalidArgumentException() val unreachable: Nothing get() = throw UnreachableException() val reserved: Nothing get() = throw ReservedException() +fun internalException(code: Int): Nothing = throw InternalException(code) fun deprecated(msg: String): Nothing = throw DeprecatedException(msg) fun mustValidate(msg: String): Nothing = throw MustValidateCodeException(msg) fun noImpl(msg: String): Nothing = throw NotImplementedException(msg) @@ -39,8 +42,7 @@ fun invalidOp(msg: String): Nothing = throw InvalidOperationException(msg) fun invalidArg(msg: String): Nothing = throw InvalidArgumentException(msg) fun unreachable(msg: String): Nothing = throw UnreachableException(msg) fun reserved(msg: String): Nothing = throw ReservedException(msg) -fun unsupported(msg: String): Nothing = throw UnsupportedOperationException(msg) -fun unsupported(): Nothing = throw UnsupportedOperationException("unsupported") +fun unsupported(msg: String = "unsupported"): Nothing = throw UnsupportedOperationException(msg) fun invalidArgument(msg: String): Nothing = throw InvalidArgumentException(msg) fun unexpected(msg: String): Nothing = throw UnexpectedException(msg) fun malformedInput(msg: String): Nothing = throw MalformedInputException(msg) diff --git a/krypto/src/commonMain/kotlin/com/soywiz/krypto/encoding/Hex.kt b/krypto/src/commonMain/kotlin/com/soywiz/krypto/encoding/Hex.kt index c381cf0d4b..79499dd1a0 100644 --- a/krypto/src/commonMain/kotlin/com/soywiz/krypto/encoding/Hex.kt +++ b/krypto/src/commonMain/kotlin/com/soywiz/krypto/encoding/Hex.kt @@ -76,7 +76,15 @@ val String.unhexIgnoreSpaces: ByteArray get() = buildString { val String.unhex get() = Hex.decode(this) val ByteArray.hex get() = Hex.encodeLower(this) +/** + * Returns this number as a hexadecimal string in the format: + * 0xWWXXYYZZ + */ val Int.hex: String get() = "0x$shex" +/** + * Returns this number as a hexadecimal string in the format: + * WWXXYYZZ + */ val Int.shex: String get() = buildString(8) { for (n in 0 until 8) {