C
C#2w ago
The Hyper

Stopping Invoking the rest of the registered methods if the bool is true

Any possible ways to do it?
11 Replies
canton7
canton72w ago
By "The rest of the registered methods", do you mean all other methods which were added to that multicast delegate with +=?
The Hyper
The Hyper2w ago
yep
canton7
canton72w ago
Not directly. Some of the BCL's events, such as this one https://learn.microsoft.com/en-us/dotnet/api/system.windows.routedeventargs.handled?view=windowsdesktop-8.0 have a Handled property on the EventArgs. To make that work, they don't invoke the multicast delegate with .Invoke, but they explicitly get the invocation list (https://learn.microsoft.com/en-us/dotnet/api/system.multicastdelegate.getinvocationlist?view=net-8.0) and call the delegates one by one, checking that Handled property after each
The Hyper
The Hyper2w ago
public static event Func<bool>
onKey,
onMouseMotion,
onMouseButton,
onJoypadMotion,
onJoypadButton,
onScreenDrag,
onScreenTouch;

public static void SetInputs(InputEvent input)
{
foreach (var del in onKey.GetInvocationList())
{
if (del)
{

}
}
}
public static event Func<bool>
onKey,
onMouseMotion,
onMouseButton,
onJoypadMotion,
onJoypadButton,
onScreenDrag,
onScreenTouch;

public static void SetInputs(InputEvent input)
{
foreach (var del in onKey.GetInvocationList())
{
if (del)
{

}
}
}
can't find the "Handled" property nor get the bool value
canton7
canton72w ago
I gave you an example of part of the BCL which has defined its own Handled property on its EventArgs subclass
ffmpeg -i me -f null -
if you want that kind of behavior then using multicast delegate seems the wrong tool tbh
cap5lut
cap5lut2w ago
actually it seems quite possible depending on if u have control over invoking.
class Example
{
public event Action<bool>? Event;

public void Fire(bool value)
{
if (value)
{
if (Event?.GetInvocationList().FirstOrDefault() is { } first)
{
first.DynamicInvoke(true);
}
}
else
{
Event?.Invoke(false);
}
}
}
class Example
{
public event Action<bool>? Event;

public void Fire(bool value)
{
if (value)
{
if (Event?.GetInvocationList().FirstOrDefault() is { } first)
{
first.DynamicInvoke(true);
}
}
else
{
Event?.Invoke(false);
}
}
}
var ex = new Example();
ex.Event += _ => Console.WriteLine("first");
ex.Event += _ => Console.WriteLine("second");
ex.Fire(true);
ex.Fire(false);
var ex = new Example();
ex.Event += _ => Console.WriteLine("first");
ex.Event += _ => Console.WriteLine("second");
ex.Fire(true);
ex.Fire(false);
would print
first
first
second
first
first
second
tho, that would be damn slow and causes more allocations
ffmpeg -i me -f null -
it's possible, but for me it would way better - if possible - to have an object that manages the dispatch and can 'explain' why stuff is going to all or some of the registered handlers
cap5lut
cap5lut2w ago
yeah i agree there
The Hyper
The Hyper2w ago
public class InputHandleEvent
{
private List<Func<bool>> registered_methods;
public InputHandleEvent(int initial_event_capacity)
{
registered_methods = new(initial_event_capacity);
}
public void Add(Func<bool> method)
{
registered_methods.Add(method);
}
public void Remove(Func<bool> method)
{
registered_methods.Remove(method);
}

public void Invoke()
{
for (int i = 0, length = registered_methods.Count; i < length; ++i)
{
if (registered_methods[i]())
return;
}
}
}
public class InputHandleEvent
{
private List<Func<bool>> registered_methods;
public InputHandleEvent(int initial_event_capacity)
{
registered_methods = new(initial_event_capacity);
}
public void Add(Func<bool> method)
{
registered_methods.Add(method);
}
public void Remove(Func<bool> method)
{
registered_methods.Remove(method);
}

public void Invoke()
{
for (int i = 0, length = registered_methods.Count; i < length; ++i)
{
if (registered_methods[i]())
return;
}
}
}
is this a bad idea?
cap5lut
cap5lut2w ago
besides the Handled property u could do it relatively like that. the event members have add and remove accessors similar to get and set for properties:
private readonly List<Func<bool>> _eventHandlers = new();
public event Func<bool> Event
{
add
{
_eventHandlers.Add(value);
}
remove
{
_eventHandlers.Remove(value);
}
}
private void InvokeEvent()
{
foreach (var handler in _eventHandlers)
{
if (handler())
{
break;
}
}
}
private readonly List<Func<bool>> _eventHandlers = new();
public event Func<bool> Event
{
add
{
_eventHandlers.Add(value);
}
remove
{
_eventHandlers.Remove(value);
}
}
private void InvokeEvent()
{
foreach (var handler in _eventHandlers)
{
if (handler())
{
break;
}
}
}
this way u can still add/remove event handlers like with normal ones