Upstream version 9.37.197.0
[platform/framework/web/crosswalk.git] / src / third_party / trace-viewer / trace_viewer / tracing / selection.js
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 'use strict';
6
7 /**
8  * @fileoverview Code for the viewport.
9  */
10 tvcm.require('tvcm.events');
11 tvcm.require('tvcm.guid');
12 tvcm.require('tvcm.range');
13 tvcm.require('tracing.trace_model.instant_event');
14 tvcm.require('tracing.trace_model.flow_event');
15 tvcm.require('tracing.trace_model');
16
17 tvcm.exportTo('tracing', function() {
18
19   var RequestSelectionChangeEvent = tvcm.Event.bind(
20       undefined, 'requestSelectionChange', true, false);
21
22   var EVENT_TYPES = [
23     {
24       constructor: tracing.trace_model.Slice,
25       name: 'slice',
26       pluralName: 'slices'
27     },
28     {
29       constructor: tracing.trace_model.InstantEvent,
30       name: 'instantEvent',
31       pluralName: 'instantEvents'
32     },
33     {
34       constructor: tracing.trace_model.CounterSample,
35       name: 'counterSample',
36       pluralName: 'counterSamples'
37     },
38     {
39       constructor: tracing.trace_model.ObjectSnapshot,
40       name: 'objectSnapshot',
41       pluralName: 'objectSnapshots'
42     },
43     {
44       constructor: tracing.trace_model.ObjectInstance,
45       name: 'objectInstance',
46       pluralName: 'objectInstances'
47     },
48     {
49       constructor: tracing.trace_model.Sample,
50       name: 'sample',
51       pluralName: 'samples'
52     },
53     {
54       constructor: tracing.trace_model.FlowEvent,
55       name: 'flowEvent',
56       pluralName: 'flowEvents'
57     }
58   ];
59
60   /**
61    * Represents a selection within a  and its associated set of tracks.
62    * @constructor
63    */
64   function Selection(opt_events) {
65     this.bounds_dirty_ = true;
66     this.bounds_ = new tvcm.Range();
67     this.length_ = 0;
68     this.guid_ = tvcm.GUID.allocate();
69
70     if (opt_events) {
71       for (var i = 0; i < opt_events.length; i++)
72         this.push(opt_events[i]);
73     }
74   }
75   Selection.prototype = {
76     __proto__: Object.prototype,
77
78     get bounds() {
79       if (this.bounds_dirty_) {
80         this.bounds_.reset();
81         for (var i = 0; i < this.length_; i++)
82           this[i].addBoundsToRange(this.bounds_);
83         this.bounds_dirty_ = false;
84       }
85       return this.bounds_;
86     },
87
88     get duration() {
89       if (this.bounds_.isEmpty)
90         return 0;
91       return this.bounds_.max - this.bounds_.min;
92     },
93
94     get length() {
95       return this.length_;
96     },
97
98     get guid() {
99       return this.guid_;
100     },
101
102     clear: function() {
103       for (var i = 0; i < this.length_; ++i)
104         delete this[i];
105       this.length_ = 0;
106       this.bounds_dirty_ = true;
107     },
108
109     push: function(event) {
110       this[this.length_++] = event;
111       this.bounds_dirty_ = true;
112       return event;
113     },
114
115     addSelection: function(selection) {
116       for (var i = 0; i < selection.length; i++)
117         this.push(selection[i]);
118     },
119
120     subSelection: function(index, count) {
121       count = count || 1;
122
123       var selection = new Selection();
124       selection.bounds_dirty_ = true;
125       if (index < 0 || index + count > this.length_)
126         throw new Error('Index out of bounds');
127
128       for (var i = index; i < index + count; i++)
129         selection.push(this[i]);
130
131       return selection;
132     },
133
134     getEventsOrganizedByType: function() {
135       var events = {};
136       EVENT_TYPES.forEach(function(eventType) {
137         events[eventType.pluralName] = new Selection();
138       });
139       for (var i = 0; i < this.length_; i++) {
140         var event = this[i];
141         EVENT_TYPES.forEach(function(eventType) {
142           if (event instanceof eventType.constructor)
143             events[eventType.pluralName].push(event);
144         });
145       }
146       return events;
147     },
148
149     enumEventsOfType: function(type, func) {
150       for (var i = 0; i < this.length_; i++)
151         if (this[i] instanceof type)
152           func(this[i]);
153     },
154
155     map: function(fn) {
156       for (var i = 0; i < this.length_; i++)
157         fn(this[i]);
158     },
159
160     /**
161      * Helper for selection previous or next.
162      * @param {boolean} offset If positive, select one forward (next).
163      *   Else, select previous.
164      *
165      * @param {TimelineViewport} viewport The viewport to use to determine what
166      * is near to the current selection.
167      *
168      * @return {boolean} true if current selection changed.
169      */
170     getShiftedSelection: function(viewport, offset) {
171       var newSelection = new Selection();
172       for (var i = 0; i < this.length_; i++) {
173         var event = this[i];
174
175         var addEventToNewSelection = function(event) {
176         };
177
178         // If this is a flow event, and we have a next/prev item in the chain
179         // then we use that as the item to move too. Otherwise, we let the
180         // normal movement for a slice kick in and use that.
181         if (event instanceof tracing.trace_model.FlowEvent) {
182           if ((offset > 0) && event.nextFlowEvent) {
183             newSelection.push(event.nextFlowEvent);
184             continue;
185           } else if ((offset < 0) && event.previousFlowEvent) {
186             newSelection.push(event.previousFlowEvent);
187             continue;
188           }
189         }
190
191         var track = viewport.trackForEvent(event);
192         track.addItemNearToProvidedEventToSelection(
193             event, offset, newSelection);
194       }
195
196       if (newSelection.length == 0)
197         return undefined;
198       return newSelection;
199     }
200   };
201
202   return {
203     Selection: Selection,
204     RequestSelectionChangeEvent: RequestSelectionChangeEvent
205   };
206 });