Skip to content

Instantly share code, notes, and snippets.

@sidepelican
sidepelican / concat.swift
Last active June 5, 2024 08:27
resultBuilderと雪だるまジェネリクスで型の組み立て
import Foundation
@dynamicMemberLookup
struct Concat<L: Decodable, R: Decodable>: Decodable {
init(left: L, right: R) {
self.left = left
self.right = right
}
private var left: L
private var right: R
public struct RandomUInt8Sequence: Sequence {
@usableFromInline var count: Int
public init(count: Int) {
self.count = count
}
public func makeIterator() -> Iterator {
Iterator(self)
}
public struct Iterator: IteratorProtocol {
@sidepelican
sidepelican / test.swift
Last active May 23, 2024 00:44
子タスクがキャンセルハンドルしなくても元スコープを抜け出せるtimeout
import Foundation
func brokenTask() async {
await withCheckedContinuation { (c) in
// キャンセルシグナルが握りつぶされていて正しく中断しない処理
Task {
try await Task.sleep(for: .seconds(5))
c.resume()
}
}
@sidepelican
sidepelican / main.swift
Created September 18, 2023 09:33
Taskはキャンセルされても明示的にtry Task.checkCancellation()などで抜けない限り最後まで走り抜ける
import Foundation
func mySleep(seconds: Int) async {
await withCheckedContinuation { c in
DispatchQueue.global().asyncAfter(deadline: .now() + TimeInterval(seconds)) {
c.resume()
}
}
}
@sidepelican
sidepelican / main.swift
Created September 18, 2023 09:08
TaskLocalの引き継ぎはasync letやTask {}では行われる
import Foundation
enum MyValue {
@TaskLocal static var foo: Int = 0
}
func myFunc(@_inheritActorContext _ op: @Sendable @escaping () async -> ()) async {
await withCheckedContinuation { c in
DispatchQueue.global().async {
Task {
@sidepelican
sidepelican / main.swift
Created February 22, 2023 02:18
Task.detachedはTask.initとは別のスレッドプールを持つが、無限に伸びるわけではない
var greeting = "Hello, playground"
print(greeting, ProcessInfo.processInfo.processorCount)
defer {
print(greeting)
}
for i in 0..<30 {
Task.detached {
print("detached", i)
sleep(1)
import Foundation
@propertyWrapper
public struct ThreadLocal<Value> {
private let defaultValue: () -> Value
private let name: String
public init(wrappedValue: @autoclosure @escaping () -> Value) {
self.defaultValue = wrappedValue
self.name = UUID().uuidString

動画の長さに合わせて無音ファイルをカット

$ ffmpeg -ss 0 -i mute30.wav -t 16.45 mute.wav

無音ファイルと動画を結合

$ ffmpeg -i in.mp4 -i mute.wav -vf scale=886:1920,setsar=1:1 out.mp4
@sidepelican
sidepelican / ContentView.swift
Created January 13, 2022 09:12
.task{}のバックポート検討
import SwiftUI
func longlongAsyncFunction() async {
let id = UUID()
print("\(id): start")
do {
try await withTaskCancellationHandler {
try await Task.sleep(nanoseconds: 1000 * 1000 * 1000 * 10)
print("\(id): end")
} onCancel: {
#if !canImport(ObjectiveC)
import Foundation
import XCTest
// INFO:
//typealias XCTestCaseClosure = (XCTestCase) throws -> Void
//typealias XCTestCaseEntry = (testCaseClass: XCTestCase.Type, allTests: [(String, XCTestCaseClosure)])
func testCase<T: XCTestCase>(_ allTests: [(String, (T) -> () async throws -> Void)]) -> XCTestCaseEntry {
let tests: [(String, XCTestCaseClosure)] = allTests.map { ($0.0, asyncTest($0.1)) }
return (T.self, tests)