Class: Wongi::Engine::DataOverlay

Inherits:
Object
  • Object
show all
Defined in:
lib/wongi-engine/data_overlay.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(rete, parent = nil) ⇒ DataOverlay

Returns a new instance of DataOverlay.



7
8
9
10
11
12
13
# File 'lib/wongi-engine/data_overlay.rb', line 7

def initialize(rete, parent = nil)
  @rete = rete
  @parent = parent
  @raw_wmes = Hash.new { |h, k| h[k] = [] }
  @raw_tokens = Hash.new { |h, k| h[k] = [] }
  rete.add_overlay(self)
end

Instance Attribute Details

#parentObject (readonly)

Returns the value of attribute parent.



5
6
7
# File 'lib/wongi-engine/data_overlay.rb', line 5

def parent
  @parent
end

#reteObject (readonly)

Returns the value of attribute rete.



4
5
6
# File 'lib/wongi-engine/data_overlay.rb', line 4

def rete
  @rete
end

Instance Method Details

#<<(thing) ⇒ Object



46
47
48
49
50
51
52
53
54
55
# File 'lib/wongi-engine/data_overlay.rb', line 46

def <<(thing)
  case thing
  when Array
    assert WME.new(*thing).tap { |wme| wme.overlay = self }
  when WME
    assert(thing)
  else
    raise Error, "overlays can only accept data"
  end
end

#add_token(token, beta) ⇒ Object



127
128
129
130
# File 'lib/wongi-engine/data_overlay.rb', line 127

def add_token(token, beta)
  tokens = raw_tokens(beta)
  tokens << token unless tokens.include?(token)
end

#add_wme(wme, alpha) ⇒ Object



118
119
120
121
# File 'lib/wongi-engine/data_overlay.rb', line 118

def add_wme(wme, alpha)
  wmes = raw_wmes(alpha)
  wmes << wme unless wmes.include?(wme)
end

#ancestor?(other) ⇒ Boolean

Returns:

  • (Boolean)


31
32
33
34
35
# File 'lib/wongi-engine/data_overlay.rb', line 31

def ancestor?(other)
  return false if parent.nil?
  return true if parent == other
  parent.ancestor?(other)
end

#assert(wme) ⇒ Object



57
58
59
60
61
62
63
64
65
# File 'lib/wongi-engine/data_overlay.rb', line 57

def assert wme
  @next_cascade ||= []
  @next_cascade << [:assert, wme]
  if @current_cascade.nil?
    @current_cascade = @next_cascade
    @next_cascade = nil
    process_cascade
  end
end

#disposeObject



37
38
39
40
41
42
43
44
# File 'lib/wongi-engine/data_overlay.rb', line 37

def dispose
  return if self == rete.default_overlay
  rete.remove_overlay(self)
  @raw_tokens.values.each do |tokens|
    tokens.each(&:dispose!)
  end
  @raw_tokens.clear
end

#highest(other) ⇒ Object



97
98
99
100
101
102
103
# File 'lib/wongi-engine/data_overlay.rb', line 97

def highest(other)
  return self if self == other
  return self if other.nil?
  return self if ancestor?(other)
  return other if other.ancestor?(self)
  nil # unrelated lineages
end

#new_childObject



15
16
17
# File 'lib/wongi-engine/data_overlay.rb', line 15

def new_child
  DataOverlay.new(rete, self)
end

#process_cascadeObject



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/wongi-engine/data_overlay.rb', line 80

def process_cascade
  while @current_cascade
    @current_cascade.each do |(operation, wme, options)|
      case operation
      when :assert
        wme.overlay = self
        rete.real_assert(wme)
      when :retract
        rete.real_retract(wme, options)
        wme.overlay = nil
      end
    end
    @current_cascade = @next_cascade
    @next_cascade = nil
  end
end

#raw_tokens(beta) ⇒ Object



140
141
142
# File 'lib/wongi-engine/data_overlay.rb', line 140

def raw_tokens(beta)
  @raw_tokens[beta.object_id]
end

#raw_wmes(alpha) ⇒ Object



136
137
138
# File 'lib/wongi-engine/data_overlay.rb', line 136

def raw_wmes(alpha)
  @raw_wmes[alpha.object_id]
end

#remove_token(token, beta) ⇒ Object



132
133
134
# File 'lib/wongi-engine/data_overlay.rb', line 132

def remove_token(token, beta)
  raw_tokens(beta).delete(token)
end

#remove_wme(wme, alpha) ⇒ Object



123
124
125
# File 'lib/wongi-engine/data_overlay.rb', line 123

def remove_wme(wme, alpha)
  raw_wmes(alpha).delete(wme)
end

#retract(wme, options = { }) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/wongi-engine/data_overlay.rb', line 67

def retract wme, options = { }
  if wme.is_a? Array
    wme = WME.new(*wme)
  end
  @next_cascade ||= []
  @next_cascade << [:retract, wme, options]
  if @current_cascade.nil?
    @current_cascade = @next_cascade
    @next_cascade = nil
    process_cascade
  end
end

#tokens(beta) ⇒ Object



114
115
116
# File 'lib/wongi-engine/data_overlay.rb', line 114

def tokens(beta)
  DeleteSafeEnumerator.new(raw_tokens(beta))
end

#with_childObject



19
20
21
22
23
24
25
26
27
28
29
# File 'lib/wongi-engine/data_overlay.rb', line 19

def with_child
  return unless block_given?
  new_child.tap do |overlay|
    begin
      result = yield overlay
    ensure
      overlay.dispose
    end
    result
  end
end

#wmes(alpha) ⇒ Object

TODO: this is inconsistent. A WME retracted in-flight will be visible in active enumerators but a token will not. But this is how it works.



110
111
112
# File 'lib/wongi-engine/data_overlay.rb', line 110

def wmes(alpha)
  DuplicatingEnumerator.new(raw_wmes(alpha))
end