A composable filter over a domain of things - the objects a level is built
from, or the items alive in it. trx.objects.query and trx.items.query are
each the identity query, matching everything; narrow one down, then read the
result.
A query is immutable. Every method returns a fresh query, so a base can be kept and branched from without one narrowing leaking into another.
Each domain adds narrowings of its own on top of the ones below - see
trx.items.ItemQuery and trx.objects.ObjectQuery - and chained methods read
left to right, combining with AND: q:spawnable():by_name("wolf").
A filter over a domain, read with one of the terminals below once it is narrow enough.
Operators:
query & query. Both queries match. Their domains must agree.~query. Everything the query does not match: ~q:animation().query | query. Either query matches, for what a chain cannot say: q:pickup() | q:inventory_item(). Their domains must agree.Methods:
query:count()
How many candidates match.
Returns: integer. The count, without building the list.
query:first()
The first matching handle.
Returns: any or nil. The handle, or nil.
query:ids()
The matching ids. For objects these are object ids; for items, their numbers.
Returns: a list of integer.
query:matches()
The matching handles.
Returns: a list of trx.objects.Object or trx.items.Item.
query:where(predicate)
Narrows by a test of the caller's own, for what the domain does not name.
Parameters:
predicate (function). The test each candidate is put through.
Called with:id (integer). The candidate's id.handle (any). The candidate itself, a trx.objects.Object or a trx.items.Item.Returns: trx.query.Query. The narrowed query.
Example:
local hurt = trx.items.query:where(function(id, item)
return item.hit_points < 10
end)
A query over a domain whose things answer to names, which adds the name layer to everything a trx.query.Query has. A domain without names offers none of it.
Methods:
namedquery:best()
The ids tied for the best by_name score: one for a
name only one thing answers to, the whole group for a group named in full. Without a
by_name, every matching id.
Returns: a list of integer.
namedquery:by_name(name)
Ranks rather than filters: matches the way a player types a name,
forgivingly, and orders what survives the rest of the query best first. Some of a domain's
narrowings are also searchable groups, so their own name matches every member. A group named
in full comes first, ahead of anything that answers to the same word.
Parameters:
Returns: trx.query.Query. The narrowed query.
Example:
trx.objects.query:spawnable():by_name("wolf"):ids()
namedquery:names()
Every name the matches answer to, for offering completions. The group names any match belongs to come first, because a completer offers the list in order and a group name that ties on score would otherwise sit behind a thing's own. Which groups answer follows from what the query kept, so one narrowed to what fights offers no trx.objects.ObjectQuery:pickup.
Returns: a list of string.
trx.query.narrowing(make)
Builds a narrowing method for a domain's query type out of a predicate factory. trx.items and trx.objects declare their own filters with it.
Parameters:
Returns: function. The method to declare as an impl.
trx.query.new(domain, class)
Builds the identity query over a domain, as an instance of that domain's query type. trx.objects and trx.items call this to make the query a script reaches through trx.objects.query and trx.items.query.
Parameters:
domain (table). What the query runs against.
Keys:
enumerate (function). Every id the domain holds.id_of (function). The id of a thing the domain hands out.searchable (function). Whether an id is one a name may reach.names_of (function, optional). The names an id answers to, for a domain that has them.default_names_of (function, optional). The same names before a language file is loaded.class (table). The query type the domain's narrowings were declared on.
Returns: trx.query.Query. The identity query, matching everything until narrowed.