Difference between revisions of "Void lock (in Element target, optional in VoidCallback successCallback, optional in VoidCallback failureCallback);"
(Created page with '==Doing the callbacks in IDL/C++== Consider a similar interface already in the DOM, navigator.geolocation.getCurrentPosition: https://mxr.mozilla.org/mozilla-central/source/dom…') |
(No difference)
|
Latest revision as of 19:00, 21 November 2011
Doing the callbacks in IDL/C++
Consider a similar interface already in the DOM, navigator.geolocation.getCurrentPosition:
https://mxr.mozilla.org/mozilla-central/source/dom/interfaces/geolocation/nsIDOMGeoGeolocation.idl
44 [scriptable, function, uuid(37687DAF-B85F-4E4D-8881-85A0AD24CF78)] 45 interface nsIDOMGeoGeolocation : nsISupports 46 { 47 void getCurrentPosition(in nsIDOMGeoPositionCallback successCallback, 48 [optional] in nsIDOMGeoPositionErrorCallback errorCallback, 49 [optional] in nsIDOMGeoPositionOptions options);
Here's the C++. Notice how the callbacks have become their own types: nsIDOMGeoPositionCallback and nsIDOMGeoPositionErrorCallback
918 NS_IMETHODIMP 919 nsGeolocation::GetCurrentPosition(nsIDOMGeoPositionCallback *callback, 920 nsIDOMGeoPositionErrorCallback *errorCallback, 921 nsIDOMGeoPositionOptions *options) 922 { 923 NS_ENSURE_ARG_POINTER(callback); 924 925 if (!sGeoEnabled) 926 return NS_ERROR_NOT_AVAILABLE; 927 928 if (mPendingCallbacks.Length() > MAX_GEO_REQUESTS_PER_WINDOW) 929 return NS_ERROR_NOT_AVAILABLE; 930 931 nsRefPtr<nsGeolocationRequest> request = new nsGeolocationRequest(this, 932 callback, 933 errorCallback, 934 options, 935 false);
The callback (and errorCallback) are passed into the ctor for nsGeolocationRequest. It holds on to them as member variables:
239 nsGeolocationRequest::nsGeolocationRequest(nsGeolocation* aLocator, 240 nsIDOMGeoPositionCallback* aCallback, 241 nsIDOMGeoPositionErrorCallback* aErrorCallback, 242 nsIDOMGeoPositionOptions* aOptions, 243 bool aWatchPositionRequest) 244 : mAllowed(false), 245 mCleared(false), 246 mIsWatchPositionRequest(aWatchPositionRequest), 247 mCallback(aCallback), 248 mErrorCallback(aErrorCallback), 249 mOptions(aOptions), 250 mLocator(aLocator) 251 { 252 }
When it's time to finish the request, it uses these to trigger the call back in JS:
432 void 433 nsGeolocationRequest::SendLocation(nsIDOMGeoPosition* aPosition) 434 { 435 if (mCleared || !mAllowed) 436 return; 437 438 if (mTimeoutTimer) { 439 mTimeoutTimer->Cancel(); 440 mTimeoutTimer = nsnull; 441 } 442 443 // we should not pass null back to the DOM. 444 if (!aPosition) { 445 NotifyError(nsIDOMGeoPositionError::POSITION_UNAVAILABLE); 446 return; 447 } 448 449 // Ensure that the proper context is on the stack (bug 452762) 450 nsCOMPtr<nsIJSContextStack> stack(do_GetService("@mozilla.org/js/xpc/ContextStack;1")); 451 if (!stack || NS_FAILED(stack->Push(nsnull))) 452 return; // silently fail 453 454 mCallback->HandleEvent(aPosition); 455 456 // remove the stack 457 JSContext* cx; 458 stack->Pop(&cx); 459 460 if (mIsWatchPositionRequest) 461 SetTimeoutTimer(); 462 }
The callback DOM object wrapper looks like this:
42 [scriptable, function, uuid(527E8B53-6F29-4B6A-8D04-5C1666A4C4C1)] 43 interface nsIDOMGeoPositionCallback : nsISupports { 44 void handleEvent(in nsIDOMGeoPosition position); 45 };
So an nsDOMGeoPositionCallback is really an object with a single method, handleEvent, that takes an nsIDOMGeoPosition.