|
31 | 31 | ## The base type all Godot types inherit from. |
32 | 32 | ## Manages lifecycle of the wrapped ``GodotObject``. |
33 | 33 | godotObject: ptr GodotObject |
34 | | - linkedObject: NimGodotObject |
| 34 | + linkedObjectPtr: pointer |
35 | 35 | ## Wrapper around native object that is the container of the Nim "script" |
36 | 36 | ## This is needed for `of` checks and `as` conversions to work as |
37 | 37 | ## expected. For example, Nim type may inherit from ``Spatial``, but the |
38 | 38 | ## script is attached to ``Particles``. In this case conversion to |
39 | 39 | ## ``Particles`` is valid, but Nim type system is not aware of that. |
40 | 40 | ## This works in both directions - for linked native object this |
41 | 41 | ## reference points to Nim object. |
| 42 | + ## This is stored as a raw pointer to avoid reference cycles and therefore |
| 43 | + ## improve GC performance. |
42 | 44 | isRef*: bool |
43 | 45 | isFinalized: bool |
44 | 46 | isNative: bool |
@@ -185,6 +187,9 @@ proc deinit*(obj: NimGodotObject) = |
185 | 187 | obj.godotObject.deinit() |
186 | 188 | obj.godotObject = nil |
187 | 189 |
|
| 190 | +proc linkedObject(obj: NimGodotObject): NimGodotObject {.inline.} = |
| 191 | + cast[NimGodotObject](obj.linkedObjectPtr) |
| 192 | + |
188 | 193 | proc nimGodotObjectFinalizer*[T: NimGodotObject](obj: T) = |
189 | 194 | if obj.godotObject.isNil or obj.isNative: return |
190 | 195 | # important to set it before so that ``unreference`` is aware |
@@ -465,14 +470,17 @@ proc setGodotObject*(nimObj: NimGodotObject, obj: ptr GodotObject) {.inline.} = |
465 | 470 | proc setNativeObject*(nimObj: NimGodotObject, |
466 | 471 | nativeObj: NimGodotObject) {.inline.} = |
467 | 472 | ## Used from Godot constructor produced by ``gdobj`` macro. Do not call. |
468 | | - nimObj.linkedObject = nativeObj |
469 | | - nativeObj.linkedObject = nimObj |
| 473 | + GC_ref(nativeObj) |
| 474 | + nimObj.linkedObjectPtr = cast[pointer](nativeObj) |
| 475 | + nativeObj.linkedObjectPtr = cast[pointer](nimObj) |
470 | 476 | nativeObj.isNative = true |
471 | 477 |
|
472 | 478 | proc removeGodotObject*(nimObj: NimGodotObject) {.inline.} = |
473 | 479 | ## Used from Godot destructor produced by ``gdobj`` macro. Do not call. |
| 480 | + GC_unref(nimObj.linkedObject) |
474 | 481 | nimObj.godotObject = nil |
475 | 482 | nimObj.linkedObject.godotObject = nil |
| 483 | + nimObj.linkedObjectPtr = nil |
476 | 484 |
|
477 | 485 | proc `==`*(self, other: NimGodotObject): bool {.inline.} = |
478 | 486 | ## Compares objects by referential equality. |
|
0 commit comments