Skip to content

Commit 10f2a93

Browse files
committed
Add DebounceFunction and ThrottleFunction
1 parent 250bdf9 commit 10f2a93

File tree

4 files changed

+66
-15
lines changed

4 files changed

+66
-15
lines changed

Pro

Submodule Pro updated from 8c9ccfa to 39b2b44

Tool/Package.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ let package = Package(
4242
]
4343
),
4444
.library(name: "GitIgnoreCheck", targets: ["GitIgnoreCheck"]),
45+
.library(name: "DebounceFunction", targets: ["DebounceFunction"]),
4546
],
4647
dependencies: [
4748
// A fork of https://github.com/aespinilla/Tiktoken to allow loading from local files.
@@ -102,6 +103,8 @@ let package = Package(
102103
)]
103104
),
104105

106+
.target(name: "DebounceFunction"),
107+
105108
.target(
106109
name: "AppActivator",
107110
dependencies: [
Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,22 @@
1-
//
2-
// File.swift
3-
//
4-
//
5-
// Created by Shangxin Guo on 2024/2/15.
6-
//
7-
81
import Foundation
2+
3+
public actor DebounceFunction<T> {
4+
let duration: TimeInterval
5+
let block: (T) async -> Void
6+
7+
var task: Task<Void, Error>?
8+
9+
public init(duration: TimeInterval, block: @escaping (T) async -> Void) {
10+
self.duration = duration
11+
self.block = block
12+
}
13+
14+
public func callAsFunction(_ t: T) async {
15+
task?.cancel()
16+
task = Task { [block, duration] in
17+
try await Task.sleep(nanoseconds: UInt64(duration * 1_000_000_000))
18+
await block(t)
19+
}
20+
}
21+
}
22+
Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,42 @@
1-
//
2-
// File.swift
3-
//
4-
//
5-
// Created by Shangxin Guo on 2024/2/15.
6-
//
7-
81
import Foundation
2+
3+
public actor ThrottleFunction<T> {
4+
let duration: TimeInterval
5+
let block: (T) async -> Void
6+
7+
var task: Task<Void, Error>?
8+
var lastFinishTime: Date = .init(timeIntervalSince1970: 0)
9+
var now: () -> Date = { Date() }
10+
11+
public init(duration: TimeInterval, block: @escaping (T) async -> Void) {
12+
self.duration = duration
13+
self.block = block
14+
}
15+
16+
public func callAsFunction(_ t: T) async {
17+
if task == nil {
18+
scheduleTask(t, wait: now().timeIntervalSince(lastFinishTime) < duration)
19+
}
20+
}
21+
22+
func scheduleTask(_ t: T, wait: Bool) {
23+
task = Task.detached { [weak self] in
24+
guard let self else { return }
25+
do {
26+
if wait {
27+
try await Task.sleep(nanoseconds: UInt64(duration * 1_000_000_000))
28+
}
29+
await block(t)
30+
await finishTask()
31+
} catch {
32+
await finishTask()
33+
}
34+
}
35+
}
36+
37+
func finishTask() {
38+
task = nil
39+
lastFinishTime = now()
40+
}
41+
}
42+

0 commit comments

Comments
 (0)