Engine.EnterFrameManager = class { constructor() { this.enterFrameQueue = new Engine.CallbackQueue(this); this.postFrameQueue = new Engine.CallbackQueue(this); this.onException = null; } add(obj, func, useRealTime /* = false*/) { if (useRealTime === undefined) useRealTime = false; this.enterFrameQueue.add(obj, func, useRealTime); } remove(obj) { this.enterFrameQueue.remove(obj); } enterFrame(timeElapsed, realTimeElapsed) { this.enterFrameQueue.enterFrame(timeElapsed, realTimeElapsed); } addPostFrame(obj, func, useRealTime /* = false*/) { if (useRealTime === undefined) useRealTime = false; this.postFrameQueue.add(obj, func, useRealTime); } removePostFrame(obj) { this.postFrameQueue.remove(obj); } postFrame(timeElapsed, realTimeElapsed) { this.postFrameQueue.enterFrame(timeElapsed, realTimeElapsed); } } Engine.CallbackQueue = class { constructor(owner) { this.owner = owner; this.LastItemsUpdated = 0; this.LastTimeUpdated = 0; this.usesRealTime = new Map(); // object, bool this.enterFrameCallbacks = new Map(); this.addQueue = new Map(); this.removeQueue = [] } add(obj, func, useRealTime) { if (useRealTime && !this.usesRealTime.has(obj)) this.usesRealTime.set(obj, true); if (!useRealTime && this.usesRealTime.has(obj)) this.usesRealTime.delete(obj); // If the item is marked for removal, cancel the removal. if (this.removeQueue.indexOf(obj) != -1) { this.removeQueue.remove(obj); // don't add to the queue if this item is already active if (this.enterFrameCallbacks.has(obj)) return; } // Queue (if we aren't already adding this object...) if (!this.addQueue.has(obj)) { this.addQueue.set(obj, func); } } remove(obj) { if (this.usesRealTime.has(obj)) this.usesRealTime.delete(obj); // If we haven't added this object yet, just remove it from the add queue if (this.addQueue.has(obj)) { this.addQueue.delete(obj); return; } // Queue for removal if (!this.removeQueue.contains(obj)) { this.removeQueue.push(obj); } } enterFrame(timeElapsed, realTimeElapsed) { for(var i = 0; i < this.removeQueue.length; i++) { var obj = this.removeQueue[i]; if (this.enterFrameCallbacks.has(obj)) { this.enterFrameCallbacks.delete(obj); } } this.removeQueue = []; for (let obj of this.addQueue.keys()) { if (!this.enterFrameCallbacks.has(obj)) { this.enterFrameCallbacks.set(obj, this.addQueue.get(obj)); } } this.addQueue.clear(); this.LastItemsUpdated = 0; for (let obj of this.enterFrameCallbacks.keys()) { var func = this.enterFrameCallbacks.get(obj); var useTime = this.usesRealTime.has(obj) && this.usesRealTime.get(obj) ? realTimeElapsed : timeElapsed; if (this.owner.OnException == null) { func.call(obj, useTime); this.LastItemsUpdated++; } else { try { func.call(obj, useTime); this.LastItemsUpdated++; } catch (e) { this.owner.onException(e); } } } this.LastTimeUpdated = timeElapsed; } }