191 lines
5.2 KiB
JavaScript
191 lines
5.2 KiB
JavaScript
Type.registerNamespace('Sys.Extended.UI');
|
|
|
|
Sys.Extended.UI.DeferredOperation = function(delay, context, callback) {
|
|
// Used to define a cancellable async operation
|
|
// "delay" - the number of milliseconds to delay execution
|
|
// "context" - an object used as the context for the callback method
|
|
// "callback" - the callback method to execute at the end of the delay
|
|
|
|
this._delay = delay;
|
|
this._context = context;
|
|
this._callback = callback;
|
|
this._completeCallback = null;
|
|
this._errorCallback = null;
|
|
this._timer = null;
|
|
this._callArgs = null;
|
|
this._isComplete = false;
|
|
this._completedSynchronously = false;
|
|
this._asyncResult = null;
|
|
this._exception = null;
|
|
this._throwExceptions = true;
|
|
this._oncomplete$delegate = Function.createDelegate(this, this._oncomplete);
|
|
|
|
// post to ensure that attaching it always gets the port as its context
|
|
this.post = Function.createDelegate(this, this.post);
|
|
}
|
|
|
|
Sys.Extended.UI.DeferredOperation.prototype = {
|
|
|
|
get_isPending: function() {
|
|
return (this._timer != null);
|
|
},
|
|
|
|
get_isComplete: function() {
|
|
return this._isComplete;
|
|
},
|
|
|
|
get_completedSynchronously: function() {
|
|
return this._completedSynchronously;
|
|
},
|
|
|
|
get_exception: function() {
|
|
return this._exception;
|
|
},
|
|
|
|
get_throwExceptions: function() {
|
|
return this._throwExceptions;
|
|
},
|
|
|
|
set_throwExceptions: function(value) {
|
|
// Sets whether to throw exceptions
|
|
this._throwExceptions = value;
|
|
},
|
|
|
|
get_delay: function() {
|
|
// Gets the current delay in milliseconds
|
|
return this._delay;
|
|
},
|
|
|
|
set_delay: function(value) {
|
|
// Sets the current delay in milliseconds
|
|
this._delay = value;
|
|
},
|
|
|
|
post: function(args) {
|
|
// A method that can be directly attached to a delegate
|
|
var ar = [];
|
|
for(var i = 0; i < arguments.length; i++)
|
|
ar[i] = arguments[i];
|
|
|
|
this.beginPost(ar, null, null);
|
|
},
|
|
|
|
beginPost: function(args, completeCallback, errorCallback) {
|
|
// Posts a call to an async operation on this port
|
|
|
|
// cancel any pending post
|
|
this.cancel();
|
|
|
|
// cache the call arguments
|
|
this._callArgs = Array.clone(args || []);
|
|
this._completeCallback = completeCallback;
|
|
this._errorCallback = errorCallback;
|
|
|
|
if(this._delay == -1) {
|
|
// if there is no delay (-1), complete synchronously
|
|
try {
|
|
this._oncomplete();
|
|
} finally {
|
|
this._completedSynchronously = true;
|
|
}
|
|
} else {
|
|
// complete the post on a seperate call after a delay
|
|
this._timer = setTimeout(this._oncomplete$delegate, this._delay);
|
|
}
|
|
},
|
|
|
|
cancel: function() {
|
|
if(this._timer) {
|
|
clearTimeout(this._timer);
|
|
this._timer = null;
|
|
}
|
|
|
|
this._callArgs = null;
|
|
this._isComplete = false;
|
|
this._asyncResult = null;
|
|
this._completeCallback = null;
|
|
this._errorCallback = null;
|
|
this._exception = null;
|
|
this._completedSynchronously = false;
|
|
},
|
|
|
|
call: function(args) {
|
|
// Executes the deferred operation synchronously
|
|
|
|
var ar = [];
|
|
for(var i = 0; i < arguments.length; i++)
|
|
ar[i] = arguments[i];
|
|
|
|
// cancel any pending post
|
|
this.cancel();
|
|
|
|
// cache the call arguments
|
|
this._callArgs = ar;
|
|
this._completeCallback = null;
|
|
this._errorCallback = null;
|
|
|
|
try {
|
|
this._oncomplete();
|
|
} finally {
|
|
this._completedSynchronously = true;
|
|
}
|
|
|
|
if(this._exception)
|
|
throw this._exception;
|
|
|
|
return this._asyncResult;
|
|
},
|
|
|
|
complete: function() {
|
|
// Completes a pending post synchronously
|
|
|
|
if(this._timer) {
|
|
try {
|
|
this._oncomplete();
|
|
} finally {
|
|
this._completedSynchronously = true;
|
|
}
|
|
|
|
return this._asyncResult;
|
|
} else if(this._isComplete) {
|
|
return this._asyncResult;
|
|
}
|
|
},
|
|
|
|
_oncomplete: function() {
|
|
// Completes a pending post asynchronously
|
|
|
|
var args = this._callArgs,
|
|
completeCallback = this._completeCallback,
|
|
errorCallback = this._errorCallback;
|
|
|
|
// clear the post state
|
|
this.cancel();
|
|
try {
|
|
// call the post callback
|
|
if(args)
|
|
this._asyncResult = this._callback.apply(this._context, args);
|
|
else
|
|
this._asyncResult = this._callback.call(this._context);
|
|
|
|
this._isComplete = true;
|
|
this._completedSynchronously = false;
|
|
|
|
if(completeCallback)
|
|
completeCallback(this);
|
|
} catch(e) {
|
|
this._isComplete = true;
|
|
this._completedSynchronously = false;
|
|
this._exception = e;
|
|
|
|
if(errorCallback)
|
|
if(errorCallback(this))
|
|
return;
|
|
|
|
if(this._throwExceptions)
|
|
throw e;
|
|
}
|
|
}
|
|
}
|
|
|
|
Sys.Extended.UI.DeferredOperation.registerClass("Sys.Extended.UI.DeferredOperation"); |