A game framework written with osu! in mind.
at master 105 lines 3.6 kB view raw
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. 2// See the LICENCE file in the repository root for full licence text. 3 4using System; 5using ManagedBass; 6using osu.Framework.Allocation; 7using osu.Framework.Platform; 8 9namespace osu.Framework.Audio.Callbacks 10{ 11 /// <summary> 12 /// Wrapper on <see cref="FileProcedures"/> to provide functionality in <see cref="BassCallback"/>. 13 /// Can delegate to a class implementing the <see cref="IFileProcedures"/> interface. 14 /// </summary> 15 public class FileCallbacks : BassCallback 16 { 17 public FileProcedures Callbacks { get; private set; } 18 19 private FileProcedures instanceProcedures => new FileProcedures 20 { 21 Read = Read, 22 Close = Close, 23 Length = Length, 24 Seek = Seek 25 }; 26 27 private static readonly FileProcedures static_procedures = new FileProcedures 28 { 29 Read = readCallback, 30 Close = closeCallback, 31 Length = lengthCallback, 32 Seek = seekCallback 33 }; 34 35 private readonly IFileProcedures implementation; 36 37 private readonly FileProcedures procedures; 38 39 public FileCallbacks(IFileProcedures implementation) 40 { 41 Callbacks = RuntimeInfo.SupportsJIT ? instanceProcedures : static_procedures; 42 this.implementation = implementation; 43 procedures = null; 44 } 45 46 public FileCallbacks(FileProcedures procedures) 47 { 48 Callbacks = RuntimeInfo.SupportsJIT ? instanceProcedures : static_procedures; 49 this.procedures = procedures; 50 implementation = null; 51 } 52 53 public long Length(IntPtr user) => implementation?.Length(user) ?? procedures.Length(user); 54 55 public bool Seek(long offset, IntPtr user) => implementation?.Seek(offset, user) ?? procedures.Seek(offset, user); 56 57 public int Read(IntPtr buffer, int length, IntPtr user) => implementation?.Read(buffer, length, user) ?? procedures.Read(buffer, length, user); 58 59 public void Close(IntPtr user) 60 { 61 if (implementation != null) 62 implementation.Close(user); 63 else 64 procedures.Close(user); 65 } 66 67 [MonoPInvokeCallback(typeof(FileReadProcedure))] 68 private static int readCallback(IntPtr buffer, int length, IntPtr user) 69 { 70 var ptr = new ObjectHandle<FileCallbacks>(user); 71 if (ptr.GetTarget(out FileCallbacks target)) 72 return target.Read(buffer, length, user); 73 74 return 0; 75 } 76 77 [MonoPInvokeCallback(typeof(FileCloseProcedure))] 78 private static void closeCallback(IntPtr user) 79 { 80 var ptr = new ObjectHandle<FileCallbacks>(user); 81 if (ptr.GetTarget(out FileCallbacks target)) 82 target.Close(user); 83 } 84 85 [MonoPInvokeCallback(typeof(FileLengthProcedure))] 86 private static long lengthCallback(IntPtr user) 87 { 88 var ptr = new ObjectHandle<FileCallbacks>(user); 89 if (ptr.GetTarget(out FileCallbacks target)) 90 return target.Length(user); 91 92 return 0; 93 } 94 95 [MonoPInvokeCallback(typeof(FileSeekProcedure))] 96 private static bool seekCallback(long offset, IntPtr user) 97 { 98 var ptr = new ObjectHandle<FileCallbacks>(user); 99 if (ptr.GetTarget(out FileCallbacks target)) 100 return target.Seek(offset, user); 101 102 return false; 103 } 104 } 105}