Skip to content

Commit 0242075

Browse files
author
robot-divkit
committedOct 11, 2022
Release 10.0.0
Release 10.0.0
1 parent 6ca6ce2 commit 0242075

File tree

8 files changed

+466
-76
lines changed

8 files changed

+466
-76
lines changed
 

‎Core/BaseTiny/Atomic.swift

+4-11
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,20 @@ import Foundation
44

55
public final class Atomic<T> {
66
private var unsafeValue: T
7-
private let queue: DispatchQueue
7+
private let lock = RWLock()
88

9-
public init(initialValue: T, accessQueue: DispatchQueue) {
9+
public init(initialValue: T) {
1010
unsafeValue = initialValue
11-
queue = accessQueue
12-
}
13-
14-
@inlinable
15-
public convenience init(initialValue: T, label: String) {
16-
let accessQueue = DispatchQueue(label: label, attributes: [.concurrent])
17-
self.init(initialValue: initialValue, accessQueue: accessQueue)
1811
}
1912

2013
public func accessRead<U>(_ block: (T) throws -> U) rethrows -> U {
21-
try queue.sync {
14+
try lock.read {
2215
try block(unsafeValue)
2316
}
2417
}
2518

2619
public func accessWrite<U>(_ block: (inout T) throws -> U) rethrows -> U {
27-
try queue.sync(flags: .barrier) {
20+
try lock.write {
2821
try block(&unsafeValue)
2922
}
3023
}

‎Core/BaseTiny/Memoization.swift

+7-8
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import Foundation
44

5-
private let accessQueue = DispatchQueue(label: "Memoization queue", attributes: [.concurrent])
65
private let assignmentQueue = DispatchQueue(
76
label: "Memoization optimization assignment (for classes)",
87
attributes: [.concurrent]
@@ -22,14 +21,14 @@ private func cachedValue<A, B>(
2221
}
2322

2423
public func memoize<A: Hashable, B>(_ f: @escaping (A) throws -> B) -> (A) throws -> B {
25-
let cache = Atomic(initialValue: [A: B](), accessQueue: accessQueue)
24+
let cache = Atomic(initialValue: [A: B]())
2625
return { (input: A) -> B in
2726
try cachedValue(from: cache, for: input, fallback: f)
2827
}
2928
}
3029

3130
public func memoize<A: Hashable, B>(_ f: @escaping (A) -> B) -> (A) -> B {
32-
let cache = Atomic(initialValue: [A: B](), accessQueue: accessQueue)
31+
let cache = Atomic(initialValue: [A: B]())
3332
return { (input: A) -> B in
3433
cachedValue(from: cache, for: input, fallback: f)
3534
}
@@ -41,7 +40,7 @@ private struct MemoizeParams2<A: Hashable, B: Hashable>: Hashable {
4140
}
4241

4342
public func memoize<A: Hashable, B: Hashable, C>(_ f: @escaping (A, B) -> C) -> (A, B) -> C {
44-
let cache = Atomic(initialValue: [MemoizeParams2<A, B>: C](), accessQueue: accessQueue)
43+
let cache = Atomic(initialValue: [MemoizeParams2<A, B>: C]())
4544
return { (a: A, b: B) -> C in
4645
cachedValue(from: cache, for: MemoizeParams2(a: a, b: b), fallback: { f($0.a, $0.b) })
4746
}
@@ -73,9 +72,9 @@ private class MemoizeParams3AClass<A: Hashable, B: Hashable, C: Hashable>: Hasha
7372

7473
static func ==(lhs: MemoizeParams3AClass, rhs: MemoizeParams3AClass) -> Bool {
7574
// This 🦃 performs a very specific optimization for the case when
76-
// we put the calculcations for the specific string (which has reference type) to the cache,
75+
// we put the calculations for the specific string (which has reference type) to the cache,
7776
// but _sometimes_ we re-create the instance of this string. Thus, if we don't modify
78-
// dictionary key, we'll always miss comparation by reference.
77+
// dictionary key, we'll always miss comparison by reference.
7978
// Here we rely on the implementation detail of Dictionary, namely we hope that
8079
// `lhs` corresponds to the key _already contained_ in dictionary and `rhs` corresponds
8180
// to the key by which we're trying to get the value.
@@ -96,7 +95,7 @@ public func memoize<
9695
C: Hashable,
9796
D
9897
>(_ f: @escaping (A, B, C) -> D) -> (A, B, C) -> D {
99-
let cache = Atomic(initialValue: [MemoizeParams3<A, B, C>: D](), accessQueue: accessQueue)
98+
let cache = Atomic(initialValue: [MemoizeParams3<A, B, C>: D]())
10099
return { (a: A, b: B, c: C) -> D in
101100
cachedValue(
102101
from: cache,
@@ -112,7 +111,7 @@ public func memoizeAClass<
112111
C: Hashable,
113112
D
114113
>(_ f: @escaping (A, B, C) -> D) -> (A, B, C) -> D where A: AnyObject {
115-
let cache = Atomic(initialValue: [MemoizeParams3AClass<A, B, C>: D](), accessQueue: accessQueue)
114+
let cache = Atomic(initialValue: [MemoizeParams3AClass<A, B, C>: D]())
116115
return { (a: A, b: B, c: C) -> D in
117116
cachedValue(
118117
from: cache,

‎Core/Base/RWLock.swift ‎Core/BaseTiny/RWLock.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ public final class RWLock {
1313
pthread_rwlock_destroy(&lock)
1414
}
1515

16-
public func read<T>(_ block: () -> T) -> T {
16+
public func read<T>(_ block: () throws -> T) rethrows -> T {
1717
pthread_rwlock_rdlock(&lock)
1818
defer { pthread_rwlock_unlock(&lock) }
19-
return block()
19+
return try block()
2020
}
2121

22-
public func write<T>(_ block: () -> T) -> T {
22+
public func write<T>(_ block: () throws -> T) rethrows -> T {
2323
pthread_rwlock_wrlock(&lock)
2424
defer { pthread_rwlock_unlock(&lock) }
25-
return block()
25+
return try block()
2626
}
2727
}

‎Core/CommonCore/Theme.swift

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// Copyright 2021 Yandex LLC. All rights reserved.
22

3-
import BaseTiny
43
import BaseUI
54

65
public enum Theme: String {

‎DivKit/DivKitInfo.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
public enum DivKitInfo {
2-
public static let version = "9.0.0"
2+
public static let version = "10.0.0"
33
}

‎DivKit/Extensions/ArrayExtensions.swift

+9-3
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,15 @@ extension Array where Element == Div {
77
mappedBy modificator: (Div, Block) throws -> T
88
) throws -> [T] {
99
try iterativeFlatMap { div, index in
10-
let divContext = modified(context) { $0.parentPath += index }
11-
let block = try? div.value.makeBlock(context: divContext)
12-
return try block.map { try modificator(div, $0) }
10+
let itemContext = modified(context) { $0.parentPath += index }
11+
let block: Block
12+
do {
13+
block = try div.value.makeBlock(context: itemContext)
14+
} catch {
15+
DivKitLogger.error("Failed to create block: \(error)")
16+
return nil
17+
}
18+
return try modificator(div, block)
1319
}
1420
}
1521

‎DivKitExtensions/Lottie/LottieExtensionHandler.swift

+35-48
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,14 @@ public final class LottieExtensionHandler: DivExtensionHandler {
2727
div: DivBase,
2828
context: DivBlockModelingContext
2929
) -> Block {
30-
let extensionParams = div.extensions?
31-
.first(where: { $0.id == self.id })
32-
guard let extensionParams = extensionParams?.params,
33-
let lottieValue = LottieValues(
34-
params: extensionParams
35-
) else { return block }
30+
let extensionData = div.extensions?.first { $0.id == id }
31+
guard let paramsDict = extensionData?.params,
32+
let params = LottieExtensionParams(params: paramsDict) else {
33+
return block
34+
}
3635

3736
let animationHolder: AnimationHolder
38-
switch lottieValue.source {
37+
switch params.source {
3938
case let .url(url):
4039
animationHolder = RemoteAnimationHolder(
4140
url: url,
@@ -49,8 +48,8 @@ public final class LottieExtensionHandler: DivExtensionHandler {
4948
animatableView: Lazy(
5049
getter: {
5150
self.factory.createAnimatableView(
52-
withMode: lottieValue.repeatMode.repeateMode,
53-
repeatCount: lottieValue.repeatCount
51+
withMode: params.repeatMode,
52+
repeatCount: params.repeatCount
5453
)
5554
}
5655
),
@@ -61,25 +60,16 @@ public final class LottieExtensionHandler: DivExtensionHandler {
6160
}
6261
}
6362

64-
extension LottieValues.RepeatMode {
65-
var repeateMode: AnimationRepeatMode {
66-
switch self {
67-
case .reverse:
68-
return .reverse
69-
case .restart:
70-
return .restart
71-
}
72-
}
73-
}
74-
7563
private class JSONAnimationHolder: AnimationHolder {
7664
let animation: AnimationSourceType?
7765

7866
init(json: [String: Any]) {
7967
self.animation = .json(json)
8068
}
8169

82-
func requestAnimationWithCompletion(_ completion: @escaping (AnimationSourceType?) -> Void) -> Cancellable? {
70+
func requestAnimationWithCompletion(
71+
_ completion: @escaping (AnimationSourceType?) -> Void
72+
) -> Cancellable? {
8373
completion(animation)
8474
return nil
8575
}
@@ -97,53 +87,50 @@ private class JSONAnimationHolder: AnimationHolder {
9787
}
9888
}
9989

100-
private struct LottieValues {
101-
enum ValuesError: String, Error {
102-
case notValidJSONOrURL
103-
case notValidRepeatCount
104-
case notValidRepeatMode
105-
}
106-
90+
private struct LottieExtensionParams {
10791
enum Source {
10892
case json([String: Any])
10993
case url(URL)
11094
}
11195

112-
enum RepeatMode: String {
113-
case reverse
114-
case restart
115-
}
116-
11796
var source: Source
11897
var repeatCount: Float
119-
var repeatMode: RepeatMode
98+
var repeatMode: AnimationRepeatMode
12099

121100
init?(params: [String: Any]) {
122101
if let json = params["lottie_json"] as? [String: Any] {
123102
source = .json(json)
124-
} else if let urlString = params["lottie_url"] as? String, let url = URL(string: urlString) {
103+
} else if let urlString = params["lottie_url"] as? String,
104+
let url = URL(string: urlString) {
125105
source = .url(url)
126106
} else {
127107
DivKitLogger.error("Not valid lottie_json or lottie_url")
128108
return nil
129109
}
130110

131-
if let repeatCount = params["repeat_count"] as? Float {
132-
self.repeatCount = repeatCount
111+
if let repeatCount = params["repeat_count"] {
112+
if let repeatCountFloat = repeatCount as? Float {
113+
self.repeatCount = repeatCountFloat
114+
} else {
115+
DivKitLogger.error("Not valid repeat_count")
116+
return nil
117+
}
133118
} else {
134-
DivKitLogger.error("Not valid repeat_count")
135-
return nil
119+
self.repeatCount = 0
136120
}
137-
138-
let repeatModeString = params["repeat_mode"] as? String
139-
switch repeatModeString {
140-
case "reverse":
141-
self.repeatMode = .reverse
142-
case "restart":
121+
122+
if let repeatMode = params["repeat_mode"] {
123+
switch repeatMode as? String {
124+
case "reverse":
125+
self.repeatMode = .reverse
126+
case "restart":
127+
self.repeatMode = .restart
128+
default:
129+
DivKitLogger.error("Not valid repeat_mode")
130+
return nil
131+
}
132+
} else {
143133
self.repeatMode = .restart
144-
default:
145-
DivKitLogger.error("Not valid repeat_mode")
146-
return nil
147134
}
148135
}
149136
}

‎LICENSE

+406
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.