12df44aaf326a5c14c23806abf4674681a495635
[platform/framework/web/crosswalk.git] / src / third_party / trace-viewer / src / 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 base.require('base.events');
11 base.require('base.guid');
12 base.require('base.range');
13 base.require('tracing.trace_model.instant_event');
14 base.require('tracing.trace_model');
15
16 base.exportTo('tracing', function() {
17
18   var EVENT_TYPES = [
19     {
20       constructor: tracing.trace_model.Slice,
21       name: 'slice',
22       pluralName: 'slices'
23     },
24     {
25       constructor: tracing.trace_model.InstantEvent,
26       name: 'instantEvent',
27       pluralName: 'instantEvents'
28     },
29     {
30       constructor: tracing.trace_model.CounterSample,
31       name: 'counterSample',
32       pluralName: 'counterSamples'
33     },
34     {
35       constructor: tracing.trace_model.ObjectSnapshot,
36       name: 'objectSnapshot',
37       pluralName: 'objectSnapshots'
38     },
39     {
40       constructor: tracing.trace_model.ObjectInstance,
41       name: 'objectInstance',
42       pluralName: 'objectInstances'
43     },
44     {
45       constructor: tracing.trace_model.Sample,
46       name: 'sample',
47       pluralName: 'samples'
48     }
49   ];
50
51   /**
52    * Represents a selection within a  and its associated set of tracks.
53    * @constructor
54    */
55   function Selection(opt_events) {
56     this.bounds_dirty_ = true;
57     this.bounds_ = new base.Range();
58     this.length_ = 0;
59     this.guid_ = base.GUID.allocate();
60
61     if (opt_events) {
62       for (var i = 0; i < opt_events.length; i++)
63         this.push(opt_events[i]);
64     }
65   }
66   Selection.prototype = {
67     __proto__: Object.prototype,
68
69     get bounds() {
70       if (this.bounds_dirty_) {
71         this.bounds_.reset();
72         for (var i = 0; i < this.length_; i++)
73           this[i].addBoundsToRange(this.bounds_);
74         this.bounds_dirty_ = false;
75       }
76       return this.bounds_;
77     },
78
79     get duration() {
80       if (this.bounds_.isEmpty)
81         return 0;
82       return this.bounds_.max - this.bounds_.min;
83     },
84
85     get length() {
86       return this.length_;
87     },
88
89     get guid() {
90       return this.guid_;
91     },
92
93     clear: function() {
94       for (var i = 0; i < this.length_; ++i)
95         delete this[i];
96       this.length_ = 0;
97       this.bounds_dirty_ = true;
98     },
99
100     push: function(event) {
101       this[this.length_++] = event;
102       this.bounds_dirty_ = true;
103       return event;
104     },
105
106     addSelection: function(selection) {
107       for (var i = 0; i < selection.length; i++)
108         this.push(selection[i]);
109     },
110
111     subSelection: function(index, count) {
112       count = count || 1;
113
114       var selection = new Selection();
115       selection.bounds_dirty_ = true;
116       if (index < 0 || index + count > this.length_)
117         throw new Error('Index out of bounds');
118
119       for (var i = index; i < index + count; i++)
120         selection.push(this[i]);
121
122       return selection;
123     },
124
125     getEventsOrganizedByType: function() {
126       var events = {};
127       EVENT_TYPES.forEach(function(eventType) {
128         events[eventType.pluralName] = new Selection();
129       });
130       for (var i = 0; i < this.length_; i++) {
131         var event = this[i];
132         EVENT_TYPES.forEach(function(eventType) {
133           if (event instanceof eventType.constructor)
134             events[eventType.pluralName].push(event);
135         });
136       }
137       return events;
138     },
139
140     enumEventsOfType: function(type, func) {
141       for (var i = 0; i < this.length_; i++)
142         if (this[i] instanceof type)
143           func(this[i]);
144     },
145
146     map: function(fn) {
147       for (var i = 0; i < this.length_; i++)
148         fn(this[i]);
149     },
150
151     /**
152      * Helper for selection previous or next.
153      * @param {boolean} forwardp If true, select one forward (next).
154      *   Else, select previous.
155      *
156      * @param {TimelineViewport} viewport The viewport to use to determine what
157      * is near to the current selection.
158      *
159      * @return {boolean} true if current selection changed.
160      */
161     getShiftedSelection: function(viewport, offset) {
162       var newSelection = new Selection();
163       for (var i = 0; i < this.length_; i++) {
164         var event = this[i];
165         var track = viewport.trackForEvent(event);
166         track.addItemNearToProvidedEventToSelection(
167             event, offset, newSelection);
168       }
169
170       if (newSelection.length == 0)
171         return undefined;
172       return newSelection;
173     }
174   };
175
176   return {
177     Selection: Selection
178   };
179 });