Better handle external References
This commit is contained in:
parent
b41a37681f
commit
e716926207
2 changed files with 47 additions and 6 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
version = "0.2.0"
|
version = "0.2.1"
|
||||||
author = "Xored Software, Inc."
|
author = "Xored Software, Inc."
|
||||||
description = "Godot Engine bindings"
|
description = "Godot Engine bindings"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import "../core/strings.nim", "../core/vector2.nim", "../core/rect2.nim",
|
||||||
type
|
type
|
||||||
NimGodotObject* = ref object of RootObj
|
NimGodotObject* = ref object of RootObj
|
||||||
godotObject: ptr GodotObject
|
godotObject: ptr GodotObject
|
||||||
|
isRef: bool
|
||||||
|
|
||||||
ConversionResult* {.pure.} = enum
|
ConversionResult* {.pure.} = enum
|
||||||
OK,
|
OK,
|
||||||
|
|
@ -44,6 +45,7 @@ type
|
||||||
constructor: proc(): NimGodotObject {.gcsafe, nimcall.}
|
constructor: proc(): NimGodotObject {.gcsafe, nimcall.}
|
||||||
baseNativeClass: cstring
|
baseNativeClass: cstring
|
||||||
isNative: bool
|
isNative: bool
|
||||||
|
isRef: bool
|
||||||
|
|
||||||
var classRegistry {.threadvar.}: TableRef[cstring, ObjectInfo]
|
var classRegistry {.threadvar.}: TableRef[cstring, ObjectInfo]
|
||||||
|
|
||||||
|
|
@ -62,11 +64,31 @@ proc getClassName*(o: ptr GodotObject): string =
|
||||||
# There are physics type not known by ClassDB
|
# There are physics type not known by ClassDB
|
||||||
result = result[0..result.len-3]
|
result = result[0..result.len-3]
|
||||||
|
|
||||||
|
var unreferenceMethodBind {.threadvar.}: ptr GodotMethodBind
|
||||||
|
proc unreference(o: ptr GodotObject): bool =
|
||||||
|
if isNil(unreferenceMethodBind):
|
||||||
|
unreferenceMethodBind = getMethod(cstring"Reference",
|
||||||
|
cstring"unreference")
|
||||||
|
unreferenceMethodBind.ptrCall(o, nil, addr(result))
|
||||||
|
|
||||||
|
var referenceMethodBind {.threadvar.}: ptr GodotMethodBind
|
||||||
|
proc reference(o: ptr GodotObject) =
|
||||||
|
if isNil(referenceMethodBind):
|
||||||
|
referenceMethodBind = getMethod(cstring"Reference",
|
||||||
|
cstring"reference")
|
||||||
|
referenceMethodBind.ptrCall(o, nil, nil)
|
||||||
|
|
||||||
|
proc deinit*(obj: NimGodotObject) =
|
||||||
|
## Destroy the object. You only need to call this for objects not inherited
|
||||||
|
## from Reference, where manual lifecycle control is necessary.
|
||||||
|
assert(not obj.godotObject.isNil)
|
||||||
|
obj.godotObject.deinit()
|
||||||
|
obj.godotObject = nil
|
||||||
|
|
||||||
proc godotFinalizer[T: NimGodotObject](obj: T) =
|
proc godotFinalizer[T: NimGodotObject](obj: T) =
|
||||||
# hmm, not sure yet how to deal with references correctly
|
if obj.godotObject.isNil: return
|
||||||
# when T is Reference:
|
if obj.isRef and obj.godotObject.unreference():
|
||||||
# obj.godotObject.deinit()
|
obj.deinit()
|
||||||
discard
|
|
||||||
|
|
||||||
macro baseNativeType(T: typedesc): cstring =
|
macro baseNativeType(T: typedesc): cstring =
|
||||||
var t = getType(getType(T)[1][1])
|
var t = getType(getType(T)[1][1])
|
||||||
|
|
@ -86,6 +108,20 @@ macro baseNativeType(T: typedesc): cstring =
|
||||||
rStr.strVal = baseT
|
rStr.strVal = baseT
|
||||||
result = newNimNode(nnkCallStrLit).add(ident("cstring"), rStr)
|
result = newNimNode(nnkCallStrLit).add(ident("cstring"), rStr)
|
||||||
|
|
||||||
|
macro isReference(T: typedesc): bool =
|
||||||
|
var isRef = false
|
||||||
|
var t = getType(T)
|
||||||
|
while true:
|
||||||
|
let typeName = ($t[1][1]).split(':')[0]
|
||||||
|
if typeName == "Reference":
|
||||||
|
isRef = true
|
||||||
|
break
|
||||||
|
if typeName == "NimGodotObject":
|
||||||
|
break
|
||||||
|
t = getType(t[1][1])
|
||||||
|
result = if isRef: ident("true")
|
||||||
|
else: ident("false")
|
||||||
|
|
||||||
template registerClass*(T: typedesc; godotClassName: cstring,
|
template registerClass*(T: typedesc; godotClassName: cstring,
|
||||||
isNativeParam: bool) =
|
isNativeParam: bool) =
|
||||||
if classRegistry.isNil:
|
if classRegistry.isNil:
|
||||||
|
|
@ -96,10 +132,12 @@ template registerClass*(T: typedesc; godotClassName: cstring,
|
||||||
result = t
|
result = t
|
||||||
|
|
||||||
const base = baseNativeType(T)
|
const base = baseNativeType(T)
|
||||||
|
const isRef: bool = isReference(T)
|
||||||
classRegistry[godotClassName] = ObjectInfo(
|
classRegistry[godotClassName] = ObjectInfo(
|
||||||
constructor: constructor,
|
constructor: constructor,
|
||||||
baseNativeClass: base,
|
baseNativeClass: base,
|
||||||
isNative: isNativeParam
|
isNative: isNativeParam,
|
||||||
|
isRef: isRef
|
||||||
)
|
)
|
||||||
when isNativeParam:
|
when isNativeParam:
|
||||||
static:
|
static:
|
||||||
|
|
@ -115,6 +153,9 @@ proc newNimGodotObject[T: NimGodotObject](
|
||||||
else:
|
else:
|
||||||
result = T(objInfo.constructor())
|
result = T(objInfo.constructor())
|
||||||
result.godotObject = godotObject
|
result.godotObject = godotObject
|
||||||
|
if objInfo.isRef:
|
||||||
|
result.isRef = true
|
||||||
|
result.godotObject.reference()
|
||||||
|
|
||||||
proc asNimGodotObject*[T: NimGodotObject](godotObject: ptr GodotObject): T =
|
proc asNimGodotObject*[T: NimGodotObject](godotObject: ptr GodotObject): T =
|
||||||
if godotObject.isNil: return nil
|
if godotObject.isNil: return nil
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue