Class: Effects

Inherits:
Object
  • Object
show all
Defined in:
lib/effection/effects.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(initial_handlers = {}, parent = nil, &block) ⇒ Effects

Returns a new instance of Effects.



4
5
6
7
8
9
# File 'lib/effection/effects.rb', line 4

def initialize(initial_handlers = {}, parent = nil, &block)
  @handlers = initial_handlers
  @fib = Fiber.new(&block)
  @parent = parent
  __next()
end

Class Method Details

.effection(message, *args) ⇒ Object



29
30
31
32
33
# File 'lib/effection/effects.rb', line 29

def self.effection(message, *args)
  Fiber.yield -> effector {
    effector.__handle(message, *args)
  }
end

.listen(message, &handler) ⇒ Object



23
24
25
26
27
# File 'lib/effection/effects.rb', line 23

def self.listen(message, &handler)
  Fiber.yield -> effector {
    effector.__add_handler(message, &handler)
  }
end

.with(**initial_handlers, &block) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
# File 'lib/effection/effects.rb', line 11

def self.with(**initial_handlers, &block)
  parent = nil
  begin
    Fiber.yield -> effector {
      parent = effector
    }
  rescue FiberError
    # Ignore it if it's Can't yield from Root fiber, for now? I guess
  end
  Effects.new(initial_handlers, parent, &block)
end

Instance Method Details

#__add_handler(message, &handler) ⇒ Object



53
54
55
# File 'lib/effection/effects.rb', line 53

def __add_handler(message, &handler)
  @handlers[message] = handler
end

#__handle(message, *args) ⇒ Object



57
58
59
60
61
62
63
# File 'lib/effection/effects.rb', line 57

def __handle(message, *args)
  if @handlers[message]
    res_with = @handlers[message].(*args)
  elsif @parent != nil
    res_with = @parent.effection(message, *args)
  end
end

#__next(*newVal) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
# File 'lib/effection/effects.rb', line 41

def __next(*newVal)
  if @fib.alive?
    # This state is paused here and then will only be hit when the containing fiber calls Yield.
    cb = @fib.resume(*newVal)
    ret_val = cb
    if cb != nil and cb.respond_to? :call
      ret_val = cb.(self) 
    end
    __next(ret_val)
  end
end

#effection(message, *args) ⇒ Object



35
36
37
38
39
# File 'lib/effection/effects.rb', line 35

def effection(message, *args)
  Fiber.yield -> effector {
    effector.__handle(message, *args)
  }
end