-
Notifications
You must be signed in to change notification settings - Fork 208
/
UiEventDispatcher.ts
158 lines (141 loc) · 5.42 KB
/
UiEventDispatcher.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
* @module Utilities
*/
import { BeUiEvent } from "@itwin/core-bentley";
/** UiSync Event arguments. Contains a set of lower case event Ids.
* @public
* @deprecated in 4.2.x Please use [[UiSyncEventArgs]] in @itwin/appui-react
*/
export interface UiSyncEventArgs {
eventIds: Set<string>;
}
/** UiSync Event class.
* @public
* @deprecated in 4.2.x Use [[UiSyncEvent]] from @itwin/appui-react.
*/
// eslint-disable-next-line deprecation/deprecation
export class UiSyncEvent extends BeUiEvent<UiSyncEventArgs> { }
/** This class is used to send eventIds to interested UI components so the component can determine if it needs
* to refresh its display by calling setState on itself.
* @public
* @deprecated in 4.2.x Use [[SyncUiEventDispatcher]] from @itwin/appui-react.
*/
export class UiEventDispatcher {
private _syncEventTimerId: number | undefined;
private _eventIds: Set<string>;
private _eventIdAdded;
// eslint-disable-next-line deprecation/deprecation
private _uiSyncEvent: UiSyncEvent;
private _timeoutPeriod;
private _secondaryTimeoutPeriod;
constructor() {
this._eventIds = new Set<string>();
this._eventIdAdded = false;
// eslint-disable-next-line deprecation/deprecation
this._uiSyncEvent = new UiSyncEvent();
this._timeoutPeriod = 100;
this._secondaryTimeoutPeriod = this._timeoutPeriod / 2;
}
/** @internal - used for testing only */
/* istanbul ignore next */
public setTimeoutPeriod(period: number): void {
this._timeoutPeriod = period;
this._secondaryTimeoutPeriod = Math.floor(this._timeoutPeriod / 2);
if (this._secondaryTimeoutPeriod < 1)
this._secondaryTimeoutPeriod = 1;
if (this._syncEventTimerId) {
window.clearTimeout(this._syncEventTimerId);
this._syncEventTimerId = undefined;
}
if (this._eventIds)
this._eventIds.clear();
this._eventIdAdded = false;
}
/** The current timeout period */
public get timeoutPeriod(): number {
return this._timeoutPeriod;
}
/** Return set of event ids that will be sent to listeners/. */
public get syncEventIds(): Set<string> {
return this._eventIds;
}
/** Return UiSyncEvent so callers can register an event callback. */
// eslint-disable-next-line deprecation/deprecation
public get onSyncUiEvent(): UiSyncEvent {
return this._uiSyncEvent;
}
/** Immediately trigger sync event processing. */
public dispatchImmediateSyncUiEvent(eventId: string): void {
const eventIds = new Set<string>();
eventIds.add(eventId.toLowerCase());
this.onSyncUiEvent.emit({ eventIds });
}
/** Save eventId in Set for processing. */
public dispatchSyncUiEvent(eventId: string): void {
// istanbul ignore if
if (0 === this._timeoutPeriod) {
return;
}
this.syncEventIds.add(eventId.toLowerCase());
if (!this._syncEventTimerId) { // if there is not a timer active, create one
this._syncEventTimerId = window.setTimeout(() => { this.checkForAdditionalIds(); }, this._timeoutPeriod);
} else {
this._eventIdAdded = true;
}
}
/** Save multiple eventIds in Set for processing. */
public dispatchSyncUiEvents(eventIds: string[]): void {
// istanbul ignore if
if (0 === this._timeoutPeriod) {
return;
}
eventIds.forEach((id) => this.syncEventIds.add(id.toLowerCase()));
// istanbul ignore else
if (!this._syncEventTimerId) { // if there is not a timer active, create one
this._syncEventTimerId = window.setTimeout(() => { this.checkForAdditionalIds(); }, this._timeoutPeriod);
} else {
this._eventIdAdded = true;
}
}
/** Trigger registered event processing when timer has expired and no addition eventId are added. */
public checkForAdditionalIds() {
/* istanbul ignore else */
if (!this._eventIdAdded) {
// istanbul ignore else
if (this._syncEventTimerId) {
window.clearTimeout(this._syncEventTimerId);
this._syncEventTimerId = undefined;
}
this._eventIdAdded = false;
// istanbul ignore else
if (this.syncEventIds.size > 0) {
const eventIds = new Set<string>();
this.syncEventIds.forEach((value) => eventIds.add(value));
this._eventIds.clear();
this.onSyncUiEvent.emit({ eventIds });
}
return;
}
// istanbul ignore next
if (this._syncEventTimerId) {
window.clearTimeout(this._syncEventTimerId);
this._syncEventTimerId = undefined;
}
// istanbul ignore next
this._eventIdAdded = false;
// if events have been added before the initial timer expired wait half that time to see if events are still being added.
// istanbul ignore next
this._syncEventTimerId = window.setTimeout(() => { this.checkForAdditionalIds(); }, this._secondaryTimeoutPeriod);
}
/** Checks to see if an eventId of interest is contained in the set of eventIds */
public hasEventOfInterest(eventIds: Set<string>, idsOfInterest: string[]) {
/* istanbul ignore else */
if ((idsOfInterest.length > 0) && idsOfInterest.some((value: string): boolean => eventIds.has(value.toLowerCase())))
return true;
return false;
}
}