Skip to content

Commit

Permalink
Projectを一つに統合
Browse files Browse the repository at this point in the history
  • Loading branch information
ikorin24 committed May 25, 2020
1 parent f219e69 commit 0a8d4e0
Show file tree
Hide file tree
Showing 12 changed files with 2,459 additions and 8 deletions.
6 changes: 0 additions & 6 deletions MMDTools.sln
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PMXParser", "PMXParser\PMXP
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Test", "Test\Test.csproj", "{61065D56-65C2-419D-91C9-5B9D49A7C18B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PMXParser.UM", "PMXParser.UM\PMXParser.UM.csproj", "{AD783164-260C-48E9-B62E-2A8AD11A44E9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -23,10 +21,6 @@ Global
{61065D56-65C2-419D-91C9-5B9D49A7C18B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{61065D56-65C2-419D-91C9-5B9D49A7C18B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{61065D56-65C2-419D-91C9-5B9D49A7C18B}.Release|Any CPU.Build.0 = Release|Any CPU
{AD783164-260C-48E9-B62E-2A8AD11A44E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AD783164-260C-48E9-B62E-2A8AD11A44E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AD783164-260C-48E9-B62E-2A8AD11A44E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AD783164-260C-48E9-B62E-2A8AD11A44E9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
111 changes: 111 additions & 0 deletions PMXParser/Unmanaged/DisposableRawArray.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace MMDTools.Unmanaged
{
[DebuggerTypeProxy(typeof(DisposableRawArrayDebuggerTypeProxy<>))]
[DebuggerDisplay("DisposableRawArray<{typeof(T).Name}>[{Length}]")]
[StructLayout(LayoutKind.Sequential)]
internal unsafe readonly struct DisposableRawArray<T> : IDisposable, IEquatable<DisposableRawArray<T>> where T : unmanaged, IDisposable
{
// RawArray, ReadOnlyRawArray と同じメモリレイアウトにしなければならない

private readonly IntPtr _ptr;
private readonly int _length;
public readonly int Length => _length;

public ref T this[int index]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => ref ((T*)_ptr)[index];
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal DisposableRawArray(int length)
{
if(length < 0) { throw new ArgumentOutOfRangeException(nameof(length), $"{nameof(length)} is negative value."); }
if(length == 0) {
this = default;
return;
}
var byteLen = sizeof(T) * length;
_ptr = Marshal.AllocHGlobal(byteLen);
new Span<T>((T*)_ptr, length).Fill(default);
_length = length;
UnmanagedMemoryChecker.RegisterNewAllocatedBytes(byteLen);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Dispose()
{
if(_ptr != IntPtr.Zero) {
foreach(var item in AsSpan()) {
item.Dispose();
}
UnmanagedMemoryChecker.RegisterReleasedBytes(sizeof(T) * Length);
Marshal.FreeHGlobal(_ptr);
Unsafe.AsRef(_ptr) = IntPtr.Zero; // Clear pointer into null for safety.
}
Unsafe.AsRef(Length) = 0;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Span<T> AsSpan() => new Span<T>((T*)_ptr, Length);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Span<T> AsSpan(int start)
{
if((uint)start >= (uint)Length) { throw new ArgumentOutOfRangeException(); }
return new Span<T>((T*)_ptr + start, Length);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Span<T> AsSpan(int start, int length)
{
if((uint)start >= (uint)Length) { throw new ArgumentOutOfRangeException(); }
if((uint)start + (uint)length >= (uint)Length) { throw new ArgumentOutOfRangeException(); }
return new Span<T>((T*)_ptr + start, length);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal ReadOnlyRawArray<TTo> AsReadOnly<TTo>() where TTo : unmanaged
{
if(sizeof(T) != sizeof(TTo)) { throw new InvalidCastException("Type size of element is mismatch."); }
ref var this_ = ref Unsafe.AsRef(this);
return Unsafe.As<DisposableRawArray<T>, ReadOnlyRawArray<TTo>>(ref this_);
}

public override bool Equals(object? obj) => obj is DisposableRawArray<T> array && Equals(array);

public bool Equals(DisposableRawArray<T> other)
{
return _ptr == other._ptr &&
_length == other._length;
}

public override int GetHashCode() => HashCode.Combine(_ptr, _length);
}

internal sealed class DisposableRawArrayDebuggerTypeProxy<T> where T : unmanaged, IDisposable
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly DisposableRawArray<T> _entity;

[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
public T[] Items
{
get
{
var items = new T[_entity.Length];
_entity.AsSpan().CopyTo(items);
return items;
}
}

public DisposableRawArrayDebuggerTypeProxy(DisposableRawArray<T> entity) => _entity = entity;
}
}
Loading

0 comments on commit 0a8d4e0

Please sign in to comment.