This is an automated email from the ASF dual-hosted git repository. sushuang pushed a commit to branch custom-morph2 in repository https://gitbox.apache.org/repos/asf/incubator-echarts.git
commit b7b941a6ae255a6f37e63810e5914da832cdcfbb Author: 100pah <sushuang0...@gmail.com> AuthorDate: Tue Sep 22 16:27:02 2020 +0800 fix: fix task clear when setOption in the second time and reuse series. --- src/stream/Scheduler.ts | 79 ++++++++++++++++++++++++------------------------- src/stream/task.ts | 57 ++++++++++++++++++++++++++++++----- 2 files changed, 88 insertions(+), 48 deletions(-) diff --git a/src/stream/Scheduler.ts b/src/stream/Scheduler.ts index 6bcaa15..2a0bdc0 100644 --- a/src/stream/Scheduler.ts +++ b/src/stream/Scheduler.ts @@ -17,7 +17,7 @@ * under the License. */ -import {each, map, isFunction, createHashMap, noop, HashMap} from 'zrender/src/core/util'; +import {each, map, isFunction, createHashMap, noop, HashMap, assert} from 'zrender/src/core/util'; import { createTask, Task, TaskContext, TaskProgressCallback, TaskProgressParams, TaskPlanCallbackReturn, PerformArgs @@ -41,7 +41,7 @@ export type OverallTask = Task<OverallTaskContext> & { agentStubMap?: HashMap<StubTask> }; export type StubTask = Task<StubTaskContext> & { - agent?: OverallTask + agent?: OverallTask; }; export type Pipeline = { @@ -263,6 +263,11 @@ class Scheduler { each(this._allHandlers, function (handler) { const record = stageTaskMap.get(handler.uid) || stageTaskMap.set(handler.uid, {}); + if (__DEV__) { + // Currently do not need to support to sepecify them both. + assert(!(handler.reset && handler.overallReset)); + } + handler.reset && this._createSeriesStageTask(handler, record, ecModel, api); handler.overallReset && this._createOverallStageTask(handler, record, ecModel, api); }, this); @@ -408,8 +413,9 @@ class Scheduler { api: ExtensionAPI ): void { const scheduler = this; - const seriesTaskMap = stageHandlerRecord.seriesTaskMap - || (stageHandlerRecord.seriesTaskMap = createHashMap()); + const oldSeriesTaskMap = stageHandlerRecord.seriesTaskMap; + // Totally stages are about several dozen, so probalby do not need to reuse the map. + const newSeriesTaskMap = stageHandlerRecord.seriesTaskMap = createHashMap(); const seriesType = stageHandler.seriesType; const getTargetSeries = stageHandler.getTargetSeries; @@ -431,12 +437,15 @@ class Scheduler { // Init tasks for each seriesModel only once. // Reuse original task instance. - const task = seriesTaskMap.get(pipelineId) - || seriesTaskMap.set(pipelineId, createTask<SeriesTaskContext>({ + const task = newSeriesTaskMap.set( + pipelineId, + oldSeriesTaskMap && oldSeriesTaskMap.get(pipelineId) + || createTask<SeriesTaskContext>({ plan: seriesTaskPlan, reset: seriesTaskReset, count: seriesTaskCount - })); + }) + ); task.context = { model: seriesModel, ecModel: ecModel, @@ -449,15 +458,6 @@ class Scheduler { }; scheduler._pipe(seriesModel, task); } - - // Clear unused series tasks. - const pipelineMap = scheduler._pipelineMap; - seriesTaskMap.each(function (task, pipelineId) { - if (!pipelineMap.get(pipelineId)) { - task.dispose(); - seriesTaskMap.removeKey(pipelineId); - } - }); } private _createOverallStageTask( @@ -478,13 +478,14 @@ class Scheduler { scheduler: scheduler }; - // Reuse orignal stubs. - const agentStubMap = overallTask.agentStubMap = overallTask.agentStubMap - || createHashMap<StubTask>(); + const oldAgentStubMap = overallTask.agentStubMap; + // Totally stages are about several dozen, so probalby do not need to reuse the map. + const newAgentStubMap = overallTask.agentStubMap = createHashMap<StubTask>(); const seriesType = stageHandler.seriesType; const getTargetSeries = stageHandler.getTargetSeries; let overallProgress = true; + let shouldOverallTaskDirty = false; // FIXME:TS never used, so comment it // let modifyOutputEnd = stageHandler.modifyOutputEnd; @@ -492,7 +493,10 @@ class Scheduler { // stub in each pipelines, it will set the overall task dirty when the pipeline // progress. Moreover, to avoid call the overall task each frame (too frequent), // we set the pipeline block. - if (seriesType) { + if (stageHandler.createOnAllSeries) { + ecModel.eachRawSeries(createStub); + } + else if (seriesType) { ecModel.eachRawSeriesByType(seriesType, createStub); } else if (getTargetSeries) { @@ -509,15 +513,18 @@ class Scheduler { function createStub(seriesModel: SeriesModel): void { const pipelineId = seriesModel.uid; - let stub = agentStubMap.get(pipelineId); - if (!stub) { - stub = agentStubMap.set(pipelineId, createTask<StubTaskContext>( - {reset: stubReset, onDirty: stubOnDirty} - )); - // When the result of `getTargetSeries` changed, the overallTask - // should be set as dirty and re-performed. - overallTask.dirty(); - } + const stub = newAgentStubMap.set( + pipelineId, + oldAgentStubMap && oldAgentStubMap.get(pipelineId) + || ( + // When the result of `getTargetSeries` changed, the overallTask + // should be set as dirty and re-performed. + shouldOverallTaskDirty = true, + createTask<StubTaskContext>( + {reset: stubReset, onDirty: stubOnDirty} + ) + ) + ); stub.context = { model: seriesModel, overallProgress: overallProgress @@ -530,17 +537,9 @@ class Scheduler { scheduler._pipe(seriesModel, stub); } - // Clear unused stubs. - const pipelineMap = scheduler._pipelineMap; - agentStubMap.each(function (stub, pipelineId) { - if (!pipelineMap.get(pipelineId)) { - stub.dispose(); - // When the result of `getTargetSeries` changed, the overallTask - // should be set as dirty and re-performed. - overallTask.dirty(); - agentStubMap.removeKey(pipelineId); - } - }); + if (shouldOverallTaskDirty) { + overallTask.dirty(); + } } private _pipe(seriesModel: SeriesModel, task: GeneralTask) { diff --git a/src/stream/task.ts b/src/stream/task.ts index 103f701..97bcaeb 100644 --- a/src/stream/task.ts +++ b/src/stream/task.ts @@ -23,6 +23,7 @@ import { Pipeline } from './Scheduler'; import { Payload } from '../util/types'; import List from '../data/List'; + export interface TaskContext { outputData?: List; data?: List; @@ -183,7 +184,6 @@ export class Task<Ctx extends TaskContext> { const step = performArgs && performArgs.step; if (upTask) { - if (__DEV__) { assert(upTask._outputDueEnd != null); } @@ -386,16 +386,18 @@ const iterator: TaskDataIterator = (function () { /////////////////////////////////////////////////////////// // For stream debug (Should be commented out after used!) -// Usage: printTask(this, 'begin'); -// Usage: printTask(this, null, {someExtraProp}); -// function printTask(task, prefix, extra) { +// @usage: printTask(this, 'begin'); +// @usage: printTask(this, null, {someExtraProp}); +// @usage: Use `__idxInPipeline` as conditional breakpiont. +// +// window.printTask = function (task: any, prefix: string, extra: { [key: string]: unknown }): void { // window.ecTaskUID == null && (window.ecTaskUID = 0); // task.uidDebug == null && (task.uidDebug = `task_${window.ecTaskUID++}`); // task.agent && task.agent.uidDebug == null && (task.agent.uidDebug = `task_${window.ecTaskUID++}`); // let props = []; // if (task.__pipeline) { // let val = `${task.__idxInPipeline}/${task.__pipeline.tail.__idxInPipeline} ${task.agent ? '(stub)' : ''}`; -// props.push({text: 'idx', value: val}); +// props.push({text: '__idxInPipeline/total', value: val}); // } else { // let stubCount = 0; // task.agentStubMap.each(() => stubCount++); @@ -403,7 +405,7 @@ const iterator: TaskDataIterator = (function () { // } // props.push({text: 'uid', value: task.uidDebug}); // if (task.__pipeline) { -// props.push({text: 'pid', value: task.__pipeline.id}); +// props.push({text: 'pipelineId', value: task.__pipeline.id}); // task.agent && props.push( // {text: 'stubFor', value: task.agent.uidDebug} // ); @@ -421,9 +423,48 @@ const iterator: TaskDataIterator = (function () { // } // let args = ['color: blue']; // let msg = `%c[${prefix || 'T'}] %c` + props.map(item => ( -// args.push('color: black', 'color: red'), +// args.push('color: green', 'color: red'), // `${item.text}: %c${item.value}` // )).join('%c, '); // console.log.apply(console, [msg].concat(args)); // // console.log(this); -// } +// }; +// window.printPipeline = function (task: any, prefix: string) { +// const pipeline = task.__pipeline; +// let currTask = pipeline.head; +// while (currTask) { +// window.printTask(currTask, prefix); +// currTask = currTask._downstream; +// } +// }; +// window.showChain = function (chainHeadTask) { +// var chain = []; +// var task = chainHeadTask; +// while (task) { +// chain.push({ +// task: task, +// up: task._upstream, +// down: task._downstream, +// idxInPipeline: task.__idxInPipeline +// }); +// task = task._downstream; +// } +// return chain; +// }; +// window.findTaskInChain = function (task, chainHeadTask) { +// let chain = window.showChain(chainHeadTask); +// let result = []; +// for (let i = 0; i < chain.length; i++) { +// let chainItem = chain[i]; +// if (chainItem.task === task) { +// result.push(i); +// } +// } +// return result; +// }; +// window.printChainAEachInChainB = function (chainHeadTaskA, chainHeadTaskB) { +// let chainA = window.showChain(chainHeadTaskA); +// for (let i = 0; i < chainA.length; i++) { +// console.log('chainAIdx:', i, 'inChainB:', window.findTaskInChain(chainA[i].task, chainHeadTaskB)); +// } +// }; --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@echarts.apache.org For additional commands, e-mail: commits-h...@echarts.apache.org