Class: Gamefic::Query::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/gamefic/query/base.rb

Overview

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.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*arguments, name: self.class.to_s) ⇒ Base

Returns a new instance of Base.

Raises:

  • (ArgumentError)

    if any of the arguments are nil



20
21
22
23
24
25
# 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

Instance Attribute Details

#argumentsArray<Object> (readonly)



14
15
16
# File 'lib/gamefic/query/base.rb', line 14

def arguments
  @arguments
end

Class Method Details

.plainObject



101
102
103
# File 'lib/gamefic/query/base.rb', line 101

def self.plain
  @plain ||= new
end

.span(subject) ⇒ Object



105
106
107
# File 'lib/gamefic/query/base.rb', line 105

def self.span(subject)
  plain.span(subject)
end

Instance Method Details

#accept?(subject, object) ⇒ Boolean

True if the object is selectable by the subject.



65
66
67
# File 'lib/gamefic/query/base.rb', line 65

def accept?(subject, object)
  select(subject).include?(object)
end

#bind(narrative) ⇒ Object



93
94
95
96
97
98
99
# 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

#filter(subject, token) ⇒ Result

Get a query result for a given subject and token.



32
33
34
35
36
37
# 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

#inspectObject



89
90
91
# File 'lib/gamefic/query/base.rb', line 89

def inspect
  "#{name}(#{arguments.map(&:inspect).join(', ')})"
end

#nameObject



85
86
87
# File 'lib/gamefic/query/base.rb', line 85

def name
  @name || self.class.to_s
end

#precisionInteger

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.



81
82
83
# File 'lib/gamefic/query/base.rb', line 81

def precision
  @precision ||= calculate_precision
end

#select(subject) ⇒ Array<Entity>

Get an array of entities that match the arguments from the context of the subject.



44
45
46
# File 'lib/gamefic/query/base.rb', line 44

def select(subject)
  span(subject).that_are(*arguments)
end

#span(_subject) ⇒ Array<Entity>

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.



56
57
58
# File 'lib/gamefic/query/base.rb', line 56

def span(_subject)
  []
end