1 |
|
2 | import {Logger} from "./logger";
|
3 | import {LoggerFactory} from "./logger";
|
4 | import {Utils as _} from './utils';
|
5 | import {Bean} from "./context/context";
|
6 | import {Qualifier} from "./context/context";
|
7 | import {IEventEmitter} from "./interfaces/iEventEmitter";
|
8 | import {GridOptionsWrapper} from "./gridOptionsWrapper";
|
9 | import {AgEvent, Events} from "./events";
|
10 |
|
11 | @Bean('eventService')
|
12 | export class EventService implements IEventEmitter {
|
13 |
|
14 | private allSyncListeners: {[key: string]: Function[]} = {};
|
15 | private allAsyncListeners: {[key: string]: Function[]} = {};
|
16 |
|
17 | private globalSyncListeners: Function[] = [];
|
18 | private globalAsyncListeners: Function[] = [];
|
19 |
|
20 | private logger: Logger;
|
21 |
|
22 | private asyncFunctionsQueue: Function[] = [];
|
23 | private scheduled = false;
|
24 |
|
25 |
|
26 |
|
27 | private static PRIORITY = '-P1';
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 | public setBeans(@Qualifier('loggerFactory') loggerFactory: LoggerFactory,
|
39 | @Qualifier('gridOptionsWrapper') gridOptionsWrapper: GridOptionsWrapper,
|
40 | @Qualifier('globalEventListener') globalEventListener: Function = null) {
|
41 | this.logger = loggerFactory.create('EventService');
|
42 |
|
43 | if (globalEventListener) {
|
44 | let async = gridOptionsWrapper.useAsyncEvents();
|
45 | this.addGlobalListener(globalEventListener, async);
|
46 | }
|
47 | }
|
48 |
|
49 | private getListenerList(eventType: string, async: boolean): Function[] {
|
50 | let listenerMap = async ? this.allAsyncListeners : this.allSyncListeners;
|
51 | let listenerList = listenerMap[eventType];
|
52 | if (!listenerList) {
|
53 | listenerList = [];
|
54 | listenerMap[eventType] = listenerList;
|
55 | }
|
56 | return listenerList;
|
57 | }
|
58 |
|
59 | public addEventListener(eventType: string, listener: Function, async = false): void {
|
60 | let listenerList = this.getListenerList(eventType, async);
|
61 | if (listenerList.indexOf(listener)<0) {
|
62 | listenerList.push(listener);
|
63 | }
|
64 | }
|
65 |
|
66 |
|
67 |
|
68 |
|
69 | public addModalPriorityEventListener(eventType: string, listener: Function, async = false): void {
|
70 | this.addEventListener(eventType + EventService.PRIORITY, listener, async);
|
71 | }
|
72 |
|
73 | public addGlobalListener(listener: Function, async = false): void {
|
74 | if (async) {
|
75 | this.globalAsyncListeners.push(listener);
|
76 | } else {
|
77 | this.globalSyncListeners.push(listener);
|
78 | }
|
79 | }
|
80 |
|
81 | public removeEventListener(eventType: string, listener: Function, async = false): void {
|
82 | let listenerList = this.getListenerList(eventType, async);
|
83 | _.removeFromArray(listenerList, listener);
|
84 | }
|
85 |
|
86 | public removeGlobalListener(listener: Function, async = false): void {
|
87 | if (async) {
|
88 | _.removeFromArray(this.globalAsyncListeners, listener);
|
89 | } else {
|
90 | _.removeFromArray(this.globalSyncListeners, listener);
|
91 | }
|
92 | }
|
93 |
|
94 |
|
95 |
|
96 | public dispatchEvent(event: AgEvent): void {
|
97 |
|
98 | this.dispatchToListeners(event, true);
|
99 | this.dispatchToListeners(event, false);
|
100 | }
|
101 |
|
102 | private dispatchToListeners(event: AgEvent, async: boolean) {
|
103 |
|
104 | let globalListeners = async ? this.globalAsyncListeners : this.globalSyncListeners;
|
105 | let eventType = event.type;
|
106 |
|
107 |
|
108 | let p1ListenerList = this.getListenerList(eventType + EventService.PRIORITY, async);
|
109 | _.forEachSnapshotFirst(p1ListenerList, listener => {
|
110 | if (async) {
|
111 | this.dispatchAsync( () => listener(event) );
|
112 | } else {
|
113 | listener(event);
|
114 | }
|
115 | });
|
116 |
|
117 | let listenerList = this.getListenerList(eventType, async);
|
118 | _.forEachSnapshotFirst(listenerList,listener => {
|
119 | if (async) {
|
120 | this.dispatchAsync( () => listener(event) );
|
121 | } else {
|
122 | listener(event);
|
123 | }
|
124 | });
|
125 |
|
126 | _.forEachSnapshotFirst(globalListeners, listener => {
|
127 | if (async) {
|
128 | this.dispatchAsync( () => listener(eventType, event) );
|
129 | } else {
|
130 | listener(eventType, event);
|
131 | }
|
132 | });
|
133 | }
|
134 |
|
135 |
|
136 |
|
137 |
|
138 |
|
139 | private dispatchAsync(func: Function): void {
|
140 |
|
141 |
|
142 | this.asyncFunctionsQueue.push(func);
|
143 |
|
144 |
|
145 |
|
146 |
|
147 |
|
148 | if (!this.scheduled) {
|
149 |
|
150 | setTimeout(this.flushAsyncQueue.bind(this), 0);
|
151 |
|
152 | this.scheduled = true;
|
153 | }
|
154 | }
|
155 |
|
156 |
|
157 | private flushAsyncQueue(): void {
|
158 | this.scheduled = false;
|
159 |
|
160 |
|
161 |
|
162 |
|
163 |
|
164 |
|
165 | let queueCopy = this.asyncFunctionsQueue.slice();
|
166 | this.asyncFunctionsQueue = [];
|
167 |
|
168 |
|
169 | queueCopy.forEach( func => func() );
|
170 | }
|
171 | }
|