summaryrefslogtreecommitdiff
path: root/scripts/lib/signals.js
blob: 25eebede78adbd080f3ef92decec810686e65c4f (plain)
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
(function ()  
{
    var _registered = {};
    var _blocked = false;
    var _pending = [];
    function _disconnect(sig) 
    {
        signals[sig] = null;
        delete _registered[sig];
    }
    var _disconnectByProp = function(prop, obj) 
    {
        var sig, i, sigs;
        if (_blocked)
        {
            _pending.push({prop : prop, obj : obj});
            return;
        }
        for (sig in _registered) 
        {
            sigs = _registered[sig];
            for (i = 0; i<sigs.length; i++) 
            {
                if (sigs[i][prop] == obj) 
                {
                    if (_registered[sig].length === 1) 
                    {
                        _disconnect(sig);
                    }
                    else 
                    {
                        sigs.splice(i, 1);
                    }
                    return;
                }
            }
        }
    };
    Object.defineProperties(signals, 
    {
        "emit" : 
        {
            value : function(sig, args) 
            {
                var sigs = _registered[sig];
                var currentSig, pending;
                var ret = false;
                var i, l;
                _blocked = true;
                for (i=0, l=sigs.length; i<l; i++)
                {
                    currentSig = sigs[i];
                    ret = currentSig.callback.apply(currentSig.callback, args) || ret;
                } 
                _blocked = false;
                if (_pending.length > 0)
                {
                    for (i=_pending.length-1; i>=0; --i)
                    {
                        pending = _pending[i];
                        _disconnectByProp(pending.prop, pending.obj);
                    }
                    _pending = [];
                }
                return ret;
            }
        },
        "connect" : 
        {
            value : (function () 
            {
                var id = 0;
                return function(sig, func) 
                {
                    if (func === null || typeof func !== "function") 
                    {
                        return -1;
                    }
                    ++id;
                    if (_registered[sig] === undefined || _registered[sig] === null) 
                    {
                        _registered[sig] = [];
                        signals[sig] = function () { return signals.emit(sig, arguments); };
                    }
                    _registered[sig].push({ callback : func, id : id });
                    return id;
                };
            })()
        },
        "connectWebView" :
        {
            value : function(name, callback)
            {
                this.connect("createTab", function(wv) {
                    wv.connect(name, function() { callback.apply(callback, arguments);});
                });
            }
        },
        "disconnect" : 
        {
            value : function(obj) {
                if (typeof obj == "function")
                    _disconnectByProp("callback", obj);
                else 
                    _disconnectByProp("id", obj);

            }
        },
        "disconnectByName" : 
        {
            value : function (name) 
            {
                if (signals[name] !== null && signals[name] !== undefined) 
                {
                    _disconnect(name);
                    return true;
                }
                return false;
            }
        }
    });
})();