1#!/usr/bin/env ruby
2#
3# Copyright (C) 2017 Stephen Paul Weber <singpolyma@singpolyma.net>
4#
5# This file is part of sgx-bwmsgsv2.
6#
7# sgx-bwmsgsv2 is free software: you can redistribute it and/or modify it under
8# the terms of the GNU Affero General Public License as published by the Free
9# Software Foundation, either version 3 of the License, or (at your option) any
10# later version.
11#
12# sgx-bwmsgsv2 is distributed in the hope that it will be useful, but WITHOUT
13# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
15# details.
16#
17# You should have received a copy of the GNU Affero General Public License along
18# with sgx-bwmsgsv2. If not, see <http://www.gnu.org/licenses/>.
19
20require "eventmachine"
21require "promise"
22
23class EMPromise < Promise
24 def initialize(deferrable=nil)
25 super()
26 fulfill(deferrable) if deferrable
27 end
28
29 def fulfill(value, bind_defer=true)
30 if bind_defer && value.is_a?(EM::Deferrable)
31 value.callback { |x| fulfill(x, false) }
32 value.errback(&method(:reject))
33 else
34 super(value)
35 end
36 end
37
38 def defer
39 EM.next_tick { yield }
40 end
41
42 def wait
43 fiber = Fiber.current
44 resume = proc do |arg|
45 defer { fiber.resume(arg) }
46 end
47
48 self.then(resume, resume)
49 Fiber.yield
50 end
51
52 def self.reject(e)
53 new.tap { |promise| promise.reject(e) }
54 end
55end
56
57module EventMachine
58 module Deferrable
59 def promise
60 EMPromise.new(self)
61 end
62
63 [:then, :rescue, :catch].each do |method|
64 define_method(method) do |*args, &block|
65 promise.public_send(method, *args, &block)
66 end
67 end
68 end
69end