Skip to content

Commit

Permalink
Adds repeatElement operator.
Browse files Browse the repository at this point in the history
  • Loading branch information
kzaher committed Sep 13, 2015
1 parent 4695ab9 commit 880c777
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ All notable changes to this project will be documented in this file.
* Removes `SpinLock`s in disposables in favor of more performant `OSAtomicCompareAndSwap32`.
* Adds `buffer` operator (version with time and count).
* Adds `range` operator.
* Adds `repeat` operator.

## [2.0.0-alpha.2](https://github.com/ReactiveX/RxSwift/releases/tag/2.0.0-alpha.2)

Expand Down
6 changes: 6 additions & 0 deletions Rx.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,8 @@
C84B38EF1BA433CD001B7D88 /* Generate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C84B38ED1BA433CD001B7D88 /* Generate.swift */; };
C86409FC1BA593F500D3C4E8 /* Range.swift in Sources */ = {isa = PBXBuildFile; fileRef = C86409FB1BA593F500D3C4E8 /* Range.swift */; };
C86409FD1BA593F500D3C4E8 /* Range.swift in Sources */ = {isa = PBXBuildFile; fileRef = C86409FB1BA593F500D3C4E8 /* Range.swift */; };
C8640A031BA5B12A00D3C4E8 /* Repeat.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8640A021BA5B12A00D3C4E8 /* Repeat.swift */; };
C8640A041BA5B12A00D3C4E8 /* Repeat.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8640A021BA5B12A00D3C4E8 /* Repeat.swift */; };
C88254161B8A752B00B02D69 /* RxCollectionViewReactiveArrayDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C88253F11B8A752B00B02D69 /* RxCollectionViewReactiveArrayDataSource.swift */; };
C88254171B8A752B00B02D69 /* RxTableViewReactiveArrayDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C88253F21B8A752B00B02D69 /* RxTableViewReactiveArrayDataSource.swift */; };
C88254181B8A752B00B02D69 /* ItemEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = C88253F41B8A752B00B02D69 /* ItemEvents.swift */; };
Expand Down Expand Up @@ -459,6 +461,7 @@
C84B38E71BA43380001B7D88 /* ScheduledItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScheduledItem.swift; sourceTree = "<group>"; };
C84B38ED1BA433CD001B7D88 /* Generate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Generate.swift; sourceTree = "<group>"; };
C86409FB1BA593F500D3C4E8 /* Range.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Range.swift; sourceTree = "<group>"; };
C8640A021BA5B12A00D3C4E8 /* Repeat.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Repeat.swift; sourceTree = "<group>"; };
C88253F11B8A752B00B02D69 /* RxCollectionViewReactiveArrayDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxCollectionViewReactiveArrayDataSource.swift; sourceTree = "<group>"; };
C88253F21B8A752B00B02D69 /* RxTableViewReactiveArrayDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxTableViewReactiveArrayDataSource.swift; sourceTree = "<group>"; };
C88253F41B8A752B00B02D69 /* ItemEvents.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemEvents.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -673,6 +676,7 @@
C86409FB1BA593F500D3C4E8 /* Range.swift */,
C8093C841B8A72BE0088E94D /* Reduce.swift */,
C8093C851B8A72BE0088E94D /* RefCount.swift */,
C8640A021BA5B12A00D3C4E8 /* Repeat.swift */,
C8093C861B8A72BE0088E94D /* Sample.swift */,
C8093C871B8A72BE0088E94D /* Scan.swift */,
C8093C881B8A72BE0088E94D /* Sink.swift */,
Expand Down Expand Up @@ -1376,6 +1380,7 @@
C8093D441B8A72BE0088E94D /* Take.swift in Sources */,
C8093D321B8A72BE0088E94D /* Reduce.swift in Sources */,
C84B38EA1BA43380001B7D88 /* ScheduledItem.swift in Sources */,
C8640A041BA5B12A00D3C4E8 /* Repeat.swift in Sources */,
C8093CF41B8A72BE0088E94D /* Error.swift in Sources */,
C8093D141B8A72BE0088E94D /* Debug.swift in Sources */,
C8093CCE1B8A72BE0088E94D /* Bag.swift in Sources */,
Expand Down Expand Up @@ -1487,6 +1492,7 @@
C8093D431B8A72BE0088E94D /* Take.swift in Sources */,
C8093D311B8A72BE0088E94D /* Reduce.swift in Sources */,
C84B38E91BA43380001B7D88 /* ScheduledItem.swift in Sources */,
C8640A031BA5B12A00D3C4E8 /* Repeat.swift in Sources */,
C8093CF31B8A72BE0088E94D /* Error.swift in Sources */,
C8093D131B8A72BE0088E94D /* Debug.swift in Sources */,
C8093CCD1B8A72BE0088E94D /* Bag.swift in Sources */,
Expand Down
4 changes: 4 additions & 0 deletions RxExample/RxExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@
C86409F91BA5909000D3C4E8 /* SubjectType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C864098E1BA5909000D3C4E8 /* SubjectType.swift */; };
C86409FA1BA5909000D3C4E8 /* Variable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C864098F1BA5909000D3C4E8 /* Variable.swift */; };
C86409FF1BA5A87200D3C4E8 /* Range.swift in Sources */ = {isa = PBXBuildFile; fileRef = C86409FE1BA5A87200D3C4E8 /* Range.swift */; };
C8640A011BA5AB5A00D3C4E8 /* Repeat.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8640A001BA5AB5A00D3C4E8 /* Repeat.swift */; };
C86E2F3E1AE5A0CA00C31024 /* SearchResultViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C86E2F321AE5A0CA00C31024 /* SearchResultViewModel.swift */; };
C86E2F3F1AE5A0CA00C31024 /* SearchViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C86E2F331AE5A0CA00C31024 /* SearchViewModel.swift */; };
C86E2F451AE5A0CA00C31024 /* WikipediaAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = C86E2F3B1AE5A0CA00C31024 /* WikipediaAPI.swift */; };
Expand Down Expand Up @@ -522,6 +523,7 @@
C864098E1BA5909000D3C4E8 /* SubjectType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SubjectType.swift; sourceTree = "<group>"; };
C864098F1BA5909000D3C4E8 /* Variable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Variable.swift; sourceTree = "<group>"; };
C86409FE1BA5A87200D3C4E8 /* Range.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Range.swift; sourceTree = "<group>"; };
C8640A001BA5AB5A00D3C4E8 /* Repeat.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Repeat.swift; sourceTree = "<group>"; };
C86E2F321AE5A0CA00C31024 /* SearchResultViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = SearchResultViewModel.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C86E2F331AE5A0CA00C31024 /* SearchViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = SearchViewModel.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C86E2F3B1AE5A0CA00C31024 /* WikipediaAPI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WikipediaAPI.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1002,6 +1004,7 @@
C86409FE1BA5A87200D3C4E8 /* Range.swift */,
C864095A1BA5909000D3C4E8 /* Reduce.swift */,
C864095B1BA5909000D3C4E8 /* RefCount.swift */,
C8640A001BA5AB5A00D3C4E8 /* Repeat.swift */,
C864095C1BA5909000D3C4E8 /* Sample.swift */,
C864095D1BA5909000D3C4E8 /* Scan.swift */,
C864095E1BA5909000D3C4E8 /* Sink.swift */,
Expand Down Expand Up @@ -1516,6 +1519,7 @@
C8297E561B6CF905000589EA /* WikipediaPage.swift in Sources */,
C86409921BA5909000D3C4E8 /* Lock.swift in Sources */,
C86409901BA5909000D3C4E8 /* Cancelable.swift in Sources */,
C8640A011BA5AB5A00D3C4E8 /* Repeat.swift in Sources */,
C84B3A2F1BA4345A001B7D88 /* _RXKVOObserver.m in Sources */,
C8297E571B6CF905000589EA /* Randomizer.swift in Sources */,
C86409981BA5909000D3C4E8 /* AnonymousDisposable.swift in Sources */,
Expand Down
43 changes: 43 additions & 0 deletions RxSwift/Observables/Implementations/Repeat.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//
// Repeat.swift
// RxExample
//
// Created by Krunoslav Zaher on 9/13/15.
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
//

import Foundation

class RepeatElement<Element> : Producer<Element> {
let element: Element
let scheduler: ImmediateSchedulerType

init(element: Element, scheduler: ImmediateSchedulerType) {
self.element = element
self.scheduler = scheduler
}

override func run<O : ObserverType where O.E == Element>(observer: O, cancel: Disposable, setSink: (Disposable) -> Void) -> Disposable {
let sink = RepeatElementSink(parent: self, observer: observer, cancel: cancel)
setSink(sink)
return sink.run()
}
}

class RepeatElementSink<O: ObserverType> : Sink<O> {
typealias Parent = RepeatElement<O.E>

let parent: Parent

init(parent: Parent, observer: O, cancel: Disposable) {
self.parent = parent
super.init(observer: observer, cancel: cancel)
}

func run() -> Disposable {
return self.parent.scheduler.scheduleRecursive(self.parent.element) { e, recurse in
self.observer?.on(.Next(e))
recurse(e)
}
}
}
14 changes: 12 additions & 2 deletions RxSwift/Observables/Observable+Creation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ public func deferred<E>(observableFactory: () throws -> Observable<E>)
return Deferred(observableFactory: observableFactory)
}


/**
Generates an observable sequence by running a state-driven loop producing the sequence's elements, using the specified scheduler
to run the loop send out observer messages.
Expand Down Expand Up @@ -148,4 +147,15 @@ public func range(start: Int, _ count: Int, _ scheduler: ImmediateSchedulerType
}

return RangeProducer<Int>(start: start, count: count, scheduler: scheduler)
}
}

/**
Generates an observable sequence that repeats the given element infinitely, using the specified scheduler to send out observer messages.

- parameter element: Element to repeat.
- parameter scheduler: Scheduler to run the producer loop on.
- returns: An observable sequence that repeats the given element infinitely.
*/
public func repeatElement<E>(element: E, _ scheduler: ImmediateSchedulerType) -> Observable<E> {
return RepeatElement(element: element, scheduler: scheduler)
}
21 changes: 21 additions & 0 deletions RxTests/RxSwiftTests/Tests/Observable+CreationTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ extension ObservableCreationTests {
}
}

// range
extension ObservableCreationTests {
func testRange_Boundaries() {
let scheduler = TestScheduler(initialClock: 0)
Expand Down Expand Up @@ -127,4 +128,24 @@ extension ObservableCreationTests {
next(203, -8)
])
}
}

// repeatElement
extension ObservableCreationTests {
func testRepeat_Element() {
let scheduler = TestScheduler(initialClock: 0)

let res = scheduler.start(207) {
repeatElement(42, scheduler)
}

XCTAssertEqual(res.messages, [
next(201, 42),
next(202, 42),
next(203, 42),
next(204, 42),
next(205, 42),
next(206, 42)
])
}
}

0 comments on commit 880c777

Please sign in to comment.