Commit 1ffbfe63 authored by Martin Finkel's avatar Martin Finkel

Refactor ModuleDescription

parent 493ae7c8
......@@ -35,9 +35,9 @@ namespace LibVLCSharp.Tests
foreach (var filter in audioFilters)
{
Debug.WriteLine(filter.Help);
Debug.WriteLine(filter.Longname);
Debug.WriteLine(filter.LongName);
Debug.WriteLine(filter.Name);
Debug.WriteLine(filter.Shortname);
Debug.WriteLine(filter.ShortName);
}
}
......@@ -48,9 +48,9 @@ namespace LibVLCSharp.Tests
var videoFilters = libVLC.VideoFilters;
foreach (var filter in videoFilters)
{
Debug.WriteLine(filter.Longname);
Debug.WriteLine(filter.LongName);
Debug.WriteLine(filter.Name);
Debug.WriteLine(filter.Shortname);
Debug.WriteLine(filter.ShortName);
}
}
......
......@@ -25,5 +25,18 @@ namespace LibVLCSharp.Shared.Helpers
DeviceIdentifier = Utf8StringMarshaler.GetInstance().MarshalNativeToManaged(s.DeviceIdentifier) as string,
Description = Utf8StringMarshaler.GetInstance().MarshalNativeToManaged(s.Description) as string,
};
/// <summary>
/// Helper method that creates a managed type from the internal interop structure.
/// </summary>
/// <param name="s">ModuleDescriptionStructure from interop</param>
/// <returns>public ModuleDescription to be consumed by the user</returns>
internal static ModuleDescription Build(this ModuleDescriptionStructure s) => new ModuleDescription
{
Name = Utf8StringMarshaler.GetInstance().MarshalNativeToManaged(s.Name) as string,
ShortName = Utf8StringMarshaler.GetInstance().MarshalNativeToManaged(s.ShortName) as string,
LongName = Utf8StringMarshaler.GetInstance().MarshalNativeToManaged(s.LongName) as string,
Help = Utf8StringMarshaler.GetInstance().MarshalNativeToManaged(s.Help) as string
};
}
}
\ No newline at end of file
......@@ -435,16 +435,11 @@ namespace LibVLCSharp.Shared
/// <para>libvlc_module_description_t</para>
/// <para>libvlc_module_description_list_release</para>
/// </remarks>
public ModuleDescription[] AudioFilters
{
get
{
return MarshalUtils.Retrieve(() => Native.LibVLCAudioFilterListGet(NativeReference),
MarshalUtils.PtrToStructure<ModuleDescription.Internal>,
intern => ModuleDescription.__CreateInstance(intern),
module => module.Next, Native.LibVLCModuleDescriptionListRelease);
}
}
public ModuleDescription[] AudioFilters => MarshalUtils.Retrieve(() => Native.LibVLCAudioFilterListGet(NativeReference),
MarshalUtils.PtrToStructure<ModuleDescriptionStructure>,
s => s.Build(),
module => module.Next,
Native.LibVLCModuleDescriptionListRelease);
/// <summary>Returns a list of video filters that are available.</summary>
/// <returns>
......@@ -456,9 +451,10 @@ namespace LibVLCSharp.Shared
/// <para>libvlc_module_description_list_release</para>
/// </remarks>
public ModuleDescription[] VideoFilters => MarshalUtils.Retrieve(() => Native.LibVLCVideoFilterListGet(NativeReference),
MarshalUtils.PtrToStructure<ModuleDescription.Internal>,
intern => ModuleDescription.__CreateInstance(intern),
module => module.Next, Native.LibVLCModuleDescriptionListRelease);
MarshalUtils.PtrToStructure<ModuleDescriptionStructure>,
s => s.Build(),
module => module.Next,
Native.LibVLCModuleDescriptionListRelease);
/// <summary>Gets the list of available audio output modules.</summary>
/// <returns>list of available audio outputs. It must be freed with</returns>
......
......@@ -3,10 +3,7 @@ using System.Runtime.InteropServices;
namespace LibVLCSharp.Shared.Structures
{
/// <summary>
/// <para>Description for audio output. It contains</para>
/// <para>name, description and pointer to next record.</para>
/// </summary>
[StructLayout(LayoutKind.Sequential)]
internal struct AudioOutputDescriptionStructure
{
......@@ -15,6 +12,9 @@ namespace LibVLCSharp.Shared.Structures
public IntPtr NextAudioOutputDescription;
}
/// <summary>
/// Description for audio output.
/// </summary>
public class AudioOutputDescription
{
public string Name;
......
......@@ -11,9 +11,19 @@ namespace LibVLCSharp.Shared.Structures
public IntPtr Description;
}
/// <summary>
/// Description for audio output device
/// </summary>
public class AudioOutputDevice
{
/// <summary>
/// Device identifier string.
/// </summary>
public string DeviceIdentifier;
/// <summary>
/// User-friendly device description.
/// </summary>
public string Description;
}
}
\ No newline at end of file
......@@ -3,136 +3,24 @@ using System.Runtime.InteropServices;
namespace LibVLCSharp.Shared.Structures
{
// TODO: cleanup
public unsafe partial class ModuleDescription : IDisposable
[StructLayout(LayoutKind.Sequential)]
internal struct ModuleDescriptionStructure
{
[StructLayout(LayoutKind.Sequential)]
public struct Internal
{
//[FieldOffset(0)]
//[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8StringMarshaler))]
internal IntPtr psz_name;
//[FieldOffset(8)]
//[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8StringMarshaler))]
internal IntPtr psz_shortname;
//[FieldOffset(16)]
//[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8StringMarshaler))]
internal IntPtr psz_longname;
//[FieldOffset(24)]
//[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8StringMarshaler))]
internal IntPtr psz_help;
//[FieldOffset(32)]
//[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8StringMarshaler))]
internal IntPtr p_next;
//[SuppressUnmanagedCodeSecurity]
//[DllImport(Constants.LibraryName, CallingConvention = global::System.Runtime.InteropServices.CallingConvention.Cdecl,
// EntryPoint="??0libvlc_module_description_t@@QEAA@AEBU0@@Z")]
//internal static extern global::System.IntPtr cctor(global::System.IntPtr instance, global::System.IntPtr _0);
}
public IntPtr NativeReference { get; protected set; }
protected int __PointerAdjustment;
internal static readonly global::System.Collections.Concurrent.ConcurrentDictionary<IntPtr, ModuleDescription> NativeToManagedMap = new global::System.Collections.Concurrent.ConcurrentDictionary<IntPtr, ModuleDescription>();
protected void*[] __OriginalVTables;
protected bool __ownsNativeInstance;
internal static ModuleDescription __CreateInstance(global::System.IntPtr native, bool skipVTables = false)
{
return new ModuleDescription(native.ToPointer(), skipVTables);
}
internal static ModuleDescription __CreateInstance(ModuleDescription.Internal native, bool skipVTables = false)
{
return new ModuleDescription(native, skipVTables);
}
private static void* __CopyValue(ModuleDescription.Internal native)
{
var ret = Marshal.AllocHGlobal(sizeof(ModuleDescription.Internal));
*(ModuleDescription.Internal*)ret = native;
return ret.ToPointer();
}
private ModuleDescription(ModuleDescription.Internal native, bool skipVTables = false)
: this(__CopyValue(native), skipVTables)
{
__ownsNativeInstance = true;
NativeToManagedMap[NativeReference] = this;
}
protected ModuleDescription(void* native, bool skipVTables = false)
{
if (native == null)
return;
NativeReference = new global::System.IntPtr(native);
}
public ModuleDescription()
{
NativeReference = Marshal.AllocHGlobal(sizeof(ModuleDescription.Internal));
__ownsNativeInstance = true;
NativeToManagedMap[NativeReference] = this;
}
public ModuleDescription(ModuleDescription _0)
{
NativeReference = Marshal.AllocHGlobal(sizeof(ModuleDescription.Internal));
__ownsNativeInstance = true;
NativeToManagedMap[NativeReference] = this;
*((ModuleDescription.Internal*)NativeReference) = *((ModuleDescription.Internal*)_0.NativeReference);
}
public void Dispose()
{
Dispose(disposing: true);
}
public virtual void Dispose(bool disposing)
{
if (NativeReference == IntPtr.Zero)
return;
NativeToManagedMap.TryRemove(NativeReference, out var dummy);
NativeReference = IntPtr.Zero;
}
public string Name => Marshal.PtrToStringAnsi(((Internal*)NativeReference)->psz_name);
public string Shortname => Marshal.PtrToStringAnsi(((Internal*)NativeReference)->psz_shortname);
public string Longname => Marshal.PtrToStringAnsi(((Internal*)NativeReference)->psz_longname);
public string Help => Marshal.PtrToStringAnsi(((Internal*)NativeReference)->psz_help);
public ModuleDescription Next
{
get
{
ModuleDescription __result0;
if (((ModuleDescription.Internal*)NativeReference)->p_next == IntPtr.Zero) __result0 = null;
else if (NativeToManagedMap.ContainsKey(((Internal*)NativeReference)->p_next))
__result0 = NativeToManagedMap[((Internal*)NativeReference)->p_next];
else __result0 = __CreateInstance(((Internal*)NativeReference)->p_next);
return __result0;
}
set
{
((ModuleDescription.Internal*)NativeReference)->p_next = ReferenceEquals(value, null) ? global::System.IntPtr.Zero : value.NativeReference;
}
}
internal IntPtr Name;
internal IntPtr ShortName;
internal IntPtr LongName;
internal IntPtr Help;
internal IntPtr Next;
}
}
/// <summary>
/// Description of a module.
/// </summary>
public class ModuleDescription
{
public string Name;
public string ShortName;
public string LongName;
public string Help;
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment