blob: 5318f8b4b10437c4168f7d6ca130009feea076ae [file] [log] [blame]
<!DOCTYPE html>
<!--
Copyright 2016 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/model/event_set.html">
<link rel="import" href="/tracing/value/diagnostics/diagnostic.html">
<link rel="import" href="/tracing/value/diagnostics/event_ref.html">
<script>
'use strict';
tr.exportTo('tr.v.d', function() {
/**
* @typedef {!(tr.v.d.EventRef|tr.model.Event)} EventLike
*/
/**
* A RelatedEventSet diagnostic contains references to Events
*/
class RelatedEventSet extends tr.v.d.Diagnostic {
/**
* @param {!(tr.model.EventSet|Array.<EventLike>|EventLike)=} opt_events
*/
constructor(opt_events) {
super();
this.eventsByStableId_ = new Map();
// TODO(#2431) Plumb canonicalUrl from event.model.
this.canonicalUrl_ = undefined;
if (opt_events) {
if (opt_events instanceof tr.model.EventSet ||
opt_events instanceof Array) {
for (const event of opt_events) {
this.add(event);
}
} else {
this.add(opt_events);
}
}
}
clone() {
const clone = new tr.v.d.CollectedRelatedEventSet();
clone.addDiagnostic(this);
return clone;
}
equals(other) {
if (this.length !== other.length) return false;
for (const event of this) {
if (!other.has(event)) return false;
}
return true;
}
/**
* @param {!(tr.v.d.EventRef|tr.model.Event)} event
*/
add(event) {
this.eventsByStableId_.set(event.stableId, event);
}
/**
* @param {!(tr.v.d.EventRef|tr.model.Event)} event
* @return {boolean}
*/
has(event) {
return this.eventsByStableId_.has(event.stableId);
}
get length() {
return this.eventsByStableId_.size;
}
* [Symbol.iterator]() {
for (const event of this.eventsByStableId_.values()) {
yield event;
}
}
get canonicalUrl() {
return this.canonicalUrl_;
}
/**
* Resolve all EventRefs into Events by finding their stableIds in |model|.
* If a stableId cannot be found and |opt_required| is true, then throw an
* Error.
* If a stableId cannot be found and |opt_required| is false, then the
* EventRef will remain an EventRef.
*
* @param {!tr.model.Model} model
* @param {boolean=} opt_required
*/
resolve(model, opt_required) {
for (const [stableId, value] of this.eventsByStableId_) {
if (!(value instanceof tr.v.d.EventRef)) continue;
const event = model.getEventByStableId(stableId);
if (event instanceof tr.model.Event) {
this.eventsByStableId_.set(stableId, event);
} else if (opt_required) {
throw new Error('Unable to find Event ' + stableId);
}
}
}
serialize(serializer) {
return [...this].map(event => [
event.stableId,
serializer.getOrAllocateId(event.title),
event.start,
event.duration,
]);
}
asDictInto_(d) {
d.events = [];
for (const event of this) {
d.events.push({
stableId: event.stableId,
title: event.title,
start: tr.b.Unit.byName.timeStampInMs.truncate(event.start),
duration: tr.b.Unit.byName.timeDurationInMs.truncate(event.duration),
});
}
}
static deserialize(data, deserializer) {
return new RelatedEventSet(data.map(event => new tr.v.d.EventRef({
stableId: event[0],
title: deserializer.getObject(event[1]),
start: event[2],
duration: event[3],
})));
}
static fromDict(d) {
return new RelatedEventSet(d.events.map(
event => new tr.v.d.EventRef(event)));
}
}
tr.v.d.Diagnostic.register(RelatedEventSet, {
elementName: 'tr-v-ui-related-event-set-span'
});
return {
RelatedEventSet,
};
});
</script>