Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / trace-viewer / trace_viewer / tracing / trace_model / object_instance.js
1 // Copyright (c) 2013 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 Provides the ObjectSnapshot and ObjectHistory classes.
9  */
10 tvcm.require('tvcm.range');
11 tvcm.require('tvcm.sorted_array_utils');
12 tvcm.require('tracing.trace_model.event');
13 tvcm.require('tracing.trace_model.object_snapshot');
14
15 tvcm.exportTo('tracing.trace_model', function() {
16   var ObjectSnapshot = tracing.trace_model.ObjectSnapshot;
17
18   /**
19    * An object with a specific id, whose state has been snapshotted several
20    * times.
21    *
22    * @constructor
23    */
24   function ObjectInstance(
25       parent, id, category, name, creationTs, opt_baseTypeName) {
26     tracing.trace_model.Event.call(this);
27     this.parent = parent;
28     this.id = id;
29     this.category = category;
30     this.baseTypeName = opt_baseTypeName ? opt_baseTypeName : name;
31     this.name = name;
32     this.creationTs = creationTs;
33     this.creationTsWasExplicit = false;
34     this.deletionTs = Number.MAX_VALUE;
35     this.deletionTsWasExplicit = false;
36     this.colorId = 0;
37     this.bounds = new tvcm.Range();
38     this.snapshots = [];
39     this.hasImplicitSnapshots = false;
40   }
41
42   ObjectInstance.prototype = {
43     __proto__: tracing.trace_model.Event.prototype,
44
45     get typeName() {
46       return this.name;
47     },
48
49     addBoundsToRange: function(range) {
50       range.addRange(this.bounds);
51     },
52
53     addSnapshot: function(ts, args, opt_name, opt_baseTypeName) {
54       if (ts < this.creationTs)
55         throw new Error('Snapshots must be >= instance.creationTs');
56       if (ts >= this.deletionTs)
57         throw new Error('Snapshots cannot be added after ' +
58                         'an objects deletion timestamp.');
59
60       var lastSnapshot;
61       if (this.snapshots.length > 0) {
62         lastSnapshot = this.snapshots[this.snapshots.length - 1];
63         if (lastSnapshot.ts == ts)
64           throw new Error('Snapshots already exists at this time!');
65         if (ts < lastSnapshot.ts) {
66           throw new Error(
67               'Snapshots must be added in increasing timestamp order');
68         }
69       }
70
71       // Update baseTypeName if needed.
72       if (opt_name &&
73           (this.name != opt_name)) {
74         if (!opt_baseTypeName)
75           throw new Error('Must provide base type name for name update');
76         if (this.baseTypeName != opt_baseTypeName)
77           throw new Error('Cannot update type name: base types dont match');
78         this.name = opt_name;
79       }
80
81       var snapshotConstructor =
82           tracing.trace_model.ObjectSnapshot.getConstructor(this.name);
83       var snapshot = new snapshotConstructor(this, ts, args);
84       this.snapshots.push(snapshot);
85       return snapshot;
86     },
87
88     wasDeleted: function(ts) {
89       var lastSnapshot;
90       if (this.snapshots.length > 0) {
91         lastSnapshot = this.snapshots[this.snapshots.length - 1];
92         if (lastSnapshot.ts > ts)
93           throw new Error(
94               'Instance cannot be deleted at ts=' +
95               ts + '. A snapshot exists that is older.');
96       }
97       this.deletionTs = ts;
98       this.deletionTsWasExplicit = true;
99     },
100
101     /**
102      * See ObjectSnapshot constructor notes on object initialization.
103      */
104     preInitialize: function() {
105       for (var i = 0; i < this.snapshots.length; i++)
106         this.snapshots[i].preInitialize();
107     },
108
109     /**
110      * See ObjectSnapshot constructor notes on object initialization.
111      */
112     initialize: function() {
113       for (var i = 0; i < this.snapshots.length; i++)
114         this.snapshots[i].initialize();
115     },
116
117     getSnapshotAt: function(ts) {
118       if (ts < this.creationTs) {
119         if (this.creationTsWasExplicit)
120           throw new Error('ts must be within lifetime of this instance');
121         return this.snapshots[0];
122       }
123       if (ts > this.deletionTs)
124         throw new Error('ts must be within lifetime of this instance');
125
126       var snapshots = this.snapshots;
127       var i = tvcm.findLowIndexInSortedIntervals(
128           snapshots,
129           function(snapshot) { return snapshot.ts; },
130           function(snapshot, i) {
131             if (i == snapshots.length - 1)
132               return snapshots[i].objectInstance.deletionTs;
133             return snapshots[i + 1].ts - snapshots[i].ts;
134           },
135           ts);
136       if (i < 0) {
137         // Note, this is a little bit sketchy: this lets early ts point at the
138         // first snapshot, even before it is taken. We do this because raster
139         // tasks usually post before their tile snapshots are dumped. This may
140         // be a good line of code to re-visit if we start seeing strange and
141         // confusing object references showing up in the traces.
142         return this.snapshots[0];
143       }
144       if (i >= this.snapshots.length)
145         return this.snapshots[this.snapshots.length - 1];
146       return this.snapshots[i];
147     },
148
149     updateBounds: function() {
150       this.bounds.reset();
151       this.bounds.addValue(this.creationTs);
152       if (this.deletionTs != Number.MAX_VALUE)
153         this.bounds.addValue(this.deletionTs);
154       else if (this.snapshots.length > 0)
155         this.bounds.addValue(this.snapshots[this.snapshots.length - 1].ts);
156     },
157
158     shiftTimestampsForward: function(amount) {
159       this.creationTs += amount;
160       if (this.deletionTs != Number.MAX_VALUE)
161         this.deletionTs += amount;
162       this.snapshots.forEach(function(snapshot) {
163         snapshot.ts += amount;
164       });
165     }
166   };
167
168   ObjectInstance.nameToConstructorMap_ = {};
169   ObjectInstance.register = function(name, constructor) {
170     if (ObjectInstance.nameToConstructorMap_[name])
171       throw new Error('Constructor already registerd for ' + name);
172     ObjectInstance.nameToConstructorMap_[name] = constructor;
173   };
174
175   ObjectInstance.unregister = function(name) {
176     delete ObjectInstance.nameToConstructorMap_[name];
177   };
178
179   ObjectInstance.getConstructor = function(name) {
180     if (ObjectInstance.nameToConstructorMap_[name])
181       return ObjectInstance.nameToConstructorMap_[name];
182     return ObjectInstance;
183   };
184
185   return {
186     ObjectInstance: ObjectInstance
187   };
188 });