Skip to content

Commit

Permalink
Update readme and licence
Browse files Browse the repository at this point in the history
  • Loading branch information
Srđan Rašić committed Nov 4, 2015
1 parent d6425b1 commit 32b8411
Show file tree
Hide file tree
Showing 31 changed files with 742 additions and 170 deletions.
80 changes: 77 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,83 @@

__rKit__ is a collection of Swift frameworks for reactive and functional reactive programming.

* __rKit__ - A core framework that provides cold Stream and hot ActiveStream types and their derivatives Tasks type, Observable type and Observable Array, Dictionary and Set types.
* __rFoundation__ - Foundation framework extensions like type-safe KVO.
* __rUIKit__ - UIKit extensions (bindings).
* [rKit](https://github.com/ReactiveKit/rKit) - A core framework that provides cold Stream and hot ActiveStream types and their derivatives - Tasks, Observable and ObservableCollection types.
* [rFoundation](https://github.com/ReactiveKit/rFoundation) - Foundation framework extensions like type-safe KVO.
* [rUIKit](https://github.com/ReactiveKit/rUIKit) - UIKit extensions (bindings).

## Observable

`Observable` type represents observable mutable state, like a variable whose changes can be observed.

```swift
let name = Observable("Jim")

name.observe { value in
print(value)
}

name.value = "Jim Kirk" // prints: Jim Kirk

name.bindTo(nameLabel.rText)
```

## Task

`Task` type is used to represents asynchronous work that can fail.

```swift
func fetchImage() -> Task<UIImage, NSError> {

return create { sink in
...
sink.next(image)
sink.success()
...
}
}


fetchImage().observeNext(on: Queue.Main.contex) { image in
...
}

fetchImage().bindTo(imageView.rImage)

```

Each call to task's `observe` method performs separate work. To share results of a single call, use a `shareNext` method.

```swift
let image = fetchImage().shareNext(on: Queue.Main.context)

image.bindTo(imageView1)
image.bindTo(imageView2)
```

## Streams

Both Task and Observable are streams that conform to `StreamType` protocol. Streams can be transformed, for example:

```swift
func fetchAndBlurImage() -> Task<UIImage, NSError> {
return fetchImage().map { $0.applyBlur() }
}

```

## ObservableCollection

`ObservableCollection` is a stream that can be used to encapsulate a collection (array, dictionary or set) and send fine-grained events describing changes that occured.

```swift
let names: ObservableCollection(["Steve", "Tim"])

names.observe { event in
print(event.inserts)
}

names.append("John") // prints: [2]
```

## Installation

Expand Down
66 changes: 34 additions & 32 deletions rKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,36 @@

/* Begin PBXBuildFile section */
ECF536B01BE8F4C000015674 /* rKit.h in Headers */ = {isa = PBXBuildFile; fileRef = ECF536AF1BE8F4C000015674 /* rKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
ECF536B71BE8F4C000015674 /* rKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ECF536AC1BE8F4C000015674 /* rKit.framework */; settings = {ASSET_TAGS = (); }; };
ECF536B71BE8F4C000015674 /* rKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ECF536AC1BE8F4C000015674 /* rKit.framework */; };
ECF536BC1BE8F4C000015674 /* rKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536BB1BE8F4C000015674 /* rKitTests.swift */; };
ECF536E91BE8F50F00015674 /* BlockDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536C71BE8F50F00015674 /* BlockDisposable.swift */; settings = {ASSET_TAGS = (); }; };
ECF536EA1BE8F50F00015674 /* CompositeDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536C81BE8F50F00015674 /* CompositeDisposable.swift */; settings = {ASSET_TAGS = (); }; };
ECF536EB1BE8F50F00015674 /* Disposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536C91BE8F50F00015674 /* Disposable.swift */; settings = {ASSET_TAGS = (); }; };
ECF536EC1BE8F50F00015674 /* DisposeBag.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536CA1BE8F50F00015674 /* DisposeBag.swift */; settings = {ASSET_TAGS = (); }; };
ECF536ED1BE8F50F00015674 /* SerialDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536CB1BE8F50F00015674 /* SerialDisposable.swift */; settings = {ASSET_TAGS = (); }; };
ECF536EE1BE8F50F00015674 /* SimpleDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536CC1BE8F50F00015674 /* SimpleDisposable.swift */; settings = {ASSET_TAGS = (); }; };
ECF536EF1BE8F50F00015674 /* Lock.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536CE1BE8F50F00015674 /* Lock.swift */; settings = {ASSET_TAGS = (); }; };
ECF536F01BE8F50F00015674 /* Reference.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536CF1BE8F50F00015674 /* Reference.swift */; settings = {ASSET_TAGS = (); }; };
ECF536F11BE8F50F00015674 /* StreamBuffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536D01BE8F50F00015674 /* StreamBuffer.swift */; settings = {ASSET_TAGS = (); }; };
ECF536F21BE8F50F00015674 /* Observable.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536D21BE8F50F00015674 /* Observable.swift */; settings = {ASSET_TAGS = (); }; };
ECF536F31BE8F50F00015674 /* ObservableCollection+Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536D41BE8F50F00015674 /* ObservableCollection+Array.swift */; settings = {ASSET_TAGS = (); }; };
ECF536F41BE8F50F00015674 /* ObservableCollection+Dictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536D51BE8F50F00015674 /* ObservableCollection+Dictionary.swift */; settings = {ASSET_TAGS = (); }; };
ECF536F51BE8F50F00015674 /* ObservableCollection+Set.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536D61BE8F50F00015674 /* ObservableCollection+Set.swift */; settings = {ASSET_TAGS = (); }; };
ECF536F61BE8F50F00015674 /* ObservableCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536D71BE8F50F00015674 /* ObservableCollection.swift */; settings = {ASSET_TAGS = (); }; };
ECF536F71BE8F50F00015674 /* ObservableCollectionEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536D81BE8F50F00015674 /* ObservableCollectionEvent.swift */; settings = {ASSET_TAGS = (); }; };
ECF536F81BE8F50F00015674 /* Bindable.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536DA1BE8F50F00015674 /* Bindable.swift */; settings = {ASSET_TAGS = (); }; };
ECF536F91BE8F50F00015674 /* ExecutionContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536DB1BE8F50F00015674 /* ExecutionContext.swift */; settings = {ASSET_TAGS = (); }; };
ECF536FA1BE8F50F00015674 /* OptionalType.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536DC1BE8F50F00015674 /* OptionalType.swift */; settings = {ASSET_TAGS = (); }; };
ECF536FB1BE8F50F00015674 /* Queue.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536DD1BE8F50F00015674 /* Queue.swift */; settings = {ASSET_TAGS = (); }; };
ECF536FC1BE8F50F00015674 /* TokenizedCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536DE1BE8F50F00015674 /* TokenizedCollection.swift */; settings = {ASSET_TAGS = (); }; };
ECF536FD1BE8F50F00015674 /* ActiveStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536E01BE8F50F00015674 /* ActiveStream.swift */; settings = {ASSET_TAGS = (); }; };
ECF536FE1BE8F50F00015674 /* Stream.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536E11BE8F50F00015674 /* Stream.swift */; settings = {ASSET_TAGS = (); }; };
ECF536FF1BE8F50F00015674 /* StreamType.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536E21BE8F50F00015674 /* StreamType.swift */; settings = {ASSET_TAGS = (); }; };
ECF537001BE8F50F00015674 /* NoError.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536E41BE8F50F00015674 /* NoError.swift */; settings = {ASSET_TAGS = (); }; };
ECF537011BE8F50F00015674 /* Stream+Task.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536E51BE8F50F00015674 /* Stream+Task.swift */; settings = {ASSET_TAGS = (); }; };
ECF537021BE8F50F00015674 /* Task.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536E61BE8F50F00015674 /* Task.swift */; settings = {ASSET_TAGS = (); }; };
ECF537031BE8F50F00015674 /* TaskEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536E71BE8F50F00015674 /* TaskEvent.swift */; settings = {ASSET_TAGS = (); }; };
ECF537041BE8F50F00015674 /* TaskSink.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536E81BE8F50F00015674 /* TaskSink.swift */; settings = {ASSET_TAGS = (); }; };
ECF536E91BE8F50F00015674 /* BlockDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536C71BE8F50F00015674 /* BlockDisposable.swift */; };
ECF536EA1BE8F50F00015674 /* CompositeDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536C81BE8F50F00015674 /* CompositeDisposable.swift */; };
ECF536EB1BE8F50F00015674 /* Disposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536C91BE8F50F00015674 /* Disposable.swift */; };
ECF536EC1BE8F50F00015674 /* DisposeBag.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536CA1BE8F50F00015674 /* DisposeBag.swift */; };
ECF536ED1BE8F50F00015674 /* SerialDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536CB1BE8F50F00015674 /* SerialDisposable.swift */; };
ECF536EE1BE8F50F00015674 /* SimpleDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536CC1BE8F50F00015674 /* SimpleDisposable.swift */; };
ECF536EF1BE8F50F00015674 /* Lock.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536CE1BE8F50F00015674 /* Lock.swift */; };
ECF536F01BE8F50F00015674 /* Reference.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536CF1BE8F50F00015674 /* Reference.swift */; };
ECF536F11BE8F50F00015674 /* StreamBuffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536D01BE8F50F00015674 /* StreamBuffer.swift */; };
ECF536F21BE8F50F00015674 /* Observable.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536D21BE8F50F00015674 /* Observable.swift */; };
ECF536F31BE8F50F00015674 /* ObservableCollection+Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536D41BE8F50F00015674 /* ObservableCollection+Array.swift */; };
ECF536F41BE8F50F00015674 /* ObservableCollection+Dictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536D51BE8F50F00015674 /* ObservableCollection+Dictionary.swift */; };
ECF536F51BE8F50F00015674 /* ObservableCollection+Set.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536D61BE8F50F00015674 /* ObservableCollection+Set.swift */; };
ECF536F61BE8F50F00015674 /* ObservableCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536D71BE8F50F00015674 /* ObservableCollection.swift */; };
ECF536F71BE8F50F00015674 /* ObservableCollectionEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536D81BE8F50F00015674 /* ObservableCollectionEvent.swift */; };
ECF536F81BE8F50F00015674 /* Bindable.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536DA1BE8F50F00015674 /* Bindable.swift */; };
ECF536F91BE8F50F00015674 /* ExecutionContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536DB1BE8F50F00015674 /* ExecutionContext.swift */; };
ECF536FA1BE8F50F00015674 /* OptionalType.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536DC1BE8F50F00015674 /* OptionalType.swift */; };
ECF536FB1BE8F50F00015674 /* Queue.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536DD1BE8F50F00015674 /* Queue.swift */; };
ECF536FC1BE8F50F00015674 /* TokenizedCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536DE1BE8F50F00015674 /* TokenizedCollection.swift */; };
ECF536FD1BE8F50F00015674 /* ActiveStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536E01BE8F50F00015674 /* ActiveStream.swift */; };
ECF536FE1BE8F50F00015674 /* Stream.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536E11BE8F50F00015674 /* Stream.swift */; };
ECF536FF1BE8F50F00015674 /* StreamType.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536E21BE8F50F00015674 /* StreamType.swift */; };
ECF537001BE8F50F00015674 /* NoError.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536E41BE8F50F00015674 /* NoError.swift */; };
ECF537011BE8F50F00015674 /* Stream+Task.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536E51BE8F50F00015674 /* Stream+Task.swift */; };
ECF537021BE8F50F00015674 /* Task.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536E61BE8F50F00015674 /* Task.swift */; };
ECF537031BE8F50F00015674 /* TaskEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536E71BE8F50F00015674 /* TaskEvent.swift */; };
ECF537041BE8F50F00015674 /* TaskSink.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECF536E81BE8F50F00015674 /* TaskSink.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -207,8 +207,8 @@
ECF536DF1BE8F50F00015674 /* Streams */ = {
isa = PBXGroup;
children = (
ECF536E01BE8F50F00015674 /* ActiveStream.swift */,
ECF536E11BE8F50F00015674 /* Stream.swift */,
ECF536E01BE8F50F00015674 /* ActiveStream.swift */,
ECF536E21BE8F50F00015674 /* StreamType.swift */,
);
path = Streams;
Expand All @@ -218,10 +218,10 @@
isa = PBXGroup;
children = (
ECF536E41BE8F50F00015674 /* NoError.swift */,
ECF536E51BE8F50F00015674 /* Stream+Task.swift */,
ECF536E61BE8F50F00015674 /* Task.swift */,
ECF536E71BE8F50F00015674 /* TaskEvent.swift */,
ECF536E81BE8F50F00015674 /* TaskSink.swift */,
ECF536E71BE8F50F00015674 /* TaskEvent.swift */,
ECF536E51BE8F50F00015674 /* Stream+Task.swift */,
);
path = Task;
sourceTree = "<group>";
Expand Down Expand Up @@ -543,6 +543,7 @@
ECF536C21BE8F4C000015674 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
ECF536C31BE8F4C000015674 /* Build configuration list for PBXNativeTarget "rKitTests" */ = {
isa = XCConfigurationList;
Expand All @@ -551,6 +552,7 @@
ECF536C51BE8F4C000015674 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
Expand Down
26 changes: 21 additions & 5 deletions rKit/Disposables/BlockDisposable.swift
Original file line number Diff line number Diff line change
@@ -1,9 +1,25 @@
//
// BlockDisposable.swift
// Streams
// The MIT License (MIT)
//
// Created by Srdan Rasic on 18/10/15.
// Copyright © 2015 Srdan Rasic. All rights reserved.
// Copyright (c) 2015 Srdan Rasic (@srdanrasic)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

/// A disposable that executes the given block upon disposing.
Expand All @@ -14,7 +30,7 @@ public final class BlockDisposable: DisposableType {
}

private var handler: (() -> ())?
private let lock = RecursiveLock(name: "com.swift-bond.Bond.BlockDisposable")
private let lock = RecursiveLock(name: "com.rkit.rkit.BlockDisposable")

public init(_ handler: () -> ()) {
self.handler = handler
Expand Down
26 changes: 21 additions & 5 deletions rKit/Disposables/CompositeDisposable.swift
Original file line number Diff line number Diff line change
@@ -1,17 +1,33 @@
//
// CompositeDisposable.swift
// Streams
// The MIT License (MIT)
//
// Created by Srdan Rasic on 18/10/15.
// Copyright © 2015 Srdan Rasic. All rights reserved.
// Copyright (c) 2015 Srdan Rasic (@srdanrasic)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

/// A disposable that disposes a collection of disposables upon disposing.
public final class CompositeDisposable: DisposableType {

public private(set) var isDisposed: Bool = false
private var disposables: [DisposableType] = []
private let lock = RecursiveLock(name: "com.swift-bond.Bond.CompositeDisposable")
private let lock = RecursiveLock(name: "com.rkit.rkit.CompositeDisposable")

public convenience init() {
self.init([])
Expand Down
24 changes: 20 additions & 4 deletions rKit/Disposables/Disposable.swift
Original file line number Diff line number Diff line change
@@ -1,9 +1,25 @@
//
// Disposable.swift
// Streams
// The MIT License (MIT)
//
// Created by Srdan Rasic on 18/10/15.
// Copyright © 2015 Srdan Rasic. All rights reserved.
// Copyright (c) 2015 Srdan Rasic (@srdanrasic)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

/// Objects conforming to this protocol can dispose or cancel connection or task.
Expand Down
24 changes: 20 additions & 4 deletions rKit/Disposables/DisposeBag.swift
Original file line number Diff line number Diff line change
@@ -1,9 +1,25 @@
//
// DisposeBag.swift
// Streams
// The MIT License (MIT)
//
// Created by Srdan Rasic on 18/10/15.
// Copyright © 2015 Srdan Rasic. All rights reserved.
// Copyright (c) 2015 Srdan Rasic (@srdanrasic)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

/// A disposable container that will dispose a collection of disposables upon deinit.
Expand Down
Loading

0 comments on commit 32b8411

Please sign in to comment.