pragmagic / godot-nim

Nim bindings for Godot Engine
https://pragmagic.github.io/godot-nim/
Other
497 stars 27 forks source link

Accessors for properties, Object._set override not firing? #90

Closed geekrelief closed 3 years ago

geekrelief commented 3 years ago

I'm trying to modify a property in the inspector during runtime (or maybe for an EditorPlugin), and I want it to trigger a function. For example, I have a health property that should update the UI. So when health is modified I want it to emit a signal that the value of health has changed.

So I was wondering how could we implement accessors for properties? I see godotmacros.nim generates get and set functions for fields, so we could hook into that with a pragma. But an alternative should be to override Object._set. But the sample code below doesn't work. Method set isn't called when health is set.

  var health {.gdExport.}:int = 1

  method set(property:string, value:Variant):bool = 
    print &"{property = }"

  method ready() =
    self.setImpl("health", 5.toVariant)

Any clue what I'm doing wrong?

geekrelief commented 3 years ago

I tried modifying an existing godot property like Button's text, and my overriding set method is called. If I call getPropertyListImpl, the custom property is in there. If I try setImpl on the text property, my set is called too.

But if try setting a custom property's value (either via setImpl or inspector) even though it's in the property list, set is not called. I also tried overriding _get_property_list, but that didn't change anything.

geekrelief commented 3 years ago

I see that godot-nim defines a custom accessor function for converting data from godot to nim, and NativeScriptInstance::set in the engine see it and calls it. https://github.com/godotengine/godot/blob/db8c2410a4ee6213f5b78d3e8fb9783d9d4f0edf/modules/gdnative/nativescript/nativescript.cpp#L554 So we'd need to add a hook for accessors.