Skip to content

Instantly share code, notes, and snippets.

@jscalo
jscalo / ToiletLidSim.swift
Created March 13, 2022 18:31
Simulation that shows how often a public toilet lid needs to be touched based on different "policies".
import Foundation
enum Gender {
case female, male
static func random() -> Gender {
return Int.random(in: 0...1) == 0 ? .female : .male
}
}
private var firstSampleToPlotIdx: Int {
get {
let idx = Int(-viewPort.xTrans * viewPort.screenScale)
return (0..<dataProvider.summarySampleCnt).clamp(idx)
}
}
private var samplesToPlotInVisibleCnt: Int {
get {
return viewPort.visibleXAxisUnits
func update() {
guard viewPort != nil else { return }
guard dataProvider != nil else { return }
prepare()
updateMidline()
updatePlot()
}
@objc func pinchGesture(_ gc: UIPinchGestureRecognizer) {
switch gc.state {
case .changed:
pauseUpdates = true
scrollView.recenterForScale(gc.scale)
pauseUpdates = false
let newScale = viewPort.zoom * gc.scale
viewPort.zoom = max(newScale, 1.0)
gc.scale = 1.0
case .ended, .cancelled, .failed:
override func layoutSubviews() {
super.layoutSubviews()
let scale = bounds.width / lastBounds.width
scrollView.recenterForScale(scale)
lastBounds = bounds
updateScrollViewSize()
update()
}
private func updateScrollViewSize() {
scrollView.contentSize =
CGSize(width: bounds.width * viewPort.zoom,
height: bounds.height)
}
private func viewPortZoomed() {
dataProvider?.summarySamples = nil
updateScrollViewSize()
CATransaction.begin()
CATransaction.setDisableActions(true)
update()
CATransaction.commit()
}
private var firstSampleToPlotIdx: Int {
get {
let idx = Int(-viewPort.xTrans * UIScreen.main.scale)
return (0..<dataProvider.summarySampleCnt).clamp(idx)
}
}
private func updateLines(samples: [Float], yMidline: CGFloat) {
let maxSampleMagnitude = max(dataProvider.summarySampleMax, -(dataProvider.summarySampleMin), Float.leastNonzeroMagnitude)
let yScalingFactor = bounds.height / 2 / CGFloat(maxSampleMagnitude)
var xPos: CGFloat = 0
let cnt = samples.count
var idx = 0
let visibleDur = dataProvider.duration / Double(viewPort.zoom)
let startTime = (Double(viewPort.startingXUnit) / Double(viewPort.xAxisUnits)) * dataProvider.duration
//
// John Scalo
// CloudKitExtras.swift
//
import CloudKit
var ckLogging = true
let ckBatchLimit = 400
let usleepInterval: UInt32 = 500000