private LocalRenderCallInfo GetOrCreateParameterCallback(CefV8Context context, MethodDescriptor methodDescriptor, IV8Callback callback) { LocalRenderCallInfo parameterCallbackInfo = null; if (methodDescriptor.HasCallbackParameter && callback != null) { // Create a second stored callback info which represents the V8 callback function itself // rather than the method that is being invoked now. This allows the callback function // to be passed to and invoked by multiple native methods that accept a callback parameter. parameterCallbackInfo = (LocalRenderCallInfo)_pendingCallbacks.Get(callback.Identifier); if (parameterCallbackInfo == null) { var parameterCallbackMessage = new PluginMessage { MessageId = callback.Identifier, MessageType = PluginMessageType.ParameterCallback, PluginId = string.Empty, MemberName = string.Empty, BrowserId = context.GetBrowserId(), ContextId = GetIdForContext(context, false), FrameId = context.GetFrame().Identifier, V8CallbackId = Guid.Empty }; parameterCallbackInfo = AddLocalCallback(parameterCallbackMessage, callback, null); } } return(parameterCallbackInfo); }
private LocalRenderCallInfo AddLocalCallback(PluginMessage pluginMessage, IV8Callback callback, IJavaScriptParameterCallback parameterCallback) { var info = new LocalRenderCallInfo(this, pluginMessage, callback, parameterCallback); _pendingCallbacks.Add(info); return(info); }
/// <summary> /// Calls back into V8 in response to either: /// - a local function response message /// - a local event fired message /// - an exception while making a local function call /// Will switch to the Renderer thread if needed. /// </summary> /// <param name="call"></param> /// <param name="result"></param> /// <param name="errorCode"></param> /// <param name="error"></param> public void LocalCallbackInvoked(LocalRenderCallInfo call, object result, int errorCode, string error) { if (!CefRuntime.CurrentlyOn(CefThreadId.Renderer)) { // Call completed received from remote process, so currently are on the IO method. Marshal to the renderer to callback into V8 CefRuntime.PostTask(CefThreadId.Renderer, new ActionCallbackTask(() => LocalCallbackInvoked(call, result, errorCode, error))); return; } var msg = call.RequestMessage; Logger.Info("LocalCallbackInvoked MsgType {0} Plugin {1} Member {2}", msg.MessageType, msg.PluginId, msg.MemberName); // Already on the render thread (e.g. local plugin event triggered by call into function from JS, or function invoke failed try { var context = GetContextById(call.RequestMessage.ContextId); if (!call.IsRetained) { _pendingCallbacks.Remove(call); } if (context != null && call.Callback != null) { call.Callback.Invoke(this, context, result, errorCode, error); } if (!call.IsRetained) { call.Dispose(); } } catch (Exception exception) { Logger.Error("LocalCallbackInvoked Failed MsgType {0} Plugin {1} Member {2}: {3}", call.RequestMessage.MessageType, call.RequestMessage.PluginId, call.RequestMessage.MemberName, exception); } }