blob: 3ef616846fa6c544d6751e54a14a1eafb0eaa5e0 [file] [log] [blame]
<!DOCTYPE html>
<!--
Copyright (c) 2015 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<link rel="import" href="/tracing/base/range_utils.html">
<link rel="import" href="/tracing/base/statistics.html">
<link rel="import" href="/tracing/base/unit.html">
<link rel="import" href="/tracing/model/compound_event_selection_state.html">
<link rel="import" href="/tracing/model/event_set.html">
<link rel="import" href="/tracing/model/timed_event.html">
<script>
'use strict';
tr.exportTo('tr.model.um', function() {
var CompoundEventSelectionState = tr.model.CompoundEventSelectionState;
function UserExpectation(parentModel, initiatorTitle, start, duration) {
tr.model.TimedEvent.call(this, start);
this.associatedEvents = new tr.model.EventSet();
this.duration = duration;
this.initiatorTitle_ = initiatorTitle;
this.parentModel = parentModel;
this.typeInfo_ = undefined;
// sourceEvents are the ones that caused the UserModelBuilder to create this
// UserExpectation.
this.sourceEvents = new tr.model.EventSet();
}
UserExpectation.prototype = {
__proto__: tr.model.TimedEvent.prototype,
computeCompoundEvenSelectionState: function(selection) {
var cess = CompoundEventSelectionState.NOT_SELECTED;
if (selection.contains(this))
cess |= CompoundEventSelectionState.EVENT_SELECTED;
if (this.associatedEvents.intersectionIsEmpty(selection))
return cess;
var allContained = this.associatedEvents.every(function(event) {
return selection.contains(event);
});
if (allContained)
cess |= CompoundEventSelectionState.ALL_ASSOCIATED_EVENTS_SELECTED;
else
cess |= CompoundEventSelectionState.SOME_ASSOCIATED_EVENTS_SELECTED;
return cess;
},
// Returns samples which are overlapping with V8.Execute
get associatedSamples() {
var samples = new tr.model.EventSet();
this.associatedEvents.forEach(function(event) {
if (event instanceof tr.model.ThreadSlice)
samples.addEventSet(event.overlappingSamples);
});
return samples;
},
get userFriendlyName() {
return this.title + ' User Expectation at ' +
tr.b.Unit.byName.timeStampInMs.format(this.start);
},
get stableId() {
return ('UserExpectation.' + this.guid);
},
get typeInfo() {
if (!this.typeInfo_) {
this.typeInfo_ = UserExpectation.subTypes.findTypeInfo(
this.constructor);
}
// If you set Subclass.prototype = {}, then you must explicitly specify
// constructor in that prototype object!
// http://javascript.info/tutorial/constructor
if (!this.typeInfo_)
throw new Error('Unregistered UserExpectation');
return this.typeInfo_;
},
get colorId() {
return this.typeInfo.metadata.colorId;
},
get stageTitle() {
return this.typeInfo.metadata.stageTitle;
},
get initiatorTitle() {
return this.initiatorTitle_;
},
get title() {
if (!this.initiatorTitle)
return this.stageTitle;
return this.initiatorTitle + ' ' + this.stageTitle;
},
/**
* Returns the sum of the number of CPU ms spent by this UserExpectation.
*/
get totalCpuMs() {
var cpuMs = 0;
this.associatedEvents.forEach(function(event) {
if (event.cpuSelfTime)
cpuMs += event.cpuSelfTime;
});
return cpuMs;
}
};
var subTypes = {};
var options = new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);
tr.b.decorateExtensionRegistry(subTypes, options);
subTypes.addEventListener('will-register', function(e) {
var metadata = e.typeInfo.metadata;
if (metadata.stageTitle === undefined) {
throw new Error('Registered UserExpectations must provide ' +
'stageTitle');
}
if (metadata.colorId === undefined) {
throw new Error('Registered UserExpectations must provide ' +
'colorId');
}
});
tr.model.EventRegistry.register(
UserExpectation,
{
name: 'userExpectation',
pluralName: 'userExpectations',
subTypes: subTypes
});
return {
UserExpectation: UserExpectation
};
});
</script>