idlize

Форк
0
86 строк · 3.2 Кб
1
/*
2
 * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3
 * Licensed under the Apache License, Version 2.0 (the "License");
4
 * you may not use this file except in compliance with the License.
5
 * You may obtain a copy of the License at
6
 *
7
 * http://www.apache.org/licenses/LICENSE-2.0
8
 *
9
 * Unless required by applicable law or agreed to in writing, software
10
 * distributed under the License is distributed on an "AS IS" BASIS,
11
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
 * See the License for the specific language governing permissions and
13
 * limitations under the License.
14
 */
15

16
const SKIP_FRAMES = 10
17

18
/** This interface represents an unique observer that can be notified that some changes. */
19
export interface Dependency {
20
    /** Returns `true` if the dependency is no longer actual. */
21
    readonly obsolete: boolean
22

23
    /** Notifies the dependency that it should be invalidated. */
24
    invalidate(): void
25
}
26

27
/** This class allows to store and update all dependencies. */
28
export class Dependencies {
29
    private frame = 0
30
    private dependencies: Set<Dependency> | undefined = undefined
31
    private latest: Dependency | undefined = undefined
32

33
    /** Returns `true` if there are no dependencies to invalidate. */
34
    get empty(): boolean {
35
        return this.dependencies !== undefined
36
            ? this.dependencies!.size == 0
37
            : this.latest === undefined
38
    }
39

40
    /** @param dependency - a dependency to invalidate */
41
    register(dependency?: Dependency): void {
42
        if (dependency === undefined || dependency == this.latest || dependency.obsolete) return
43
        if (this.dependencies !== undefined) {
44
            this.dependencies!.add(dependency)
45
        } else if (this.latest !== undefined) {
46
            this.dependencies = new Set<Dependency>()
47
            this.dependencies!.add(this.latest!)
48
            this.dependencies!.add(dependency)
49
        }
50
        this.latest = dependency
51
    }
52

53
    /** Invalidates all dependencies and removes obsolete ones. */
54
    updateDependencies(invalidate: boolean): void {
55
        if (++this.frame < SKIP_FRAMES && !invalidate) return
56
        this.frame = 0
57
        if (this.dependencies !== undefined) {
58
            let disposed: Array<Dependency> | undefined = undefined
59
            const it = this.dependencies!.keys()
60
            while (true) {
61
                const result = it.next()
62
                if (result.done) break
63
                const dependency = result.value as Dependency
64
                if (!updateDependency(invalidate, dependency)) {
65
                    if (disposed) {
66
                        disposed.push(dependency)
67
                    } else {
68
                        disposed = Array.of<Dependency>(dependency)
69
                    }
70
                }
71
            }
72
            if (disposed) {
73
                let index = disposed.length
74
                while (0 < index--) this.dependencies!.delete(disposed[index])
75
            }
76
        } else if (this.latest !== undefined && !updateDependency(invalidate, this.latest!)) {
77
            this.latest = undefined
78
        }
79
    }
80
}
81

82
function updateDependency(invalidate: boolean, dependency: Dependency): boolean {
83
    if (dependency.obsolete) return false
84
    if (invalidate) dependency.invalidate()
85
    return true
86
}
87

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.