-
-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Setter not called in self #5
Comments
Hi there! self:set_some_property(value)
-- or
self:set('property', value) By the way, in GDScript, to call a setter method of a property defined in the script itself, you also have to explicitly call the method. This avoids recursion when the setter method sets the property itself and gives fine control over when calling the setter method is really needed. var some_property setget set_some_property
func set_some_property(value):
# this does not call set_property again recursively
some_property = value
func some_unrelated_method():
# in fact, anywhere in this script that sets this
# property like this will not call the setter method
some_property = 42
func _ready():
# ok, now calling setter method
set_some_property(42) Now that I'm thinking of it, though, setting properties on -- this will set the position in the script instance table, not the Node2D object
some_node2d.position = Vector2(1)
-- calling `set_position` or `set` is still the way, right now
some_node2d.set_position(Vector2(1)) A -- Version 1
-- Problem with this is that calling `set` would convert
-- `value` to a Variant, so big tables would be converted to
-- Dictionaries just to potentially be thrown away.
-- Also, right now functions and coroutines cannot be
-- transformed into Variants, although they could be, by
-- incapsulating them as Objects
function ScriptInstance:__newindex(key, value)
if not self:set(key, value) then
rawset(self, key, value)
end
end
-- Version 2
function ScriptInstance:__newindex(key, value)
-- `has_property` doesn't exist, but would potentially
-- search results from `Object.get_property_list` or
-- `ClassDB.class_get_property_list`.
-- Generating an Array and making a linear search every
-- time __newindex is called doesn't seem too good, but we
-- could cache the property names in the Script, which
-- `self` always maintains a reference to
if self:has_property(key) then
self:set(key, value)
else
rawset(self, key, value)
end
end I like version 2 better, with some caching of the property names either eagerly when loading the script or lazily when the first |
Actually you can just use "As said, local access will not trigger the setter and getter. Here is an illustration of this:" func _init():
# Does not trigger setter/getter.
my_integer = 5
print(my_integer)
# Does trigger setter/getter.
self.my_integer = 5
print(self.my_integer)
I'd actually noticed that recently as well, just thought maybe I was doing something wrong and didn't want to spam you with issues. :P I think your fix for it sounds like a good idea. I'd likely lean toward lazy caching to avoid a huge expense for deeply nested hierarchies, but that's just my initial thought. |
Oooh, now I got it, thanks!
Don't worry, that's what issues are for. This is the kind of thing that easily gets unnoticed, since for the time being I haven't done any real projects with Lua PluginScript. |
As for I think for The annoying thing is that |
Honestly I'm now wondering if perhaps it'd be best to encourage usage of |
Maybe, yes, I don't know for sure.
If we were creating our own class model in pure Lua, I would agree. |
I think I'm going to trust your expertise on this one :) In my code base I've started opting to use |
Oh btw, one other thing I noticed with setters that I'm not sure if its intended or not: When defining a setter, I actually have to define it as Ex: local Object = {
extends = "Node",
prop = property({
default = 0,
set = function (self, key, value)
-- Here "key" is just "prop" (the name of the property)
self.prop = value
end,
}),
} |
No, that's totally a bug 😅 Only |
I finally got back to messing with Lua PluginScript again. I've discovered that aside from native Godot classes, we can only inherit PluginScripts, as far as 3.4 is concerned. Thus I'm thinking that we can track available properties for native classes in |
Sounds promising, thanks for circling back around to this. |
There it is, calling |
Legendary my man. If you want I can download the latest branch and try it out in my project. Unless you think you'll be pushing a new release soon. |
I'll probably create a new release today, there are enough changes already and I usually only work on this on the weekends. |
@bojjenclon I was able to make a GitHub Action that not only builds all variations of the library, but creates the full distribution zip on push events. Here is a successful run of it, you should be able to download the |
Sick, having CI on this will make testing updates even faster. I'm currently using set/get throughout most my code, so I'll need to make a few changes to test your work, but I'll give it a try so we can root out any potential issues. |
That's the idea ;)
If it's too much trouble, don't worry. But if you do try, please tell if you find anything, whether it works or not. |
I can try to dig in a bit more later, but I did a really simple test where I simply took a property with a defined setter and changed the line from:
to
Unfortunately it doesn't seem to have worked though. :/ I don't see the value being changed properly in my GUI, whereas with |
Is |
Nope its a custom property: energy = property({
type = int,
get = function (self) return self._energy end,
set = function (self, value)
self._energy = value
if value <= 0 then
self._energy = 0
Coordinator:emit_signal("actor:energy_depleted", self)
end
if value > 100 then
self._energy = 100
end
Coordinator:emit_signal("actor:energy_changed", self)
end,
}), |
Hmm, ok. Right now The reasoning for that is mostly because of how Now that I'm thinking of it, I guess getters have the same problem of not being called when the key exists in the table. Ok, so while writing this, I was rethinking about script instances' design in Lua. Maybe they shouldn't be tables, but rather a struct which would have a consistent usage of Lots of possibilities, but yeah, that having more consistent behavior regarding getters/setters would be better than how it is today. |
Ah I see, that was a misunderstanding on my part then. I'd definitely say it could be a nice enhancement to improve that workflow, if for nothing else than to ease transition between gdscript and lua. I'd personally say its not the highest of priorities though - if you have other areas to improve first - since |
I agree, I really want Lua PluginScript to be easy to use and transition from GDScript.
Yes, this kind of documentation is a must, even though it isn't in place yet (hehe, my fault there). I'll keep you posted. |
Now script instances are a struct with a table for storing data. This makes it possible to always call setter functions on __newindex, regardless of if there already was a value in the table. The methods `rawget` and `rawset` were added to index the table directly, without calling getters/setters or indexing the owner Object.
Ok, I've created a new branch to test this idea of having Script Instances be structs with a backing table for data. But the overall functionality needs better testing, to see if nothing broke and that indexing properties make sense in that they call the right getters/setters and that they index the owner Object. |
Work has kept me insanely busy lately so I haven't had time to even crack open Godot in a while. :/ If I get a chance to test it at some point I definitely will, but your test suite may end up having to do for a while. Awesome that you're making progress on it though. |
I totally get it, don't worry.
It needs way more testing, but I'm sure we'll get to that at some point =] I still haven't taken the time to make a game/app project with Lua to test the whole plugin experience better. I'm sure I'll get to that at some point as well =P |
I've tested the solution some more and finally merged the PR. |
Me again! In GDScript if you have a setter on a property and change it via
self.property
the setter will be used. This doesn't apply to Lua, so I'm wondering how to trigger the setter from within a class method?The text was updated successfully, but these errors were encountered: