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