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