class Gamefic::Query::Base
A base class for entity-based queries that can be applied to responses. Each query matches a command token to an object that can be passed into a response callback.
Most queries return entities, but there are also queries for plain text and integers.
Attributes
@return [Array<Object>]
Public Class Methods
Source
# File lib/gamefic/query/base.rb, line 20 def initialize *arguments, name: self.class.to_s raise ArgumentError, "nil argument in query" if arguments.any?(&:nil?) @arguments = arguments @name = name end
@raise [ArgumentError] if any of the arguments are nil
@param arguments [Array<Object>] @param name [String]
Source
# File lib/gamefic/query/base.rb, line 105 def self.span(subject) plain.span(subject) end
Public Instance Methods
Source
# File lib/gamefic/query/base.rb, line 65 def accept?(subject, object) select(subject).include?(object) end
True if the object is selectable by the subject.
@param subject [Entity] @param object [Entity] @return [Boolean]
Source
# File lib/gamefic/query/base.rb, line 93 def bind(narrative) clone.tap do |query| query.instance_exec do @arguments = narrative.unproxy(@arguments) end end end
Source
# File lib/gamefic/query/base.rb, line 32 def filter(subject, token) scan = Scanner.scan(select(subject), token) return Result.new(nil, scan.token) unless scan.matched.one? Result.new(scan.matched.first, scan.remainder, scan.strictness) end
Get a query result for a given subject and token.
@param subject [Gamefic::Entity] @param token [String] @return [Result]
Source
# File lib/gamefic/query/base.rb, line 89 def inspect "#{name}(#{arguments.map(&:inspect).join(', ')})" end
Source
# File lib/gamefic/query/base.rb, line 81 def precision @precision ||= calculate_precision end
The query’s precision. The higher the number, the more specific the query is.
In general terms, a query’s precision is highest if its arguments select for a specific instance of an entity instead of a class of entity.
When a command gets parsed, the resulting list of available actions gets sorted in descending order of their responses’ overall precision, so the action with the highest precision gets attempted first.
@return [::Integer]
Source
# File lib/gamefic/query/base.rb, line 44 def select(subject) span(subject).that_are(*arguments) end
Get an array of entities that match the arguments from the context of the subject.
@param subject [Entity] @return [Array<Entity>]
Source
# File lib/gamefic/query/base.rb, line 56 def span(_subject) [] end
Get an array of entities that are candidates for selection from the context of the subject. These are the entities that select
will filter through query’s arguments.
Subclasses should override this method.
@param subject [Entity] @return [Array<Entity>]
Private Instance Methods
Source
# File lib/gamefic/query/base.rb, line 111 def calculate_precision arguments.sum(0) do |arg| case arg when Entity, Proxy::Base 1000 when Class, Module class_depth(arg) * 100 else 1 end end end
Source
# File lib/gamefic/query/base.rb, line 124 def class_depth(klass) return 1 unless klass.is_a?(Class) depth = 1 sup = klass depth += 1 while (sup = sup.superclass) depth end