[solved] wml.get_child for unit
Moderator: Forum Moderators
- Celtic_Minstrel
- Developer
- Posts: 2371
- Joined: August 3rd, 2012, 11:26 pm
- Location: Canada
- Contact:
Re: wml.get_child for unit
Nope, __cfg can be thought of as a WML copy of the unit.white_haired_uncle wrote: ↑August 22nd, 2024, 3:58 pm So does that mean any changes I make are "stored" immediately? I thought I had to "unstore" the unit (e.g to_map).
It is exactly the same apart from not going into a WML variable.white_haired_uncle wrote: ↑August 22nd, 2024, 3:58 pm I've always thought of .__cfg as being akin to storing the unit.
Sure you can. Accesswhite_haired_uncle wrote: ↑August 22nd, 2024, 3:58 pm But in WML, I store a unit to a variable, which is then just a WML variable and I can do whatever I want with it (or not). And I suppose I could store it to multiple variables, each independent of the others. Short of doing a by-value copy, I don't think I can do this in lua (this is a rather silly example that can help me understand, not something I can see myself doing).
__cfg
twice and now you have two independent WML copies of the unit.I don't really get your confusion or how you drew any of these conclusions. Every time you accesswhite_haired_uncle wrote: ↑August 22nd, 2024, 3:58 pm My immediate confusion likes with "It'll serialize every time you access it". Seems like that would mean if I made a change the next time I accessed .__cfg my change would be overwritten by the serialized data from the unit. Unless behind the scenes there are actually two copies of the unit, the "real" one and the ".__cfg" one and I'm getting a serialized version of the latter. Then "unstoring" would be syncing the real one from the "working copy".
unit.__cfg
, the game serializes that unit to WML and returns the result. If you access __cfg
twice in a row, you'll end up with two identical but independent WML tables. If you access __cfg
, make some change to the unit directly, and access __cfg
again, the first WML table reflects the state of the unit before the change and the second WML table reflects the state of the unit after the change.There is, and also the first version results in no change to the unit, since you're only modifying the temporary WML table that was created when you accessedwhite_haired_uncle wrote: ↑August 22nd, 2024, 4:28 pm Are you saying there is a difference in serialization cost between:andCode: Select all
local unit = wesnoth.units.find_on_map(cfg)[1] unit.__cfg.hitpoints=23 unit.__cfg.language_name=_"Uncle Bob" unit.__cfg.experience=100
Code: Select all
local unit = wesnoth.units.find_on_map(cfg)[1].__cfg unit.hitpoints=23 unit.language_name=_"Uncle Bob" unit.experience=100
__cfg
. The second version doesn't serialize anything. It directly modifies the unit.Re: wml.get_child for unit
Ravana wrote: ↑August 22nd, 2024, 4:44 pm Yes. Different behaviour too if you wanted to do anything with the wml table.
Code: Select all
$ unit.__cfg == unit.__cfg false
Personally I think it would be better if it were something likeCeltic_Minstrel wrote: ↑August 22nd, 2024, 5:38 pm I don't really get your confusion or how you drew any of these conclusions. Every time you accessunit.__cfg
, the game serializes that unit to WML and returns the result. If you access__cfg
twice in a row, you'll end up with two identical but independent WML tables. If you access__cfg
, make some change to the unit directly, and access__cfg
again, the first WML table reflects the state of the unit before the change and the second WML table reflects the state of the unit after the change.
.cfg()
instead of .__cfg
. Magical properties are always confusing.It doesn't? (Did you see the
.__cfg
at the end of the first line?)-
- Posts: 1456
- Joined: August 26th, 2018, 11:46 pm
- Location: A country place, far outside the Wire
Re: wml.get_child for unit
Celtic_Minstrel wrote: ↑August 22nd, 2024, 5:38 pm
I don't really get your confusion or how you drew any of these conclusions. Every time you accessunit.__cfg
, the game serializes that unit to WML and returns the result. If you access__cfg
twice in a row, you'll end up with two identical but independent WML tables. If you access__cfg
, make some change to the unit directly, and access__cfg
again, the first WML table reflects the state of the unit before the change and the second WML table reflects the state of the unit after the change.
Code: Select all
local a = wesnoth.units.find_on_map({id = Bob})[1].__cfg
local b = wesnoth.units.find_on_map({id = Bob})[1].__cfg
Here's where it gets interesting:
Code: Select all
u = wesnoth.units.find_on_map({id = Bob})[1]
print(u.__cfg.hitpoints) ==> 24
u.__cfg.hitpoints=12
print(u.__cfg.hitpoints) ==> ???
I probably just need to play with it a bit. My gut is telling me the second code block is either just stupid, or making a change this way will only work if you "unstore" immediately after the change.
Speak softly, and carry Doombringer.
- Celtic_Minstrel
- Developer
- Posts: 2371
- Joined: August 3rd, 2012, 11:26 pm
- Location: Canada
- Contact:
Re: wml.get_child for unit
Ah, you're right, I did indeed miss that… which means both versions result in no actual change to the unit.
Correct.white_haired_uncle wrote: ↑August 22nd, 2024, 7:44 pm Now, as I understand it, that's two copies of Bob serialized and stored in completely separate tables (and if this is true, I believe it confirms my suspicion that .__cfg is not a table, it RETURNS a table). No changes to a will affect b, and nothing I do to a or b will affect Bob until I "unstore" a or b.
white_haired_uncle wrote: ↑August 22nd, 2024, 7:44 pm Here's where it gets interesting:
I would have thought the second print would print 12. But if every access to .__cfg serializes from the unit (Bob), and I've done nothing here to change Bob, then I guess it would print 24.Code: Select all
u = wesnoth.units.find_on_map({id = Bob})[1] print(u.__cfg.hitpoints) ==> 24 u.__cfg.hitpoints=12 print(u.__cfg.hitpoints) ==> ???
__cfg
is read-only. It's a little unfortunate that Lua allows you to modify its members anyway, but that won't do anything, as what you're modifying is just a temporary copy of the table.Making a change this way will never work. You need to storewhite_haired_uncle wrote: ↑August 22nd, 2024, 7:44 pm My gut is telling me the second code block is either just stupid, or making a change this way will only work if you "unstore" immediately after the change.
__cfg
in a variable (which includes passing it to a function), otherwise any changes to it will be immediately lost.- hermestrismi
- Posts: 730
- Joined: February 6th, 2016, 11:28 pm
- Location: Tunisia
- Contact:
Re: wml.get_child for unit
hi,
a quick stupid question. I want to build a wml array (like append variables) like that:
what's the best way to do that? the ways I tried (
and
didn't build an append array
a quick stupid question. I want to build a wml array (like append variables) like that:
Code: Select all
[set_variables]
mode=append
name=unit_items_pair
[literal]
id=Blood Bat-20
item=sword2
[/literal]
...
[/variables]
Code: Select all
wml.array_access_set
and
Code: Select all
wml.variables
The Dark Master, The Dark Hordes (Unofficial version), Return of the Legion , Eternal Kingdom, An Elvish Scout,Unrest in Elfland , Hidden War ...
The Dark Master Project, Arabic tra. maintainer
"But he loves you" G. Carlin
The Dark Master Project, Arabic tra. maintainer
"But he loves you" G. Carlin
-
- Posts: 1456
- Joined: August 26th, 2018, 11:46 pm
- Location: A country place, far outside the Wire
Re: wml.get_child for unit
wml.array_access.get and wml.array_access.set are used to convert WML arrays to/from lua tables.
Generally, you'll use table.insert to append to a lua table. https://www.lua.org/pil/19.2.html
WML and I don't get along well, but I think this is close to what you want:
Generally, you'll use table.insert to append to a lua table. https://www.lua.org/pil/19.2.html
WML and I don't get along well, but I think this is close to what you want:
Code: Select all
local a=wml.array_access.get("unit_items_pair")
b["id]="Blood Bat-20"
b["item"]="sword"
table.insert(a,b)
print(a[#a].item) ==> "Blood Bat-20"
wml.array_access.set("unit_items_pair",a)
Speak softly, and carry Doombringer.
- hermestrismi
- Posts: 730
- Joined: February 6th, 2016, 11:28 pm
- Location: Tunisia
- Contact:
Re: wml.get_child for unit
thanks. I'll try it. may I ask if this is the best way to serialize a table (so that it became surely persistent upon reload)?white_haired_uncle wrote: ↑August 23rd, 2024, 9:52 am wml.array_access.get and wml.array_access.set are used to convert WML arrays to/from lua tables.
Generally, you'll use table.insert to append to a lua table. https://www.lua.org/pil/19.2.html
WML and I don't get along well, but I think this is close to what you want:
Code: Select all
local a=wml.array_access.get("unit_items_pair") b["id]="Blood Bat-20" b["item"]="sword" table.insert(a,b) print(a[#a].item) ==> "Blood Bat-20" wml.array_access.set("unit_items_pair",a)
The Dark Master, The Dark Hordes (Unofficial version), Return of the Legion , Eternal Kingdom, An Elvish Scout,Unrest in Elfland , Hidden War ...
The Dark Master Project, Arabic tra. maintainer
"But he loves you" G. Carlin
The Dark Master Project, Arabic tra. maintainer
"But he loves you" G. Carlin
-
- Posts: 1456
- Joined: August 26th, 2018, 11:46 pm
- Location: A country place, far outside the Wire
Re: wml.get_child for unit
Best? I don't know. It's how I do it.hermestrismi wrote: ↑August 23rd, 2024, 9:56 am
thanks. I'll try it. may I ask if this is the best way to serialize a table (so that it became surely persistent upon reload)?
There's also
https://wiki.wesnoth.org/LuaAPI/wesnoth ... stent_tags
but I've never used it.
Speak softly, and carry Doombringer.