<commit_before>/*:
> # IMPORTANT: To use `ReactiveSwift.playground`, please:

1. Retrieve the project dependencies using one of the following terminal commands from the ReactiveSwift project root directory:
    - `git submodule update --init`
 **OR**, if you have [Carthage](https://github.com/Carthage/Carthage) installed
    - `carthage checkout`
1. Open `ReactiveSwift.xcworkspace`
1. Build `ReactiveSwift-macOS` scheme
1. Finally open the `ReactiveSwift.playground`
1. Choose `View > Show Debug Area`
*/

import ReactiveSwift
import Foundation

/*:
## SignalProducer

A **signal producer**, represented by the [`SignalProducer`](https://github.com/ReactiveCocoa/ReactiveSwift/blob/master/Sources/SignalProducer.swift) type, creates
[signals](https://github.com/ReactiveCocoa/ReactiveSwift/blob/master/Sources/Signal.swift) and performs side effects.

They can be used to represent operations or tasks, like network
requests, where each invocation of `start()` will create a new underlying
operation, and allow the caller to observe the result(s). The
`startWithSignal()` variant gives access to the produced signal, allowing it to
be observed multiple times if desired.

Because of the behavior of `start()`, each signal created from the same
producer may see a different ordering or version of events, or the stream might
even be completely different! Unlike a plain signal, no work is started (and
thus no events are generated) until an observer is attached, and the work is
restarted anew for each additional observer.

Starting a signal producer returns a [disposable](https://github.com/ReactiveCocoa/ReactiveSwift/blob/master/Sources/Disposable.swift) that can be used to
interrupt/cancel the work associated with the produced signal.

Just like signals, signal producers can also be manipulated via primitives
like `map`, `filter`, etc.
Every signal primitive can be “lifted” to operate upon signal producers instead,
using the `lift` method.
Furthermore, there are additional primitives that control _when_ and _how_ work
is started—for example, `times`.
*/

/*:
### `Subscription`
A SignalProducer represents an operation that can be started on demand. Starting the operation returns a Signal on which the result(s) of the operation can be observed. This behavior is sometimes also called "cold".
This means that a subscriber will never miss any values sent by the SignalProducer.
*/
scopedExample("Subscription") {
	let producer = SignalProducer<Int, Never> { observer, _ in
		print("New subscription, starting operation")
		observer.send(value: 1)
		observer.send(value: 2)
	}

	let subscriber1 = Signal<Int, Never>.Observer(value: { print("Subscriber 1 received \($0)") })
	let subscriber2 = Signal<Int, Never>.Observer(value: { print("Subscriber 2 received \($0)") })

	print("Subscriber 1 subscribes to producer")
	producer.start(subscriber1)

	print("Subscriber 2 subscribes to producer")
	// Notice, how the producer will start the work again
	producer.start(subscriber2)
}

/*:
### `empty`
A producer for a Signal that will immediately complete without sending
any values.
*/
scopedExample("`empty`") {
	let emptyProducer = SignalProducer<Int, Never>.empty

	let observer = Signal<Int, Never>.Observer(
		value: { _ in print("value not called") },
		failed: { _ in print("error not called") },
		completed: { print("completed called") }
	)

	emptyProducer.start(observer)
}

/*:
### `never`
A producer for a Signal that never sends any events to its observers.
*/
scopedExample("`never`") {
	let neverProducer = SignalProducer<Int, Never>.never

	let observer = Signal<Int, Never>.Observer(
		value: { _ in print("value not called") },
		failed: { _ in print("error not called") },
		completed: { print("completed not called") }
	)

	neverProducer.start(observer)
}

/*:
### `startWithSignal`
Creates a Signal from the producer, passes it into the given closure,
then starts sending events on the Signal when the closure has returned.

The closure will also receive a disposable which can be used to
interrupt the work associated with the signal and immediately send an
`Interrupted` event.
*/
scopedExample("`startWithSignal`") {
	var started = false
	var value: Int?

	SignalProducer<Int, Never>(value: 42)
		.on(value: {
			value = $0
		})
		.startWithSignal { signal, disposable in
			print(value)
		}

	print(value)
}

/*:
### `startWithResult`
Creates a Signal from the producer, then adds exactly one observer to
the Signal, which will invoke the given callback when `value` or `failed`
events are received.

Returns a Disposable which can be used to interrupt the work associated
with the Signal, and prevent any future callbacks from being invoked.
*/
scopedExample("`startWithResult`") {
	SignalProducer<Int, Never>(value: 42)
		.startWithResult { result in
			print(result.value)
		}
}

/*:
### `startWithValues`
Creates a Signal from the producer, then adds exactly one observer to
the Signal, which will invoke the given callback when `value` events are
received.

This method is available only if the producer never emits error, or in
other words, has an error type of `Never`.

Returns a Disposable which can be used to interrupt the work associated
with the Signal, and prevent any future callbacks from being invoked.
*/
scopedExample("`startWithValues`") {
	SignalProducer<Int, Never>(value: 42)
		.startWithValues { value in
			print(value)
		}<commit_msg>Fix "'value' is inaccessible due to 'internal' protection level" in SignalProducer playground (#844)<commit_after>/*:
> # IMPORTANT: To use `ReactiveSwift.playground`, please:

1. Retrieve the project dependencies using one of the following terminal commands from the ReactiveSwift project root directory:
    - `git submodule update --init`
 **OR**, if you have [Carthage](https://github.com/Carthage/Carthage) installed
    - `carthage checkout`
1. Open `ReactiveSwift.xcworkspace`
1. Build `ReactiveSwift-macOS` scheme
1. Finally open the `ReactiveSwift.playground`
1. Choose `View > Show Debug Area`
*/

import ReactiveSwift
import Foundation

/*:
## SignalProducer

A **signal producer**, represented by the [`SignalProducer`](https://github.com/ReactiveCocoa/ReactiveSwift/blob/master/Sources/SignalProducer.swift) type, creates
[signals](https://github.com/ReactiveCocoa/ReactiveSwift/blob/master/Sources/Signal.swift) and performs side effects.

They can be used to represent operations or tasks, like network
requests, where each invocation of `start()` will create a new underlying
operation, and allow the caller to observe the result(s). The
`startWithSignal()` variant gives access to the produced signal, allowing it to
be observed multiple times if desired.

Because of the behavior of `start()`, each signal created from the same
producer may see a different ordering or version of events, or the stream might
even be completely different! Unlike a plain signal, no work is started (and
thus no events are generated) until an observer is attached, and the work is
restarted anew for each additional observer.

Starting a signal producer returns a [disposable](https://github.com/ReactiveCocoa/ReactiveSwift/blob/master/Sources/Disposable.swift) that can be used to
interrupt/cancel the work associated with the produced signal.

Just like signals, signal producers can also be manipulated via primitives
like `map`, `filter`, etc.
Every signal primitive can be “lifted” to operate upon signal producers instead,
using the `lift` method.
Furthermore, there are additional primitives that control _when_ and _how_ work
is started—for example, `times`.
*/

/*:
### `Subscription`
A SignalProducer represents an operation that can be started on demand. Starting the operation returns a Signal on which the result(s) of the operation can be observed. This behavior is sometimes also called "cold".
This means that a subscriber will never miss any values sent by the SignalProducer.
*/
scopedExample("Subscription") {
	let producer = SignalProducer<Int, Never> { observer, _ in
		print("New subscription, starting operation")
		observer.send(value: 1)
		observer.send(value: 2)
	}

	let subscriber1 = Signal<Int, Never>.Observer(value: { print("Subscriber 1 received \($0)") })
	let subscriber2 = Signal<Int, Never>.Observer(value: { print("Subscriber 2 received \($0)") })

	print("Subscriber 1 subscribes to producer")
	producer.start(subscriber1)

	print("Subscriber 2 subscribes to producer")
	// Notice, how the producer will start the work again
	producer.start(subscriber2)
}

/*:
### `empty`
A producer for a Signal that will immediately complete without sending
any values.
*/
scopedExample("`empty`") {
	let emptyProducer = SignalProducer<Int, Never>.empty

	let observer = Signal<Int, Never>.Observer(
		value: { _ in print("value not called") },
		failed: { _ in print("error not called") },
		completed: { print("completed called") }
	)

	emptyProducer.start(observer)
}

/*:
### `never`
A producer for a Signal that never sends any events to its observers.
*/
scopedExample("`never`") {
	let neverProducer = SignalProducer<Int, Never>.never

	let observer = Signal<Int, Never>.Observer(
		value: { _ in print("value not called") },
		failed: { _ in print("error not called") },
		completed: { print("completed not called") }
	)

	neverProducer.start(observer)
}

/*:
### `startWithSignal`
Creates a Signal from the producer, passes it into the given closure,
then starts sending events on the Signal when the closure has returned.

The closure will also receive a disposable which can be used to
interrupt the work associated with the signal and immediately send an
`Interrupted` event.
*/
scopedExample("`startWithSignal`") {
	var started = false
	var value: Int?

	SignalProducer<Int, Never>(value: 42)
		.on(value: {
			value = $0
		})
		.startWithSignal { signal, disposable in
			print(value)
		}

	print(value)
}

/*:
### `startWithResult`
Creates a Signal from the producer, then adds exactly one observer to
the Signal, which will invoke the given callback when `value` or `failed`
events are received.

Returns a Disposable which can be used to interrupt the work associated
with the Signal, and prevent any future callbacks from being invoked.
*/
scopedExample("`startWithResult`") {
	SignalProducer<Int, Never>(value: 42)
		.startWithResult { result in
			print(result)
		}
}

/*:
### `startWithValues`
Creates a Signal from the producer, then adds exactly one observer to
the Signal, which will invoke the given callback when `value` events are
received.

This method is available only if the producer never emits error, or in
other words, has an error type of `Never`.

Returns a Disposable which can be used to interrupt the work associated
with the Signal, and prevent any future callbacks from being invoked.
*/
scopedExample("`startWithValues`") {
	SignalProducer<Int, Never>(value: 42)
		.startWithValues { value in
			print(value)
		}
{'fraction_non_alphanumeric': 0.0939942978018946, 'fraction_numerical': 0.004690517796376345, 'mean_word_length': 4.865156418554477, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 27, 'https://': 8, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5328155', 'n_tokens_mistral': 3195, 'n_tokens_neox': 2962, 'n_words': 1270}