| OLD | NEW |
| 1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
| 2 <!-- | 2 <!-- |
| 3 Copyright 2015 The Chromium Authors. All rights reserved. | 3 Copyright 2015 The Chromium Authors. All rights reserved. |
| 4 Use of this source code is governed by a BSD-style license that can be | 4 Use of this source code is governed by a BSD-style license that can be |
| 5 found in the LICENSE file. | 5 found in the LICENSE file. |
| 6 --> | 6 --> |
| 7 | 7 |
| 8 <link rel="import" href="/tracing/base/task.html"> | 8 <link rel="import" href="/tracing/base/task.html"> |
| 9 <link rel="import" href="/tracing/core/filter.html"> | 9 <link rel="import" href="/tracing/core/filter.html"> |
| 10 <link rel="import" href="/tracing/core/scripting_object.html"> | 10 <link rel="import" href="/tracing/core/scripting_object.html"> |
| 11 <link rel="import" href="/tracing/extras/tquery/context.html"> | 11 <link rel="import" href="/tracing/extras/tquery/context.html"> |
| 12 <link rel="import" href="/tracing/extras/tquery/filter_all_of.html"> | 12 <link rel="import" href="/tracing/extras/tquery/filter_all_of.html"> |
| 13 <link rel="import" href="/tracing/extras/tquery/filter_any_of.html"> | 13 <link rel="import" href="/tracing/extras/tquery/filter_any_of.html"> |
| 14 <link rel="import" href="/tracing/extras/tquery/filter_has_ancestor.html"> | 14 <link rel="import" href="/tracing/extras/tquery/filter_has_ancestor.html"> |
| 15 <link rel="import" href="/tracing/extras/tquery/filter_has_duration.html"> | 15 <link rel="import" href="/tracing/extras/tquery/filter_has_duration.html"> |
| 16 <link rel="import" href="/tracing/extras/tquery/filter_has_title.html"> | 16 <link rel="import" href="/tracing/extras/tquery/filter_has_title.html"> |
| 17 <link rel="import" href="/tracing/extras/tquery/filter_is_top_level.html"> | 17 <link rel="import" href="/tracing/extras/tquery/filter_is_top_level.html"> |
| 18 <link rel="import" href="/tracing/model/event_set.html"> | 18 <link rel="import" href="/tracing/model/event_set.html"> |
| 19 | 19 |
| 20 <script> | 20 <script> |
| 21 'use strict'; | 21 'use strict'; |
| 22 | 22 |
| 23 tr.exportTo('tr.e.tquery', function() { | 23 tr.exportTo('tr.e.tquery', function() { |
| 24 function TQuery(brushingStateController) { | 24 function addEventTreeToSelection(selection, event) { |
| 25 selection.push(event); |
| 26 if (!event.subSlices) |
| 27 return; |
| 28 event.subSlices.forEach( |
| 29 addEventTreeToSelection.bind(undefined, selection)); |
| 30 } |
| 31 |
| 32 function TQuery(model) { |
| 25 tr.c.ScriptingObject.call(this); | 33 tr.c.ScriptingObject.call(this); |
| 26 | 34 |
| 27 this.brushingStateController_ = brushingStateController; | 35 this.model_ = model; |
| 28 this.parent_ = undefined; | 36 this.parent_ = undefined; |
| 29 this.filterExpression_ = undefined; | 37 this.filterExpression_ = undefined; |
| 30 // Memoized filtering result. | 38 // Memoized filtering result. |
| 31 this.selection_ = undefined; | 39 this.selection_ = undefined; |
| 32 }; | 40 }; |
| 33 | 41 |
| 34 TQuery.prototype = { | 42 TQuery.prototype = { |
| 35 __proto__: tr.c.ScriptingObject.prototype, | 43 __proto__: tr.c.ScriptingObject.prototype, |
| 36 | 44 |
| 37 onModelChanged: function() { | 45 onModelChanged: function(model) { |
| 46 this.model_ = model; |
| 38 this.selection_ = undefined; | 47 this.selection_ = undefined; |
| 39 }, | 48 }, |
| 40 | 49 |
| 41 get brushingStateController() { | 50 get brushingStateController() { |
| 42 return this.brushingStateController_; | 51 return this.brushingStateController_; |
| 43 }, | 52 }, |
| 44 | 53 |
| 45 // Append a new filter expression to this query and return a query node | 54 // Append a new filter expression to this query and return a query node |
| 46 // that represents the result. | 55 // that represents the result. |
| 47 filter: function(filterExpression) { | 56 filter: function(filterExpression) { |
| 48 var result = new TQuery(this.brushingStateController_); | 57 var result = new TQuery(this.model_); |
| 49 result.parent_ = this; | 58 result.parent_ = this; |
| 50 result.filterExpression_ = | 59 result.filterExpression_ = |
| 51 tr.e.tquery.Filter.normalizeFilterExpression(filterExpression); | 60 tr.e.tquery.Filter.normalizeFilterExpression(filterExpression); |
| 52 return result; | 61 return result; |
| 53 }, | 62 }, |
| 54 | 63 |
| 55 // Creates a graph of {Task} objects which will compute the selections for | 64 // Creates a graph of {Task} objects which will compute the selections for |
| 56 // this filter object and all of its parents. The return value is an object | 65 // this filter object and all of its parents. The return value is an object |
| 57 // with the following fields: | 66 // with the following fields: |
| 58 // - rootTask: {Task} which should be executed to kick off processing for | 67 // - rootTask: {Task} which should be executed to kick off processing for |
| (...skipping 15 matching lines...) Expand all Loading... |
| 74 var rootTask = new tr.b.Task(); | 83 var rootTask = new tr.b.Task(); |
| 75 var lastTask = rootTask; | 84 var lastTask = rootTask; |
| 76 for (var i = nodes.length - 1; i >= 0; i--) { | 85 for (var i = nodes.length - 1; i >= 0; i--) { |
| 77 var node = nodes[i]; | 86 var node = nodes[i]; |
| 78 // Reuse any memoized result. | 87 // Reuse any memoized result. |
| 79 if (node.selection_ !== undefined) | 88 if (node.selection_ !== undefined) |
| 80 continue; | 89 continue; |
| 81 node.selection_ = new tr.model.EventSet(); | 90 node.selection_ = new tr.model.EventSet(); |
| 82 if (node.parent_ === undefined) { | 91 if (node.parent_ === undefined) { |
| 83 // If this is the root, start by collecting all objects from the | 92 // If this is the root, start by collecting all objects from the |
| 84 // brushing state controller. | 93 // model. |
| 85 lastTask = lastTask.after( | 94 lastTask = lastTask.after( |
| 86 this.selectEverythingAsTask_(node.selection_)); | 95 this.selectEverythingAsTask_(node.selection_)); |
| 87 } else { | 96 } else { |
| 88 // Otherwise execute the filter expression for this node and fill | 97 // Otherwise execute the filter expression for this node and fill |
| 89 // in its selection. | 98 // in its selection. |
| 90 var prevNode = nodes[i + 1]; | 99 var prevNode = nodes[i + 1]; |
| 91 lastTask = this.createFilterTaskForNode_(lastTask, node, prevNode); | 100 lastTask = this.createFilterTaskForNode_(lastTask, node, prevNode); |
| 92 } | 101 } |
| 93 } | 102 } |
| 94 return {rootTask: rootTask, lastTask: lastTask, lastNode: node}; | 103 return {rootTask: rootTask, lastTask: lastTask, lastNode: node}; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 if (!event.subSlices) | 135 if (!event.subSlices) |
| 127 return; | 136 return; |
| 128 context = context.push(event); | 137 context = context.push(event); |
| 129 for (var i = 0; i < event.subSlices.length; i++) { | 138 for (var i = 0; i < event.subSlices.length; i++) { |
| 130 context.event = event.subSlices[i]; | 139 context.event = event.subSlices[i]; |
| 131 this.evaluateFilterExpressionForEvent_( | 140 this.evaluateFilterExpressionForEvent_( |
| 132 context, inputSelection, outputSelection, seenEvents); | 141 context, inputSelection, outputSelection, seenEvents); |
| 133 } | 142 } |
| 134 }, | 143 }, |
| 135 | 144 |
| 136 // Show the result as a highlight on the brushing state controller. Returns | 145 // Returns a task that fills the given selection with everything in the |
| 137 // a {Task} which runs the query and sets the highlight. | 146 // model. |
| 138 show: function() { | 147 selectEverythingAsTask_: function(selection) { |
| 139 var graph = this.createFilterTaskGraph_(); | 148 var filterTask = new tr.b.Task(); |
| 140 | 149 this.model_.iterateAllEventContainers(function(container) { |
| 141 graph.lastTask = graph.lastTask.after(function() { | 150 filterTask.subTask(function() { |
| 142 this.brushingStateController.showScriptControlSelection( | 151 container.iterateAllEventsInThisContainer( |
| 143 graph.lastNode.selection_); | 152 function() { return true; }, |
| 153 addEventTreeToSelection.bind(undefined, selection)); |
| 154 }, this); |
| 144 }, this); | 155 }, this); |
| 145 return graph.rootTask; | |
| 146 }, | |
| 147 | |
| 148 // Returns a task that fills the given selection with everything reachable | |
| 149 // by the brushing state controller. | |
| 150 selectEverythingAsTask_: function(selection) { | |
| 151 var passThroughFilter = new tr.c.Filter(); | |
| 152 var filterTask = this.brushingStateController. | |
| 153 addAllEventsMatchingFilterToSelectionAsTask(passThroughFilter, | |
| 154 selection); | |
| 155 return filterTask; | 156 return filterTask; |
| 156 }, | 157 }, |
| 157 | 158 |
| 159 // Returns a promise which will resolve into a {EventSet} representing the |
| 160 // result of this query. |
| 161 ready: function() { |
| 162 return new Promise(function(resolve, reject) { |
| 163 var graph = this.createFilterTaskGraph_(); |
| 164 graph.lastTask = graph.lastTask.after(function() { |
| 165 resolve(this.selection_); |
| 166 }, this); |
| 167 tr.b.Task.RunWhenIdle(graph.rootTask); |
| 168 }.bind(this)); |
| 169 }, |
| 170 |
| 158 get selection() { | 171 get selection() { |
| 159 if (this.selection_ === undefined) { | 172 if (this.selection_ === undefined) { |
| 160 var graph = this.createFilterTaskGraph_(); | 173 var graph = this.createFilterTaskGraph_(); |
| 161 tr.b.Task.RunSynchronously(graph.rootTask); | 174 tr.b.Task.RunSynchronously(graph.rootTask); |
| 162 } | 175 } |
| 163 return this.selection_; | 176 return this.selection_; |
| 164 } | 177 } |
| 165 }; | 178 }; |
| 166 tr.c.ScriptingObjectRegistry.register( | 179 tr.c.ScriptingObjectRegistry.register( |
| 167 new TQuery(), | 180 new TQuery(), |
| 168 { | 181 { |
| 169 name: '$t' | 182 name: '$t' |
| 170 } | 183 } |
| 171 ); | 184 ); |
| 172 | 185 |
| 173 return { | 186 return { |
| 174 TQuery: TQuery | 187 TQuery: TQuery |
| 175 }; | 188 }; |
| 176 }); | 189 }); |
| 177 </script> | 190 </script> |
| OLD | NEW |