EventManager.cs 2.74 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security;

namespace LibVLCSharp.Shared
{
    internal abstract class EventManager
    {
        internal struct Internal
        {
            [SuppressUnmanagedCodeSecurity]
            [DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_event_attach")]
            internal static extern int LibVLCEventAttach(IntPtr eventManager, EventType eventType, EventCallback eventCallback,
                IntPtr userData);

            [SuppressUnmanagedCodeSecurity]
            [DllImport(Constants.LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint = "libvlc_event_detach")]
            internal static extern void LibVLCEventDetach(IntPtr eventManager, EventType eventType, EventCallback eventCallback,
                IntPtr userData);
        }

        internal IntPtr NativeReference;
        readonly List<EventCallback> _callbacks = new List<EventCallback>();

        internal protected EventManager(IntPtr ptr)
        {
            if (ptr == IntPtr.Zero)
                throw new NullReferenceException(nameof(ptr));

            NativeReference = ptr;
        }

34
        protected void AttachNativeEvent(EventType eventType, EventCallback eventCallback)
35 36 37 38 39 40 41 42 43
        {
            _callbacks.Add(eventCallback);
            if (Internal.LibVLCEventAttach(NativeReference, eventType, eventCallback, IntPtr.Zero) != 0)
            {
                _callbacks.Remove(eventCallback);
                throw new VLCException($"Could not attach event {eventType}");
            }
        }

44
        protected void DetachNativeEvent(EventType eventType, EventCallback eventCallback)
45 46 47 48 49 50 51 52 53 54 55 56 57
        {
            _callbacks.Remove(eventCallback);

            Internal.LibVLCEventDetach(NativeReference, eventType, eventCallback, IntPtr.Zero);
        }

#if IOS
        internal protected static LibVLCEvent RetrieveEvent(IntPtr eventPtr) => Marshal.PtrToStructure<LibVLCEvent>(eventPtr);
#else
        internal protected LibVLCEvent RetrieveEvent(IntPtr eventPtr) => Marshal.PtrToStructure<LibVLCEvent>(eventPtr);
#endif

        internal protected void OnEventUnhandled(object sender, EventType eventType)
58 59
            => throw new InvalidOperationException($"eventType {nameof(eventType)} unhandled by type {sender.GetType().Name}");
        
60 61 62 63 64 65 66
        internal protected abstract void AttachEvent<T>(EventType eventType, EventHandler<T> eventHandler) where T : EventArgs;
        internal protected abstract void DetachEvent<T>(EventType eventType, EventHandler<T> eventHandler) where T : EventArgs;
    }

    [SuppressUnmanagedCodeSecurity, UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate void EventCallback(IntPtr args);
}