Adam Shaw 8 лет назад
Родитель
Сommit
d025219797
2 измененных файлов с 81 добавлено и 28 удалено
  1. 1 1
      src/View.js
  2. 80 27
      src/common/RenderQueue.js

+ 1 - 1
src/View.js

@@ -72,7 +72,7 @@ var View = FC.View = InteractiveDateComponent.extend({
 	requestRender: function(func, namespace, actionType) {
 		var renderQueue = this.calendar.renderQueue;
 
-		renderQueue.queue(func, '', namespace, actionType); // TODO: has UID!!!???
+		renderQueue.queue(func, namespace, actionType);
 	},
 
 

+ 80 - 27
src/common/RenderQueue.js

@@ -4,7 +4,6 @@ var RenderQueue = TaskQueue.extend({
 	waitsByNamespace: null,
 	waitNamespace: null,
 	waitId: null,
-	isKilled: false, // prevents any new tasks from being added
 
 
 	constructor: function(waitsByNamespace) {
@@ -14,20 +13,11 @@ var RenderQueue = TaskQueue.extend({
 	},
 
 
-	/*
-	entityId, namespace, actionType are optional
-	*/
-	queue: function(taskFunc, entityId, namespace, actionType) {
-
-		if (this.isKilled) {
-			return;
-		}
-
+	queue: function(taskFunc, namespace, type) {
 		var task = {
 			func: taskFunc,
-			entityId: entityId,
 			namespace: namespace,
-			actionType: actionType
+			type: type
 		};
 		var waitMs;
 
@@ -39,6 +29,10 @@ var RenderQueue = TaskQueue.extend({
 			if (namespace === this.waitNamespace && waitMs != null) {
 				this.delayWait(waitMs);
 			}
+			else {
+				this.clearWait();
+				this.tryStart();
+			}
 		}
 
 		if (this.compoundTask(task)) { // appended to queue?
@@ -75,15 +69,41 @@ var RenderQueue = TaskQueue.extend({
 	},
 
 
+	clearWait: function() {
+		if (this.waitNamespace) {
+			clearTimeout(this.waitId);
+			this.waitId = null;
+			this.waitNamespace = null;
+		}
+	},
+
+
 	canRunNext: function() {
-		return TaskQueue.prototype.canRunNext.apply(this, arguments) &&
-			!this.isKilled &&
-			(!this.waitNamespace || this.waitNamespace !== this.q[0].namespace);
+		if (!TaskQueue.prototype.canRunNext.apply(this, arguments)) {
+			return false;
+		}
+
+		// waiting for a certain namespace to stop receiving tasks?
+		if (this.waitNamespace) {
+
+			// if there was a different namespace task in the meantime,
+			// that forces all previously-waiting tasks to suddenly execute.
+			// TODO: find a way to do this in constant time.
+			for (var q = this.q, i = 0; i < q.length; i++) {
+				if (q[i].namespace !== this.waitNamespace) {
+					return true; // allow execution
+				}
+			}
+
+			return false;
+		}
+
+		return true;
 	},
 
 
 	runTask: function(task) {
-		return task.func();
+		task.func();
 	},
 
 
@@ -92,21 +112,54 @@ var RenderQueue = TaskQueue.extend({
 		var shouldAppend = true;
 		var i, task;
 
-		if (newTask.entityId && newTask.namespace && newTask.actionType === 'destroy') {
+		if (newTask.namespace) {
+
+			if (newTask.type === 'destroy' || newTask.type === 'init') {
 
-			// remove ops with same entityId and namespace
-			for (i = q.length - 1; i >= 0; i--) {
-				task = q[i];
+				// remove all add/remove ops with same namespace, regardless of order
+				for (i = q.length - 1; i >= 0; i--) {
+					task = q[i];
 
-				if (
-					task.entityId === newTask.entityId &&
-					task.namespace === newTask.namespace
-				) {
-					if (task.actionType === 'init') { // cancels out the destroy
-						shouldAppend = false;
+					if (
+						task.namespace === newTask.namespace &&
+						(task.type === 'add' || task.type === 'remove')
+					) {
+						q.splice(i, 1); // remove task
 					}
+				}
 
-					q.splice(i, 1); // remove task
+				if (newTask.type === 'destroy') {
+					// eat away final init/destroy operation
+					if (q.length) {
+						task = q[q.length - 1]; // last task
+
+						if (task.namespace === newTask.namespace) {
+
+							// the init and our destroy cancel each other out
+							if (task.type === 'init') {
+								shouldAppend = false;
+								q.pop();
+							}
+							// prefer to use the destroy operation that's already present
+							else if (task.type === 'destroy') {
+								shouldAppend = false;
+							}
+						}
+					}
+				}
+				else if (newTask.type === 'init') {
+					// eat away final init operation
+					if (q.length) {
+						task = q[q.length - 1]; // last task
+
+						if (
+							task.namespace === newTask.namespace &&
+							task.type === 'init'
+						) {
+							// our init operation takes precedence
+							q.pop();
+						}
+					}
 				}
 			}
 		}