Skip to content

Instantly share code, notes, and snippets.

@NinoScript
Created March 23, 2017 20:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NinoScript/046a7a17d30e98bac80086ead94ffb4a to your computer and use it in GitHub Desktop.
Save NinoScript/046a7a17d30e98bac80086ead94ffb4a to your computer and use it in GitHub Desktop.
D3.js-like enter and exit functions for ReactiveSwift
//
// SignalProducer+D3.swift
//
// Created by Cristián Arenas Ulloa on 3/23/17.
// WTFPLv2
//
// This overcomplicated tool fits my use case.
// It will probably make a lot of sense to you too if you've ever used D3.js.
// There was probably an easier way to do it,
// but I'm just learning ReactiveSwift so don't hate me .
//
import ReactiveSwift
extension SignalProducer {
/// Observe entering and exiting values (see D3.js)
///
/// - parameters:
/// - onEnter: A closure that is invoked when a new value is emitted.
/// - onExit: A closure that is invoked after the last value is gone.
public func observeValues(
onEnter: ((Value) -> Void)? = nil,
onExit: ((Value) -> Void)? = nil
) {
take(first: 1).on(value: onEnter).start()
take(last: 1).on(value: onExit).start()
transitions().on(value: tupleFunctions(onExit, onEnter)).start()
}
/// Zip elements of the same producer into pairs. The elements of any Nth pair
/// are the (N-1)th element and the Nth element of the producer.
/// The tuples represent the transition from the last value to the current value.
///
/// - returns: A producer that sends tuples of the last value and the current value.
public func transitions() -> SignalProducer<(Value, Value), Error> {
return zip(with: skip(first: 1))
}
}
/// Mix two single parameter functions to get one that acts on tuples
public func tupleFunctions<A, B>(
_ a: ((A) -> Void)?,
_ b: ((B) -> Void)?
) -> ((A, B) -> Void) {
return { va, vb in
a?(va)
b?(vb)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment