/*************************************************************************************************** Copyright (C) 2023 The Qt Company Ltd. SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only ***************************************************************************************************/ namespace Qt.DotNet { public partial class Adapter { /// /// Subscribe to notifications of given event from given object /// /// Native reference to target object. /// Name of event /// Opaque pointer to context data /// Pointer to callback function /// public static void AddEventHandler( IntPtr objRefPtr, string eventName, IntPtr context, Delegates.NativeEventHandler eventHandler) { #if DEBUG // Compile-time signature check of delegate vs. method _ = new Delegates.AddEventHandler(AddEventHandler); #endif var objRef = GetObjectRefFromPtr(objRefPtr); if (objRef == null) throw new ArgumentException("Invalid object reference", nameof(objRefPtr)); var eventInfo = objRef.Target.GetType().GetEvent(eventName) ?? throw new ArgumentException($"Event '{eventName}' not found", nameof(eventName)); if (Events.TryGetValue((objRef, eventName, context), out var eventRelay)) { eventRelay.Handler = eventHandler; } else { eventRelay = new EventRelay(objRef.Target, eventInfo, context, eventHandler); Events.TryAdd((objRef, eventName, context), eventRelay); } } /// /// Unsubscribe to notifications of given event from given object /// /// Native reference to target object. /// Name of event /// Opaque pointer to context data /// public static void RemoveEventHandler( IntPtr objRefPtr, string eventName, IntPtr context) { #if DEBUG // Compile-time signature check of delegate vs. method _ = new Delegates.RemoveEventHandler(RemoveEventHandler); #endif var objRef = GetObjectRefFromPtr(objRefPtr); if (objRef == null) throw new ArgumentException("Invalid object reference", nameof(objRefPtr)); RemoveEventHandler(objRef, eventName, context); } private static void RemoveEventHandler( ObjectRef objRef, string eventName, IntPtr context) { if (Events.TryRemove((objRef, eventName, context), out var evRelay)) evRelay.Enabled = false; } /// /// Unsubscribe to notifications of all events from given object /// /// Native reference to target object. /// public static void RemoveAllEventHandlers(IntPtr objRefPtr) { #if DEBUG // Compile-time signature check of delegate vs. method _ = new Delegates.RemoveAllEventHandlers(RemoveAllEventHandlers); #endif var objRef = GetObjectRefFromPtr(objRefPtr); if (objRef == null) throw new ArgumentException("Invalid object reference", nameof(objRefPtr)); RemoveAllEventHandlers(objRef); } private static void RemoveAllEventHandlers(ObjectRef objRef) { var evHandlers = Events.Where(x => x.Key.Source == objRef); foreach (var evHandler in evHandlers) RemoveEventHandler(objRef, evHandler.Key.Name, evHandler.Key.Context); } } }