1<!DOCTYPE html> 2<!-- 3Copyright (c) 2015 The Chromium Authors. All rights reserved. 4Use of this source code is governed by a BSD-style license that can be 5found in the LICENSE file. 6--> 7 8<link rel="import" href="/tracing/base/range_utils.html"> 9<link rel="import" href="/tracing/base/statistics.html"> 10<link rel="import" href="/tracing/model/compound_event_selection_state.html"> 11<link rel="import" href="/tracing/model/event_set.html"> 12<link rel="import" href="/tracing/model/timed_event.html"> 13<link rel="import" href="/tracing/value/unit.html"> 14 15<script> 16'use strict'; 17 18tr.exportTo('tr.model.um', function() { 19 var CompoundEventSelectionState = tr.model.CompoundEventSelectionState; 20 21 function UserExpectation(parentModel, initiatorTitle, start, duration) { 22 tr.model.TimedEvent.call(this, start); 23 this.associatedEvents = new tr.model.EventSet(); 24 this.duration = duration; 25 this.initiatorTitle_ = initiatorTitle; 26 this.parentModel = parentModel; 27 this.typeInfo_ = undefined; 28 29 // sourceEvents are the ones that caused the UserModelBuilder to create this 30 // UserExpectation. 31 this.sourceEvents = new tr.model.EventSet(); 32 } 33 34 UserExpectation.prototype = { 35 __proto__: tr.model.TimedEvent.prototype, 36 37 computeCompoundEvenSelectionState: function(selection) { 38 var cess = CompoundEventSelectionState.NOT_SELECTED; 39 if (selection.contains(this)) 40 cess |= CompoundEventSelectionState.EVENT_SELECTED; 41 42 if (this.associatedEvents.intersectionIsEmpty(selection)) 43 return cess; 44 45 var allContained = this.associatedEvents.every(function(event) { 46 return selection.contains(event); 47 }); 48 49 if (allContained) 50 cess |= CompoundEventSelectionState.ALL_ASSOCIATED_EVENTS_SELECTED; 51 else 52 cess |= CompoundEventSelectionState.SOME_ASSOCIATED_EVENTS_SELECTED; 53 return cess; 54 }, 55 56 get userFriendlyName() { 57 return this.title + ' User Expectation at ' + 58 tr.v.Unit.byName.timeStampInMs.format(this.start); 59 }, 60 61 get stableId() { 62 return ('UserExpectation.' + 63 this.parentModel.userModel.expectations.indexOf(this)); 64 }, 65 66 get typeInfo() { 67 if (!this.typeInfo_) 68 this.typeInfo_ = UserExpectation.findTypeInfo(this.constructor); 69 70 // If you set Subclass.prototype = {}, then you must explicitly specify 71 // constructor in that prototype object! 72 // http://javascript.info/tutorial/constructor 73 74 if (!this.typeInfo_) 75 throw new Error('Unregistered UserExpectation'); 76 77 return this.typeInfo_; 78 }, 79 80 get colorId() { 81 return this.typeInfo.metadata.colorId; 82 }, 83 84 get stageTitle() { 85 return this.typeInfo.metadata.stageTitle; 86 }, 87 88 get initiatorTitle() { 89 return this.initiatorTitle_; 90 }, 91 92 get title() { 93 if (!this.initiatorTitle) 94 return this.stageTitle; 95 96 return this.initiatorTitle + ' ' + this.stageTitle; 97 }, 98 99 /** 100 * Returns the sum of the number of CPU ms spent by this UserExpectation. 101 */ 102 get totalCpuMs() { 103 var cpuMs = 0; 104 this.associatedEvents.forEach(function(event) { 105 if (event.cpuSelfTime) 106 cpuMs += event.cpuSelfTime; 107 }); 108 return cpuMs; 109 } 110 }; 111 112 var options = new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE); 113 tr.b.decorateExtensionRegistry(UserExpectation, options); 114 115 UserExpectation.addEventListener('will-register', function(e) { 116 var metadata = e.typeInfo.metadata; 117 118 if (metadata.stageTitle === undefined) { 119 throw new Error('Registered UserExpectations must provide ' + 120 'stageTitle'); 121 } 122 123 if (metadata.colorId === undefined) { 124 throw new Error('Registered UserExpectations must provide ' + 125 'colorId'); 126 } 127 }); 128 129 tr.model.EventRegistry.register( 130 UserExpectation, 131 { 132 name: 'user-expectation', 133 pluralName: 'user-expectations', 134 singleViewElementName: 'tr-ui-a-single-user-expectation-sub-view', 135 multiViewElementName: 'tr-ui-a-multi-user-expectation-sub-view' 136 }); 137 138 return { 139 UserExpectation: UserExpectation 140 }; 141}); 142</script> 143