Resolvers, how do they work?

All development conversation and discussion takes place here

Moderator: Moderator

Post Reply
Message
Author
ibanix
Wyrmic
Posts: 244
Joined: Thu May 23, 2013 12:25 am

Resolvers, how do they work?

#1 Post by ibanix »

For wiki stuff I need to understand code, and at the moment I'm at the "how the hell do resolvers work" place.

For example:

Code: Select all

function resolvers.rngrange(x, y)
	return {__resolver="rngrange",  __resolve_instant=true, x, y}
end
function resolvers.calc.rngrange(t)
	return rng.range(t[1], t[2])
end
Questions:

1) What's with the ___resolver? Is this a magic word defined somewhere?
2) What glue causes __resolver to connect to resolvers.calc.nameoffunction?
3) Same question for __resolve_instant, and what's with 'true'?

Also, for types like this:

Code: Select all

function resolvers.attachtinker(t)
	return {__resolver="attachtinker", __resolve_last=true, t}
end

function resolvers.calc.attachtinker(t, e)
....
end
4) Where did 'e' come from?

Thanks in advance.
Please help with the ToME wiki!

HousePet
Perspiring Physicist
Posts: 6215
Joined: Sun Sep 09, 2012 7:43 am

Re: Resolvers, how do they work?

#2 Post by HousePet »

1) I think this is just a property that is looked for when the final thing is resolved.

2) I presume it looks for the __resolver field and then uses that to find a resolves.calc.X function.

3) That means it is done first when there are multiple.

4) Not sure, but I'm guessing it is the object the tinker is attached to? Or maybe the tinker itself.
My feedback meter decays into coding. Give me feedback and I make mods.

Zizzo
Sher'Tul Godslayer
Posts: 2521
Joined: Thu Jan 23, 2003 8:13 pm
Location: A shallow water area south of Bree
Contact:

Re: Resolvers, how do they work?

#3 Post by Zizzo »

[sound F/X: wiki diving] Hmm, the wiki's guide on resolvers is surprisingly sparse. Here's a rough overview:

newEntity{} defines basically a template of an entity. In Zone:makeEntity(), that template gets cloned and fleshed out into a full-fledged entity via Entity:resolve(). So say your entity definition has a field that you want to vary between entitles:

Code: Select all

newEntity {
  name = 'Silly example',
  silliness = rng.range(1, 10),
}
That won't work, because the field will be set in stone when the template is loaded and every copy will get the same value. Instead you use:

Code: Select all

newEntity {
  name = 'Silly example',
  silliness = resolvers.rngrange(1, 10),
}
which, as your code listing above shows, expands to:

Code: Select all

newEntity {
  name = 'Silly example',
  silliness = { __resolver="rngrange",  __resolve_instant=true, 1, 10 },
}
Then when an entity of this type is being created, Entity:resolve() walks the cloned template looking for anything shaped like a {__resolver} table and calls its associated resolvers.calc[__resolver]() method — in our case, resolvers.calc.rngrange(). The calc method gets called with two parameters: 't' is the {__resolver} table itself, which contains all the parameters passed to the original resolvers.whatever() call, and 'e' is the entity that's in the process of being resolved [in our example, resolvers.calc.rngrange() ignores its 'e' parameter because it doesn't need it]. The value returned from the calc method is assigned back to the field it comes from; if it's just a bare 'resolvers.something()' without a 'fieldname =' in front of it, you'll probably want to have the calc method return nil to delete the field.

Now the {__resolver} table returned by resolvers.whatever() can have a couple extra fields of interest:
  • __resolve_last: Entity:resolve() actually does two sweeps looking for {__resolver} tables, one at the very end. If your {__resolver} table includes __resolve_last=true, it will be processed in that second sweep; otherwise, it gets processed with everything else in the first sweep.
  • __resolve_instant: If your resolvers.calc.whatever() method returns something like another entity template that contains resolvers of its own, __resolve_instant=true tells Entity:resolve() to walk that return value immediately looking for more {__resolver} tables to resolve. I'm not sure why resolvers.rngrange() uses it, since it's just returning a number.
"Blessed are the yeeks, for they shall inherit Arda..."

ibanix
Wyrmic
Posts: 244
Joined: Thu May 23, 2013 12:25 am

Re: Resolvers, how do they work?

#4 Post by ibanix »

Zizzo, this is super helpful. Thank you.
Please help with the ToME wiki!

Post Reply