From 3cc127ebbcb8b9d63f6f2f6224517fed49b413e5 Mon Sep 17 00:00:00 2001 From: the_fiddler Date: Sun, 19 Jul 2009 20:56:17 +0000 Subject: [PATCH] Improved BlittableValueType API (Check, StrideOf methods). Added AL.BufferData method. --- Source/OpenTK/Audio/OpenAL/AL/AL.cs | 22 ++- Source/OpenTK/BlittableValueType.cs | 236 ++++++++++++++++++++++++---- 2 files changed, 223 insertions(+), 35 deletions(-) diff --git a/Source/OpenTK/Audio/OpenAL/AL/AL.cs b/Source/OpenTK/Audio/OpenAL/AL/AL.cs index 1e23a12e..8a12923f 100644 --- a/Source/OpenTK/Audio/OpenAL/AL/AL.cs +++ b/Source/OpenTK/Audio/OpenAL/AL/AL.cs @@ -1412,7 +1412,7 @@ namespace OpenTK.Audio /// This function fills a buffer with audio buffer. All the pre-defined formats are PCM buffer, but this function may be used by extensions to load other buffer types as well. /// buffer Handle/Name to be filled with buffer. /// Format type from among the following: ALFormat.Mono8, ALFormat.Mono16, ALFormat.Stereo8, ALFormat.Stereo16. - /// Pointer to the audio buffer. YOU MUST PIN THIS MANUALLY. + /// Pointer to a pinned audio buffer. /// The size of the audio buffer in bytes. /// The frequency of the audio buffer. [CLSCompliant(false), DllImport(AL.Lib, EntryPoint = "alBufferData", ExactSpelling = true, CallingConvention = AL.Style), SuppressUnmanagedCodeSecurity()] @@ -1422,7 +1422,7 @@ namespace OpenTK.Audio /// This function fills a buffer with audio buffer. All the pre-defined formats are PCM buffer, but this function may be used by extensions to load other buffer types as well. /// buffer Handle/Name to be filled with buffer. /// Format type from among the following: ALFormat.Mono8, ALFormat.Mono16, ALFormat.Stereo8, ALFormat.Stereo16. - /// Pointer to the audio buffer. YOU MUST PIN THIS MANUALLY. + /// Pointer to a pinned audio buffer. /// The size of the audio buffer in bytes. /// The frequency of the audio buffer. [CLSCompliant(true)] @@ -1431,10 +1431,28 @@ namespace OpenTK.Audio BufferData((uint)bid, format, buffer, size, freq); } + /// This function fills a buffer with audio buffer. All the pre-defined formats are PCM buffer, but this function may be used by extensions to load other buffer types as well. + /// buffer Handle/Name to be filled with buffer. + /// Format type from among the following: ALFormat.Mono8, ALFormat.Mono16, ALFormat.Stereo8, ALFormat.Stereo16. + /// The audio buffer. + /// The size of the audio buffer in bytes. + /// The frequency of the audio buffer. + public static void BufferData(int bid, ALFormat format, TBuffer[] buffer, int size, int freq) + where TBuffer : struct + { + if (!BlittableValueType.Check(buffer)) + throw new ArgumentException("buffer"); + + GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned); + try { BufferData(bid, format, handle.AddrOfPinnedObject(), size, freq); } + finally { handle.Free(); } + } + /// This function fills a buffer with audio buffer (PCM format). /// Buffer Handle/Name to be filled with buffer. /// A SoundData object containing the buffer to upload. [CLSCompliant(false)] + [Obsolete("Use BufferData instead.")] public static void BufferData(uint bid, SoundData buffer) { unsafe diff --git a/Source/OpenTK/BlittableValueType.cs b/Source/OpenTK/BlittableValueType.cs index 03744a75..dc9c4c4d 100644 --- a/Source/OpenTK/BlittableValueType.cs +++ b/Source/OpenTK/BlittableValueType.cs @@ -1,28 +1,28 @@ -#region License -// -// The Open Toolkit Library License -// -// Copyright (c) 2006 - 2009 the Open Toolkit library. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do -// so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// +#region License +// +// The Open Toolkit Library License +// +// Copyright (c) 2006 - 2009 the Open Toolkit library. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do +// so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// #endregion using System; @@ -34,6 +34,8 @@ using System.Reflection; namespace OpenTK { + #region BlittableValueType + /// /// Checks whether the specified type parameter is a blittable value type. /// @@ -41,26 +43,58 @@ namespace OpenTK /// A blittable value type is a struct that only references other value types recursively, /// which allows it to be passed to unmanaged code directly. /// - /// The struct to check. - /// Raised when T is not a blittable value type. - public struct BlittableValueType where T : struct + public static class BlittableValueType where T : struct { + #region Fields + + static readonly Type Type; + + #endregion + + #region Constructors + + static BlittableValueType() + { + Type = typeof(T); + } + + #endregion + + #region Public Members + /// /// Gets the size of the type in bytes. /// public static readonly int Stride = Marshal.SizeOf(typeof(T)); - static BlittableValueType() + #region Check + + /// + /// Checks whether the current typename T is blittable. + /// + public static bool Check() + { + return Check(Type); + } + + /// + /// Checks whether type is a blittable value type. + /// + /// A System.Type to check. + public static bool Check(Type type) { - Type type = typeof(T); - if (!CheckStructLayoutAttribute(type)) Debug.Print("Warning: type {0} does not specify a StructLayoutAttribute with Pack=1. The memory layout of the struct may change between platforms.", type.Name); - if (!CheckType(type)) - throw new NotSupportedException(String.Format("Type {0} contains non-primitive fields.", type.Name)); + return CheckType(type); } + #endregion + + #endregion + + #region Private Members + // Checks whether the parameter is a primitive type or consists of primitive types recursively. // Throws a NotSupportedException if it is not. static bool CheckType(Type type) @@ -94,5 +128,141 @@ namespace OpenTK return true; } + + #endregion } + + #endregion + + #region BlittableValueType + + /// + /// Checks whether the specified type parameter is a blittable value type. + /// + /// + /// A blittable value type is a struct that only references other value types recursively, + /// which allows it to be passed to unmanaged code directly. + /// + public static class BlittableValueType + { + #region Check + + /// + /// Checks whether type is a blittable value type. + /// + /// An instance of the type to check. + public static bool Check(T type) where T : struct + { + return BlittableValueType.Check(); + } + + /// + /// Checks whether type is a blittable value type. + /// + /// An instance of the type to check. + public static bool Check(T[] type) where T : struct + { + return BlittableValueType.Check(); + } + + /// + /// Checks whether type is a blittable value type. + /// + /// An instance of the type to check. + public static bool Check(T[,] type) where T : struct + { + return BlittableValueType.Check(); + } + + /// + /// Checks whether type is a blittable value type. + /// + /// An instance of the type to check. + public static bool Check(T[, ,] type) where T : struct + { + return BlittableValueType.Check(); + } + + /// + /// Checks whether type is a blittable value type. + /// + /// An instance of the type to check. + [CLSCompliant(false)] + public static bool Check(T[][] type) where T : struct + { + return BlittableValueType.Check(); + } + + #endregion + + #region From + + /// + /// Returns the size of the specified value type in bytes. + /// + /// The value type. Must be blittable. + /// An instance of the value type. + /// An integer, specifying the size of the type in bytes. + /// Occurs when type is not blittable. + public static int StrideOf(T type) + where T : struct + { + if (!Check(type)) + throw new ArgumentException("type"); + + return BlittableValueType.Stride; + } + + /// + /// Returns the size of a single array element in bytes. + /// + /// The value type. + /// An instance of the value type. + /// An integer, specifying the size of the type in bytes. + /// Occurs when type is not blittable. + public static int StrideOf(T[] type) + where T : struct + { + if (!Check(type)) + throw new ArgumentException("type"); + + return BlittableValueType.Stride; + } + + /// + /// Returns the size of a single array element in bytes. + /// + /// The value type. + /// An instance of the value type. + /// An integer, specifying the size of the type in bytes. + /// Occurs when type is not blittable. + public static int StrideOf(T[,] type) + where T : struct + { + if (!Check(type)) + throw new ArgumentException("type"); + + return BlittableValueType.Stride; + } + + /// + /// Returns the size of a single array element in bytes. + /// + /// The value type. + /// An instance of the value type. + /// An integer, specifying the size of the type in bytes. + /// Occurs when type is not blittable. + public static int StrideOf(T[, ,] type) + where T : struct + { + if (!Check(type)) + throw new ArgumentException("type"); + + return BlittableValueType.Stride; + } + + #endregion + } + + #endregion }