rx 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitattributes +22 -0
- data/.gitignore +173 -0
- data/.travis.yml +10 -0
- data/Gemfile +4 -0
- data/Rakefile +11 -0
- data/examples/aggregate.rb +39 -0
- data/examples/amb.rb +25 -0
- data/examples/ambproto.rb +24 -0
- data/examples/and.rb +26 -0
- data/examples/as_observable.rb +25 -0
- data/examples/average.rb +43 -0
- data/examples/buffer_with_count.rb +44 -0
- data/examples/buffer_with_time.rb +51 -0
- data/examples/case.rb +29 -0
- data/examples/catch.rb +20 -0
- data/examples/catchproto.rb +39 -0
- data/examples/combine_latest.rb +35 -0
- data/examples/combine_latestproto.rb +33 -0
- data/examples/concat.rb +22 -0
- data/examples/concat_all.rb +27 -0
- data/examples/concat_map.rb +61 -0
- data/examples/concat_map_observer.rb +29 -0
- data/examples/concatproto.rb +25 -0
- data/examples/connect.rb +41 -0
- data/examples/contains.rb +37 -0
- data/examples/count.rb +36 -0
- data/examples/create.rb +55 -0
- data/examples/debounce.rb +35 -0
- data/examples/default_if_empty.rb +35 -0
- data/examples/defer.rb +20 -0
- data/examples/delay.rb +49 -0
- data/examples/delay_with_selector.rb +63 -0
- data/examples/dematerialize.rb +22 -0
- data/examples/disposable.rb +12 -0
- data/examples/distinct.rb +43 -0
- data/examples/distinct_until_changed.rb +43 -0
- data/examples/do.rb +59 -0
- data/examples/empty.rb +16 -0
- data/examples/for.rb +26 -0
- data/examples/fork_join.rb +23 -0
- data/examples/from.rb +106 -0
- data/examples/from_array.rb +21 -0
- data/examples/from_callback.rb +21 -0
- data/examples/generate.rb +24 -0
- data/examples/group_join.rb +39 -0
- data/examples/if.rb +46 -0
- data/examples/intervals.rb +26 -0
- data/examples/merge.rb +36 -0
- data/examples/merge_all.rb +27 -0
- data/examples/multicast.rb +32 -0
- data/examples/never.rb +15 -0
- data/examples/of.rb +19 -0
- data/examples/on_error_resume_next.rb +21 -0
- data/examples/pairs.rb +26 -0
- data/examples/publish.rb +79 -0
- data/examples/range.rb +19 -0
- data/examples/reduce.rb +18 -0
- data/examples/repeat.rb +19 -0
- data/examples/return.rb +17 -0
- data/examples/scan.rb +41 -0
- data/examples/start.rb +29 -0
- data/examples/throw.rb +17 -0
- data/examples/time_intervals.rb +28 -0
- data/examples/timer.rb +26 -0
- data/examples/timestamp.rb +28 -0
- data/examples/to_a.rb +23 -0
- data/examples/to_async.rb +26 -0
- data/examples/using.rb +52 -0
- data/examples/when.rb +26 -0
- data/examples/while.rb +25 -0
- data/examples/window_with_time.rb +78 -0
- data/examples/zip.rb +27 -0
- data/examples/zip_array.rb +25 -0
- data/lib/core_ext/enumerable.rb +22 -0
- data/lib/rx_ruby.rb +27 -0
- data/lib/rx_ruby/concurrency/async_lock.rb +57 -0
- data/lib/rx_ruby/concurrency/current_thread_scheduler.rb +75 -0
- data/lib/rx_ruby/concurrency/default_scheduler.rb +51 -0
- data/lib/rx_ruby/concurrency/historical_scheduler.rb +16 -0
- data/lib/rx_ruby/concurrency/immediate_scheduler.rb +68 -0
- data/lib/rx_ruby/concurrency/local_scheduler.rb +39 -0
- data/lib/rx_ruby/concurrency/periodic_scheduler.rb +74 -0
- data/lib/rx_ruby/concurrency/scheduled_item.rb +42 -0
- data/lib/rx_ruby/concurrency/scheduler.rb +150 -0
- data/lib/rx_ruby/concurrency/virtual_time_scheduler.rb +170 -0
- data/lib/rx_ruby/core/async_lock_observer.rb +46 -0
- data/lib/rx_ruby/core/auto_detach_observer.rb +59 -0
- data/lib/rx_ruby/core/checked_observer.rb +66 -0
- data/lib/rx_ruby/core/notification.rb +161 -0
- data/lib/rx_ruby/core/observable.rb +104 -0
- data/lib/rx_ruby/core/observe_on_observer.rb +50 -0
- data/lib/rx_ruby/core/observer.rb +119 -0
- data/lib/rx_ruby/core/scheduled_observer.rb +83 -0
- data/lib/rx_ruby/core/synchronized_observer.rb +47 -0
- data/lib/rx_ruby/core/time_interval.rb +17 -0
- data/lib/rx_ruby/internal/priority_queue.rb +122 -0
- data/lib/rx_ruby/internal/util.rb +9 -0
- data/lib/rx_ruby/joins/active_plan.rb +45 -0
- data/lib/rx_ruby/joins/join_observer.rb +51 -0
- data/lib/rx_ruby/joins/pattern.rb +14 -0
- data/lib/rx_ruby/joins/plan.rb +44 -0
- data/lib/rx_ruby/linq/connectable_observable.rb +34 -0
- data/lib/rx_ruby/linq/observable/_observable_timer_date_and_period.rb +22 -0
- data/lib/rx_ruby/linq/observable/_observable_timer_time_span.rb +14 -0
- data/lib/rx_ruby/linq/observable/_observable_timer_time_span_and_period.rb +20 -0
- data/lib/rx_ruby/linq/observable/aggregate.rb +7 -0
- data/lib/rx_ruby/linq/observable/and.rb +7 -0
- data/lib/rx_ruby/linq/observable/case.rb +15 -0
- data/lib/rx_ruby/linq/observable/concat_all.rb +7 -0
- data/lib/rx_ruby/linq/observable/concat_map.rb +35 -0
- data/lib/rx_ruby/linq/observable/concat_map_observer.rb +43 -0
- data/lib/rx_ruby/linq/observable/contains.rb +28 -0
- data/lib/rx_ruby/linq/observable/debounce.rb +41 -0
- data/lib/rx_ruby/linq/observable/delay.rb +81 -0
- data/lib/rx_ruby/linq/observable/delay_with_selector.rb +64 -0
- data/lib/rx_ruby/linq/observable/do.rb +42 -0
- data/lib/rx_ruby/linq/observable/for.rb +13 -0
- data/lib/rx_ruby/linq/observable/fork_join.rb +55 -0
- data/lib/rx_ruby/linq/observable/from.rb +34 -0
- data/lib/rx_ruby/linq/observable/group_join.rb +108 -0
- data/lib/rx_ruby/linq/observable/if.rb +17 -0
- data/lib/rx_ruby/linq/observable/interval.rb +5 -0
- data/lib/rx_ruby/linq/observable/multicast.rb +14 -0
- data/lib/rx_ruby/linq/observable/of.rb +11 -0
- data/lib/rx_ruby/linq/observable/pairs.rb +7 -0
- data/lib/rx_ruby/linq/observable/pluck.rb +7 -0
- data/lib/rx_ruby/linq/observable/publish.rb +11 -0
- data/lib/rx_ruby/linq/observable/start.rb +7 -0
- data/lib/rx_ruby/linq/observable/time_interval.rb +15 -0
- data/lib/rx_ruby/linq/observable/timer.rb +26 -0
- data/lib/rx_ruby/linq/observable/timestamp.rb +9 -0
- data/lib/rx_ruby/linq/observable/to_async.rb +40 -0
- data/lib/rx_ruby/linq/observable/when.rb +36 -0
- data/lib/rx_ruby/linq/observable/while.rb +41 -0
- data/lib/rx_ruby/operators/aggregates.rb +611 -0
- data/lib/rx_ruby/operators/creation.rb +220 -0
- data/lib/rx_ruby/operators/multiple.rb +735 -0
- data/lib/rx_ruby/operators/single.rb +399 -0
- data/lib/rx_ruby/operators/standard_query_operators.rb +279 -0
- data/lib/rx_ruby/operators/synchronization.rb +47 -0
- data/lib/rx_ruby/operators/time.rb +120 -0
- data/lib/rx_ruby/subjects/async_subject.rb +161 -0
- data/lib/rx_ruby/subjects/behavior_subject.rb +149 -0
- data/lib/rx_ruby/subjects/replay_subject.rb +39 -0
- data/lib/rx_ruby/subjects/subject.rb +131 -0
- data/lib/rx_ruby/subjects/subject_extensions.rb +45 -0
- data/lib/rx_ruby/subscriptions/composite_subscription.rb +91 -0
- data/lib/rx_ruby/subscriptions/ref_count_subscription.rb +88 -0
- data/lib/rx_ruby/subscriptions/scheduled_subscription.rb +32 -0
- data/lib/rx_ruby/subscriptions/serial_subscription.rb +60 -0
- data/lib/rx_ruby/subscriptions/single_assignment_subscription.rb +64 -0
- data/lib/rx_ruby/subscriptions/subscription.rb +56 -0
- data/lib/rx_ruby/testing/cold_observable.rb +45 -0
- data/lib/rx_ruby/testing/hot_observable.rb +47 -0
- data/lib/rx_ruby/testing/mock_observer.rb +33 -0
- data/lib/rx_ruby/testing/reactive_test.rb +94 -0
- data/lib/rx_ruby/testing/recorded.rb +17 -0
- data/lib/rx_ruby/testing/test_scheduler.rb +96 -0
- data/lib/rx_ruby/testing/test_subscription.rb +22 -0
- data/lib/rx_ruby/version.rb +3 -0
- data/license.txt +13 -0
- data/readme.md +152 -0
- data/rx_ruby.gemspec +22 -0
- data/test/rx_ruby/concurrency/helpers/historical_virtual_scheduler_helper.rb +135 -0
- data/test/rx_ruby/concurrency/helpers/immediate_local_scheduler_helper.rb +51 -0
- data/test/rx_ruby/concurrency/test_async_lock.rb +56 -0
- data/test/rx_ruby/concurrency/test_current_thread_scheduler.rb +44 -0
- data/test/rx_ruby/concurrency/test_default_scheduler.rb +44 -0
- data/test/rx_ruby/concurrency/test_historical_scheduler.rb +18 -0
- data/test/rx_ruby/concurrency/test_immediate_scheduler.rb +53 -0
- data/test/rx_ruby/concurrency/test_local_scheduler.rb +12 -0
- data/test/rx_ruby/concurrency/test_periodic_scheduler.rb +53 -0
- data/test/rx_ruby/concurrency/test_scheduled_item.rb +50 -0
- data/test/rx_ruby/concurrency/test_scheduler.rb +128 -0
- data/test/rx_ruby/concurrency/test_virtual_time_scheduler.rb +14 -0
- data/test/rx_ruby/core/test_notification.rb +129 -0
- data/test/rx_ruby/core/test_observable_creation.rb +483 -0
- data/test/rx_ruby/core/test_observer.rb +634 -0
- data/test/rx_ruby/internal/test_priority_queue.rb +71 -0
- data/test/rx_ruby/subscriptions/test_composite_subscription.rb +116 -0
- data/test/rx_ruby/subscriptions/test_serial_subscription.rb +62 -0
- data/test/rx_ruby/subscriptions/test_singleassignment_subscription.rb +61 -0
- data/test/rx_ruby/subscriptions/test_subscription.rb +27 -0
- data/test/test_helper.rb +11 -0
- metadata +291 -0
@@ -0,0 +1,45 @@
|
|
1
|
+
module RxRuby
|
2
|
+
class ActivePlan
|
3
|
+
def initialize(join_observer_array, on_next, on_completed)
|
4
|
+
@join_observer_array = join_observer_array
|
5
|
+
@on_next = on_next
|
6
|
+
@on_completed = on_completed
|
7
|
+
@join_observers = {}
|
8
|
+
@join_observer_array.each {|x|
|
9
|
+
@join_observers[x] = x
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
def dequeue
|
14
|
+
@join_observers.each {|_, v| v.queue.shift }
|
15
|
+
end
|
16
|
+
|
17
|
+
def match
|
18
|
+
has_values = true
|
19
|
+
@join_observer_array.each {|v|
|
20
|
+
if v.queue.length == 0
|
21
|
+
has_values = false
|
22
|
+
break
|
23
|
+
end
|
24
|
+
}
|
25
|
+
if has_values
|
26
|
+
first_values = []
|
27
|
+
is_completed = false
|
28
|
+
@join_observer_array.each {|v|
|
29
|
+
first_values.push v.queue[0]
|
30
|
+
is_completed = true if v.queue[0].on_completed?
|
31
|
+
}
|
32
|
+
if is_completed
|
33
|
+
@on_completed.call
|
34
|
+
else
|
35
|
+
dequeue
|
36
|
+
values = []
|
37
|
+
first_values.each {|v|
|
38
|
+
values.push v.value
|
39
|
+
}
|
40
|
+
@on_next.call(*values)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module RxRuby
|
2
|
+
class JoinObserver < ObserverBase
|
3
|
+
|
4
|
+
attr_reader :queue
|
5
|
+
def initialize(source, on_error)
|
6
|
+
super Observer.configure {|o|
|
7
|
+
o.on_next {|notification|
|
8
|
+
if !@is_disposed
|
9
|
+
if notification.on_error?
|
10
|
+
@on_error.call(notification.exception)
|
11
|
+
next
|
12
|
+
end
|
13
|
+
@queue.push notification
|
14
|
+
@active_plans.dup.each {|v|
|
15
|
+
v.match
|
16
|
+
}
|
17
|
+
end
|
18
|
+
}
|
19
|
+
}
|
20
|
+
@source = source
|
21
|
+
@on_error = on_error
|
22
|
+
@queue = []
|
23
|
+
@active_plans = []
|
24
|
+
@subscription = SingleAssignmentSubscription.new
|
25
|
+
@is_disposed = false
|
26
|
+
end
|
27
|
+
|
28
|
+
def add_active_plan(active_plan)
|
29
|
+
@active_plans.push active_plan
|
30
|
+
end
|
31
|
+
|
32
|
+
def subscribe
|
33
|
+
@subscription.subscription = @source.materialize.subscribe(@config)
|
34
|
+
end
|
35
|
+
|
36
|
+
def remove_active_plan(active_plan)
|
37
|
+
if idx = @active_plans.index(active_plan)
|
38
|
+
@active_plans.delete_at idx
|
39
|
+
end
|
40
|
+
self.unsubscribe if @active_plans.length == 0
|
41
|
+
end
|
42
|
+
|
43
|
+
def unsubscribe
|
44
|
+
super
|
45
|
+
if !@is_disposed
|
46
|
+
@is_disposed = true
|
47
|
+
@subscription.unsubscribe
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module RxRuby
|
2
|
+
class Pattern
|
3
|
+
attr_reader :patterns
|
4
|
+
def initialize(patterns)
|
5
|
+
@patterns = patterns
|
6
|
+
end
|
7
|
+
def and(other)
|
8
|
+
Pattern.new(@patterns.concat(other))
|
9
|
+
end
|
10
|
+
def then_do(selector = Proc.new)
|
11
|
+
Plan.new(self, selector)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module RxRuby
|
2
|
+
class Plan
|
3
|
+
def initialize(expression, selector)
|
4
|
+
@expression = expression
|
5
|
+
@selector = selector
|
6
|
+
end
|
7
|
+
|
8
|
+
def activate(external_subscriptions, observer, deactivate)
|
9
|
+
join_observers = []
|
10
|
+
@expression.patterns.each {|pat|
|
11
|
+
join_observers.push plan_create_observer(external_subscriptions, pat, observer.method(:on_error))
|
12
|
+
}
|
13
|
+
|
14
|
+
active_plan = ActivePlan.new(join_observers, lambda {|*args|
|
15
|
+
begin
|
16
|
+
result = @selector.call(*args)
|
17
|
+
rescue => e
|
18
|
+
observer.on_error e
|
19
|
+
end
|
20
|
+
observer.on_next result
|
21
|
+
},
|
22
|
+
lambda {
|
23
|
+
join_observers.each {|v|
|
24
|
+
v.remove_active_plan(active_plan)
|
25
|
+
}
|
26
|
+
deactivate.call(active_plan)
|
27
|
+
})
|
28
|
+
join_observers.each {|v|
|
29
|
+
v.add_active_plan(active_plan)
|
30
|
+
}
|
31
|
+
return active_plan
|
32
|
+
end
|
33
|
+
|
34
|
+
def plan_create_observer(external_subscriptions, observable, on_error)
|
35
|
+
entry = external_subscriptions[observable]
|
36
|
+
if !entry
|
37
|
+
observer = JoinObserver.new(observable, on_error)
|
38
|
+
external_subscriptions[observable] = observer
|
39
|
+
return observer
|
40
|
+
end
|
41
|
+
entry
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module RxRuby
|
2
|
+
class ConnectableObservable < AnonymousObservable
|
3
|
+
def initialize(source, subject)
|
4
|
+
@has_subscription = false
|
5
|
+
@subscription = nil
|
6
|
+
@source_observable = source.as_observable
|
7
|
+
@subject = subject
|
8
|
+
|
9
|
+
super(&subject.method(:subscribe))
|
10
|
+
end
|
11
|
+
|
12
|
+
def connect
|
13
|
+
unless @has_subscription
|
14
|
+
@has_subscription = true
|
15
|
+
@subscription = CompositeSubscription.new [@source_observable.subscribe(@subject), Subscription.create { @has_subscription = false }]
|
16
|
+
end
|
17
|
+
@subscription
|
18
|
+
end
|
19
|
+
|
20
|
+
def ref_count
|
21
|
+
count = 0
|
22
|
+
AnonymousObservable.new do |observer|
|
23
|
+
count += 1
|
24
|
+
should_connect = true if count == 1
|
25
|
+
connectable_subscription = self.connect if should_connect
|
26
|
+
Subscription.create {
|
27
|
+
@subscription.unsubscribe
|
28
|
+
count -= 1
|
29
|
+
connectable_subscription.unsubscribe if count == 0
|
30
|
+
}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module RxRuby
|
2
|
+
class << Observable
|
3
|
+
private
|
4
|
+
def observable_timer_date_and_period(due_time, period, scheduler)
|
5
|
+
AnonymousObservable.new do |observer|
|
6
|
+
count = 0
|
7
|
+
d = due_time
|
8
|
+
p = Scheduler.normalize(period)
|
9
|
+
scheduler.schedule_recursive_absolute(d, lambda {|this|
|
10
|
+
if p > 0
|
11
|
+
now = scheduler.now()
|
12
|
+
d = d + p
|
13
|
+
d <= now && (d = now + p)
|
14
|
+
end
|
15
|
+
observer.on_next(count)
|
16
|
+
count += 1
|
17
|
+
this.call(d)
|
18
|
+
})
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module RxRuby
|
2
|
+
class << Observable
|
3
|
+
private
|
4
|
+
def observable_timer_time_span(due_time, scheduler)
|
5
|
+
AnonymousObservable.new do |observer|
|
6
|
+
scheduler.schedule_relative(Scheduler.normalize(due_time),
|
7
|
+
lambda {
|
8
|
+
observer.on_next(0)
|
9
|
+
observer.on_completed
|
10
|
+
})
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module RxRuby
|
2
|
+
class << Observable
|
3
|
+
private
|
4
|
+
def observable_timer_time_span_and_period(due_time, period, scheduler)
|
5
|
+
if due_time == period
|
6
|
+
AnonymousObservable.new do |observer|
|
7
|
+
scheduler.schedule_periodic_with_state(0, period,
|
8
|
+
lambda {|count|
|
9
|
+
observer.on_next(count)
|
10
|
+
count + 1
|
11
|
+
})
|
12
|
+
end
|
13
|
+
else
|
14
|
+
Observable.defer {
|
15
|
+
observable_timer_date_and_period(scheduler.now() + due_time, period, scheduler)
|
16
|
+
}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module RxRuby
|
2
|
+
class << Observable
|
3
|
+
def case(selector, sources, defaultSourceOrScheduler = Observable.empty)
|
4
|
+
defer {
|
5
|
+
if Scheduler === defaultSourceOrScheduler
|
6
|
+
defaultSourceOrScheduler = Observable.empty(defaultSourceOrScheduler)
|
7
|
+
end
|
8
|
+
|
9
|
+
result = sources[selector.call]
|
10
|
+
result || defaultSourceOrScheduler
|
11
|
+
}
|
12
|
+
end
|
13
|
+
alias :switchCase :case
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module RxRuby
|
2
|
+
module Observable
|
3
|
+
def concat_map(selector, result_selector = nil)
|
4
|
+
if Proc === result_selector
|
5
|
+
return concat_map(lambda {|x, i|
|
6
|
+
selector_result = selector.call(x, i)
|
7
|
+
if selector_result.respond_to?(:each)
|
8
|
+
selector_result = Observable.from(selector_result)
|
9
|
+
end
|
10
|
+
selector_result.map_with_index {|y, i2|
|
11
|
+
result_selector.call(x, y, i, i2)
|
12
|
+
}
|
13
|
+
})
|
14
|
+
end
|
15
|
+
|
16
|
+
if Proc === selector
|
17
|
+
_concat_map(selector)
|
18
|
+
else
|
19
|
+
_concat_map(lambda {|*_| selector })
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def _concat_map(selector)
|
26
|
+
map_with_index {|x, i|
|
27
|
+
result = selector.call(x, i)
|
28
|
+
if result.respond_to?(:each)
|
29
|
+
result = Observable.from(result)
|
30
|
+
end
|
31
|
+
result
|
32
|
+
}.concat_all
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module RxRuby
|
2
|
+
module Observable
|
3
|
+
def concat_map_observer(on_next, on_error, on_completed)
|
4
|
+
AnonymousObservable.new do |observer|
|
5
|
+
index = 0
|
6
|
+
|
7
|
+
subscribe(
|
8
|
+
lambda {|x|
|
9
|
+
begin
|
10
|
+
result = on_next.call(x, index)
|
11
|
+
index += 1
|
12
|
+
rescue => e
|
13
|
+
observer.on_error e
|
14
|
+
return
|
15
|
+
end
|
16
|
+
observer.on_next result
|
17
|
+
},
|
18
|
+
lambda {|err|
|
19
|
+
begin
|
20
|
+
result = on_error.call(err)
|
21
|
+
rescue => e
|
22
|
+
observer.on_error e
|
23
|
+
return
|
24
|
+
end
|
25
|
+
|
26
|
+
observer.on_next result
|
27
|
+
observer.on_completed
|
28
|
+
},
|
29
|
+
lambda {
|
30
|
+
begin
|
31
|
+
result = on_completed.call
|
32
|
+
rescue => e
|
33
|
+
observer.on_error e
|
34
|
+
return
|
35
|
+
end
|
36
|
+
|
37
|
+
observer.on_next result
|
38
|
+
observer.on_completed
|
39
|
+
})
|
40
|
+
end.concat_all
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module RxRuby
|
2
|
+
module Observable
|
3
|
+
def contains(search_element, from_index = 0)
|
4
|
+
AnonymousObservable.new do |observer|
|
5
|
+
i = 0
|
6
|
+
n = from_index
|
7
|
+
if n < 0
|
8
|
+
observer.on_next false
|
9
|
+
observer.on_completed
|
10
|
+
return Subscription.empty
|
11
|
+
end
|
12
|
+
|
13
|
+
subscribe(
|
14
|
+
lambda {|x|
|
15
|
+
if i.tap { i += 1 } >= n && x == search_element
|
16
|
+
observer.on_next true
|
17
|
+
observer.on_completed
|
18
|
+
end
|
19
|
+
},
|
20
|
+
observer.method(:on_error),
|
21
|
+
lambda {
|
22
|
+
observer.on_next false
|
23
|
+
observer.on_completed
|
24
|
+
})
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module RxRuby
|
2
|
+
module Observable
|
3
|
+
def debounce(due_time, scheduler = DefaultScheduler.instance)
|
4
|
+
AnonymousObservable.new do |observer|
|
5
|
+
cancelable = SerialSubscription.new
|
6
|
+
hasvalue = false
|
7
|
+
value = nil
|
8
|
+
id = 0
|
9
|
+
|
10
|
+
subscription = subscribe(
|
11
|
+
lambda {|x|
|
12
|
+
hasvalue = true
|
13
|
+
value = x
|
14
|
+
id += 1
|
15
|
+
current_id = id
|
16
|
+
d = SingleAssignmentSubscription.new
|
17
|
+
cancelable.subscription = d
|
18
|
+
d.subscription = scheduler.schedule_relative(due_time, lambda {
|
19
|
+
observer.on_next value if hasvalue && id == current_id
|
20
|
+
hasvalue = false
|
21
|
+
})
|
22
|
+
},
|
23
|
+
lambda {|e|
|
24
|
+
cancelable.dispose
|
25
|
+
observer.on_error e
|
26
|
+
hasvalue = false
|
27
|
+
id += 1
|
28
|
+
},
|
29
|
+
lambda {
|
30
|
+
cancelable.dispose
|
31
|
+
observer.on_next value if hasvalue
|
32
|
+
observer.on_completed
|
33
|
+
hasvalue = false
|
34
|
+
id += 1
|
35
|
+
})
|
36
|
+
|
37
|
+
CompositeSubscription.new [subscription, cancelable]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|