Skip to content

Commit

Permalink
Rework noInitZone (#234)
Browse files Browse the repository at this point in the history
  • Loading branch information
raniejade committed Aug 12, 2020
1 parent 2b3c365 commit 805cfa7
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 16 deletions.
Expand Up @@ -17,9 +17,7 @@ internal class ClassHandle<T : Object>(
private val disposables = mutableListOf<COpaquePointer>()

fun wrap(instance: COpaquePointer): T {
return Godot.noInitZone {
factory().also { it.ptr = instance }
}
return Godot.instantiateWith(instance, factory)
}

fun init() {
Expand Down
@@ -1,5 +1,6 @@
package godot.core

import godot.Object
import godot.gdnative.*
import godot.internal.type.nullSafe
import godot.registerEngineTypes
Expand Down Expand Up @@ -33,7 +34,7 @@ object Godot {

private val languageIndexRef = AtomicInt(-1)

private val initHandle = AtomicInt(0)
private var shouldInit = AtomicInt(1)

fun init(options: godot_gdnative_init_options) {
val gdnative = nullSafe(options.api_struct)
Expand Down Expand Up @@ -80,13 +81,22 @@ object Godot {
nativescriptWrapper.compareAndSwap(nativescriptWrapper.value, null)
}

fun shouldInitPtr(): Boolean = initHandle.value == 0
/**
* Check if the we should initialized the ptr to an object. It also reverts the value of shouldInit
* to true. This method is used in conjunction with [instantiateWith] to provide us a mechanism to provide
* our own ptr when instantiating an object.
*/
fun shouldInitPtr(): Boolean {
val current = shouldInit.value
shouldInit.compareAndSet(current, 0)
return current == 0
}

fun <T> noInitZone(cb: () -> T): T {
initHandle.compareAndSet(initHandle.value, 1)
val ret = cb()
initHandle.compareAndSet(initHandle.value, 0)
return ret
fun <T: Object> instantiateWith(ptr: COpaquePointer, constructor: () -> T): T {
shouldInit.compareAndSet(shouldInit.value, 1)
val instance = constructor()
instance.ptr = ptr
return instance
}

internal fun print(message: String) {
Expand Down
Expand Up @@ -53,10 +53,8 @@ internal object TypeManager {
*/
fun wrap(ptr: COpaquePointer): Object {
val tag = getTagFromInstancePtr(ptr)
val factory = tag ?: { Godot.noInitZone { Object(null) } }
val instance = factory()
instance.ptr = ptr
return instance
val factory = tag ?: ::Object
return Godot.instantiateWith(ptr, factory)
}

private fun createAndRegisterTag(factory: () -> Object): COpaquePointer {
Expand All @@ -70,8 +68,7 @@ internal object TypeManager {

private fun getTagFromInstancePtr(ptr: COpaquePointer): (() -> Object)? {
return memScoped {
val obj = Godot.noInitZone { Object() }
obj.ptr = ptr
val obj = Godot.instantiateWith(ptr, ::Object)
val className = obj.getClass()
// user defined type
// this should be first otherwise casting to a user defined type won't work!
Expand Down

0 comments on commit 805cfa7

Please sign in to comment.