/***************************************************************************************************
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);
}
}
}