1 | import {extend} from './utils/objects'
|
2 | import {VALUE, ERROR, ANY} from './constants'
|
3 | import {concat, findByPred, remove, contains} from './utils/collections'
|
4 |
|
5 | function callSubscriber(type, fn, event) {
|
6 | if (type === ANY) {
|
7 | fn(event)
|
8 | } else if (type === event.type) {
|
9 | if (type === VALUE || type === ERROR) {
|
10 | fn(event.value)
|
11 | } else {
|
12 | fn()
|
13 | }
|
14 | }
|
15 | }
|
16 |
|
17 | function Dispatcher() {
|
18 | this._items = []
|
19 | this._spies = []
|
20 | this._inLoop = 0
|
21 | this._removedItems = null
|
22 | }
|
23 |
|
24 | extend(Dispatcher.prototype, {
|
25 | add(type, fn) {
|
26 | this._items = concat(this._items, [{type, fn}])
|
27 | return this._items.length
|
28 | },
|
29 |
|
30 | remove(type, fn) {
|
31 | const index = findByPred(this._items, x => x.type === type && x.fn === fn)
|
32 |
|
33 |
|
34 |
|
35 | if (this._inLoop !== 0 && index !== -1) {
|
36 | if (this._removedItems === null) {
|
37 | this._removedItems = []
|
38 | }
|
39 | this._removedItems.push(this._items[index])
|
40 | }
|
41 |
|
42 | this._items = remove(this._items, index)
|
43 | return this._items.length
|
44 | },
|
45 |
|
46 | addSpy(fn) {
|
47 | this._spies = concat(this._spies, [fn])
|
48 | return this._spies.length
|
49 | },
|
50 |
|
51 |
|
52 |
|
53 |
|
54 | removeSpy(fn) {
|
55 | this._spies = remove(this._spies, this._spies.indexOf(fn))
|
56 | return this._spies.length
|
57 | },
|
58 |
|
59 | dispatch(event) {
|
60 | this._inLoop++
|
61 | for (let i = 0, spies = this._spies; this._spies !== null && i < spies.length; i++) {
|
62 | spies[i](event)
|
63 | }
|
64 |
|
65 | for (let i = 0, items = this._items; i < items.length; i++) {
|
66 |
|
67 | if (this._items === null) {
|
68 | break
|
69 | }
|
70 |
|
71 |
|
72 | if (this._removedItems !== null && contains(this._removedItems, items[i])) {
|
73 | continue
|
74 | }
|
75 |
|
76 | callSubscriber(items[i].type, items[i].fn, event)
|
77 | }
|
78 | this._inLoop--
|
79 | if (this._inLoop === 0) {
|
80 | this._removedItems = null
|
81 | }
|
82 | },
|
83 |
|
84 | cleanup() {
|
85 | this._items = null
|
86 | this._spies = null
|
87 | },
|
88 | })
|
89 |
|
90 | export {callSubscriber, Dispatcher}
|