1/*
2 * Copyright (C) 2013 University of Washington. All rights reserved.
3 * Copyright (C) 2014 Apple Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
15 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
16 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
17 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
18 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
20 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27// A ProbeSet clusters Probes from the same Breakpoint and their samples.
28
29WebInspector.ProbeSet = function(breakpoint)
30{
31    console.assert(breakpoint instanceof WebInspector.Breakpoint, "Unknown breakpoint argument: ", breakpoint);
32
33    WebInspector.Object.call(this);
34    this._breakpoint = breakpoint;
35    this._probes = [];
36    this._probesByIdentifier = new Map;
37
38    this._createDataTable();
39
40    WebInspector.Frame.addEventListener(WebInspector.Frame.Event.MainResourceDidChange, this._mainResourceChanged, this);
41    WebInspector.Probe.addEventListener(WebInspector.Probe.Event.SampleAdded, this._sampleCollected, this);
42    WebInspector.Breakpoint.addEventListener(WebInspector.Breakpoint.Event.ResolvedStateDidChange, this._breakpointResolvedStateDidChange, this);
43}
44
45WebInspector.Object.addConstructorFunctions(WebInspector.ProbeSet);
46
47WebInspector.ProbeSet.Event = {
48    ProbeAdded: "probe-set-probe-added",
49    ProbeRemoved: "probe-set-probe-removed",
50    ResolvedStateDidChange: "probe-set-resolved-state-did-change",
51    SamplesCleared: "probe-set-samples-cleared",
52};
53
54WebInspector.ProbeSet.SampleObjectTitle = "Object";
55
56WebInspector.ProbeSet.prototype = {
57    constructor: WebInspector.ProbeSet,
58    __proto__: WebInspector.Object.prototype,
59
60    // Public
61
62   get breakpoint()
63   {
64        return this._breakpoint;
65   },
66
67    get probes()
68    {
69        return this._probes.slice();
70    },
71
72    get dataTable()
73    {
74        return this._dataTable;
75    },
76
77    clear: function()
78    {
79        this._breakpoint.clearActions(WebInspector.BreakpointAction.Type.Probe);
80    },
81
82    clearSamples: function()
83    {
84        for (var probe of this._probes)
85            probe.clearSamples();
86
87        var oldTable = this._dataTable;
88        this._createDataTable();
89        this.dispatchEventToListeners(WebInspector.ProbeSet.Event.SamplesCleared, {oldTable: oldTable});
90    },
91
92    createProbe: function(expression)
93    {
94        this.breakpoint.createAction(WebInspector.BreakpointAction.Type.Probe, null, expression);
95    },
96
97    addProbe: function(probe)
98    {
99        console.assert(probe instanceof WebInspector.Probe, "Tried to add non-probe ", probe, " to probe group", this);
100        console.assert(probe.breakpoint === this.breakpoint, "Probe and ProbeSet must have same breakpoint.", probe, this);
101
102        this._probes.push(probe);
103        this._probesByIdentifier.set(probe.id, probe);
104
105        this.dataTable.addProbe(probe);
106        this.dispatchEventToListeners(WebInspector.ProbeSet.Event.ProbeAdded, probe);
107    },
108
109    removeProbe: function(probe)
110    {
111        console.assert(probe instanceof WebInspector.Probe, "Tried to remove non-probe ", probe, " to probe group", this);
112        console.assert(this._probes.indexOf(probe) != -1, "Tried to remove probe", probe, " not in group ", this);
113        console.assert(this._probesByIdentifier.has(probe.id), "Tried to remove probe", probe, " not in group ", this);
114
115        this._probes.splice(this._probes.indexOf(probe), 1);
116        this._probesByIdentifier.delete(probe.id);
117        this.dataTable.removeProbe(probe);
118        this.dispatchEventToListeners(WebInspector.ProbeSet.Event.ProbeRemoved, probe);
119    },
120
121    willRemove: function()
122    {
123        console.assert(!this._probes.length, "ProbeSet.willRemove called, but probes still associated with group: ", this._probes);
124
125        WebInspector.Frame.removeEventListener(WebInspector.Frame.Event.MainResourceDidChange, this._mainResourceChanged, this);
126        WebInspector.Probe.removeEventListener(WebInspector.Probe.Event.SampleAdded, this._sampleCollected, this);
127        WebInspector.Breakpoint.removeEventListener(WebInspector.Breakpoint.Event.ResolvedStateDidChange, this._breakpointResolvedStateDidChange, this);
128    },
129
130    // Private
131
132    _mainResourceChanged: function()
133    {
134        this.dataTable.mainResourceChanged();
135    },
136
137    _createDataTable: function()
138    {
139        if (this.dataTable)
140            this.dataTable.willRemove();
141
142        this._dataTable = new WebInspector.ProbeSetDataTable(this);
143    },
144
145    _sampleCollected: function(event)
146    {
147        var sample = event.data;
148        console.assert(sample instanceof WebInspector.ProbeSample, "Tried to add non-sample to probe group: ", sample);
149
150        var probe = event.target;
151        if (!this._probesByIdentifier.has(probe.id))
152            return;
153
154        console.assert(this.dataTable);
155        this.dataTable.addSampleForProbe(probe, sample);
156    },
157
158    _breakpointResolvedStateDidChange: function(event)
159    {
160        this.dispatchEventToListeners(WebInspector.ProbeSet.Event.ResolvedStateDidChange);
161    }
162};
163