<commit_before>﻿using System;
using System.Collections.Generic;
using System.IO;

using CSGL.Vulkan.Unmanaged;

namespace CSGL.Vulkan {
    public class ShaderModuleCreateInfo {
        public byte[] Data { get; set; }

        public ShaderModuleCreateInfo(byte[] data) {
            Data = data;
        }

        public ShaderModuleCreateInfo(Stream stream) {
            int length = (int)(stream.Length - stream.Position);
            byte[] data = new byte[length];
            stream.Read(data, 0, length);
            Data = data;
        }
    }

    public class ShaderModule : IDisposable, INative<VkShaderModule> {
        VkShaderModule shaderModule;
        bool disposed = false;

        Device device;

        vkCreateShaderModuleDelegate createShaderModule;
        vkDestroyShaderModuleDelegate destroyShaderModule;

        public VkShaderModule Native {
            get {
                return shaderModule;
            }
        }

        public ShaderModule(Device device, ShaderModuleCreateInfo info) {
            if (device == null) throw new ArgumentNullException(nameof(device));
            if (info == null) throw new ArgumentNullException(nameof(info));
            if (info.Data == null) throw new ArgumentNullException(nameof(info.Data));

            this.device = device;

            createShaderModule = device.Commands.createShaderModule;
            destroyShaderModule = device.Commands.destroyShaderModule;

            CreateShader(info);
        }

        void CreateShader(ShaderModuleCreateInfo mInfo) {
            VkShaderModuleCreateInfo info = new VkShaderModuleCreateInfo();
            info.sType = VkStructureType.ShaderModuleCreateInfo;
            info.codeSize = (ulong)mInfo.Data.LongLength;

            var dataPinned = new PinnedArray<byte>(mInfo.Data);
            info.pCode = dataPinned.Address;

            using (dataPinned) {
                var result = createShaderModule(device.Native, ref info, device.Instance.AllocationCallbacks, out shaderModule);
                if (result != VkResult.Success) throw new ShaderModuleException(string.Format("Error creating shader module: {0}"));
            }
        }

        public void Dispose() {
            if (disposed) return;

            destroyShaderModule(device.Native, shaderModule, device.Instance.AllocationCallbacks);

            disposed = true;
        }
    }

    public class ShaderModuleException : Exception {
        public ShaderModuleException(string message) : base(message) { }
    }
}
<commit_msg>Implement Dispose pattern<commit_after>﻿using System;
using System.Collections.Generic;
using System.IO;

using CSGL.Vulkan.Unmanaged;

namespace CSGL.Vulkan {
    public class ShaderModuleCreateInfo {
        public byte[] Data { get; set; }

        public ShaderModuleCreateInfo(byte[] data) {
            Data = data;
        }

        public ShaderModuleCreateInfo(Stream stream) {
            int length = (int)(stream.Length - stream.Position);
            byte[] data = new byte[length];
            stream.Read(data, 0, length);
            Data = data;
        }
    }

    public class ShaderModule : IDisposable, INative<VkShaderModule> {
        VkShaderModule shaderModule;
        bool disposed = false;

        Device device;

        vkCreateShaderModuleDelegate createShaderModule;
        vkDestroyShaderModuleDelegate destroyShaderModule;

        public VkShaderModule Native {
            get {
                return shaderModule;
            }
        }

        public ShaderModule(Device device, ShaderModuleCreateInfo info) {
            if (device == null) throw new ArgumentNullException(nameof(device));
            if (info == null) throw new ArgumentNullException(nameof(info));
            if (info.Data == null) throw new ArgumentNullException(nameof(info.Data));

            this.device = device;

            createShaderModule = device.Commands.createShaderModule;
            destroyShaderModule = device.Commands.destroyShaderModule;

            CreateShader(info);
        }

        void CreateShader(ShaderModuleCreateInfo mInfo) {
            VkShaderModuleCreateInfo info = new VkShaderModuleCreateInfo();
            info.sType = VkStructureType.ShaderModuleCreateInfo;
            info.codeSize = (ulong)mInfo.Data.LongLength;

            var dataPinned = new PinnedArray<byte>(mInfo.Data);
            info.pCode = dataPinned.Address;

            using (dataPinned) {
                var result = createShaderModule(device.Native, ref info, device.Instance.AllocationCallbacks, out shaderModule);
                if (result != VkResult.Success) throw new ShaderModuleException(string.Format("Error creating shader module: {0}"));
            }
        }

        public void Dispose() {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        void Dispose(bool disposing) {
            if (disposed) return;

            destroyShaderModule(device.Native, shaderModule, device.Instance.AllocationCallbacks);

            disposed = true;
        }

        ~ShaderModule() {
            Dispose(false);
        }
    }

    public class ShaderModuleException : Exception {
        public ShaderModuleException(string message) : base(message) { }
    }
}

{'fraction_non_alphanumeric': 0.0835385489676075, 'fraction_numerical': 0.0007577192650123129, 'mean_word_length': 2.281541330018645, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4502728', 'n_tokens_mistral': 1384, 'n_tokens_neox': 1327, 'n_words': 303}