1.5, added stuff, fixed stuff
- mod icon - fixes for new vanilla clipping issues - GenClosest optimization improving repairing, wardening, tending jobs - caching for new ListerBuildings methods - DynamicDrawManager single threading - Type.GetFields caching - StatParts analyzer category - removed duplicate steam warning and optionally window - added exception handling for debug menu, incidentworker, Graphic_Multi, InitializeComps, making all those now log what mod broke and not cause black screens or whatever
This commit is contained in:
@@ -1,31 +0,0 @@
|
||||
// Copyright (c) 2023 bradson
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
#if false
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace PerformanceFish.Experimental;
|
||||
|
||||
#pragma warning disable CS8500
|
||||
/// <summary>
|
||||
/// References within fixed size buffers don't get tracked by the GC. This leads to memory corruption. Don't use
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public unsafe struct InlineArray256<T> where T : class
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
private T _firstEntry;
|
||||
|
||||
[FieldOffset(0)]
|
||||
private fixed ulong _entries[256];
|
||||
|
||||
public T this[int index]
|
||||
{
|
||||
get => (&_firstEntry)[index];
|
||||
set => (&_firstEntry)[index] = value;
|
||||
}
|
||||
}
|
||||
#pragma warning restore CS8500
|
||||
#endif
|
||||
@@ -5,54 +5,254 @@
|
||||
|
||||
#if false
|
||||
using System.Runtime.InteropServices;
|
||||
// ReSharper disable PrivateFieldCanBeConvertedToLocalVariable
|
||||
|
||||
namespace PerformanceFish.Experimental;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public unsafe struct UnalignedPointer
|
||||
{
|
||||
private fixed byte _data[6]; // 48bit
|
||||
|
||||
// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] // 48bit
|
||||
// private byte[] _data;
|
||||
// 48 bit
|
||||
private ushort
|
||||
_top,
|
||||
_mid,
|
||||
_bot;
|
||||
|
||||
public void* Value
|
||||
{
|
||||
get
|
||||
{
|
||||
fixed (void* value = _data)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
var result = (void*)(Unsafe.As<ushort, ulong>(ref _top) & 0x0000_FFFF_FFFF_FFFF);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public UnalignedPointer(void* pointer)
|
||||
{
|
||||
fixed (UnalignedPointer* instance = &this)
|
||||
{
|
||||
instance->_data = (byte*)pointer;
|
||||
}
|
||||
Unsafe.As<ushort, uint>(ref _top) = (uint)(ulong)pointer;
|
||||
_bot = (ushort)((ulong)pointer >> 32);
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe struct TaggedPointer
|
||||
{
|
||||
private void* _data;
|
||||
private const ulong
|
||||
LowerBitMask = ~(ulong.MaxValue >> 3),
|
||||
UpperBitMask = 0x0000_0000_0000_FFFF,
|
||||
ValueBitMask = ~LowerBitMask & ~UpperBitMask;
|
||||
|
||||
private ulong _data;
|
||||
|
||||
public void* Value
|
||||
{
|
||||
get
|
||||
{
|
||||
var value = _data;
|
||||
var value = (void*)(_data & ValueBitMask);
|
||||
return value;
|
||||
}
|
||||
set => _data = (_data & ~ValueBitMask) | ((ulong)value & ValueBitMask);
|
||||
}
|
||||
|
||||
public ushort UpperBits => (ushort)_data;
|
||||
public ushort UpperBits
|
||||
{
|
||||
get => (ushort)(_data & UpperBitMask);
|
||||
set => _data = (_data & ~UpperBitMask) | (value & UpperBitMask);
|
||||
}
|
||||
|
||||
public byte LowerBits => (byte)_data;
|
||||
public byte LowerBits
|
||||
{
|
||||
get => (byte)((_data & LowerBitMask) >> 61);
|
||||
set => _data = (_data & ~LowerBitMask) | (((ulong)value << 61) & LowerBitMask);
|
||||
}
|
||||
|
||||
public TaggedPointer(void* pointer) => _data = pointer;
|
||||
public TaggedPointer(void* pointer) => Value = pointer;
|
||||
|
||||
public TaggedPointer(void* pointer, ushort upperBits, byte lowerBits)
|
||||
=> _data = ((ulong)pointer & ValueBitMask)
|
||||
| (upperBits & UpperBitMask)
|
||||
| (((ulong)lowerBits << 61) & LowerBitMask);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
public struct UInt48 : IComparable<UInt48>, IEquatable<UInt48>
|
||||
{
|
||||
public const ulong MaxValue = ulong.MaxValue >> 16;
|
||||
|
||||
private ushort
|
||||
_top,
|
||||
_mid,
|
||||
_bot;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public UInt48(ulong value)
|
||||
{
|
||||
Unsafe.As<ushort, uint>(ref _top) = (uint)value;
|
||||
_bot = (ushort)(value >> 32);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(UInt48 other) => this == other;
|
||||
|
||||
public override bool Equals(object? obj) => obj is UInt48 value && this == value;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public int CompareTo(UInt48 other) => ((ulong)this).CompareTo(other);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override int GetHashCode() => Unsafe.As<ushort, int>(ref _top) ^ _bot;
|
||||
|
||||
public override string ToString() => ((ulong)this).ToString();
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator ==(UInt48 left, UInt48 right)
|
||||
{
|
||||
var x = left;
|
||||
var y = right;
|
||||
return (Unsafe.As<ushort, uint>(ref x._top) == Unsafe.As<ushort, uint>(ref y._top)) & (x._bot == y._bot);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator !=(UInt48 left, UInt48 right) => !(left == right);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator <(UInt48 left, UInt48 right) => (ulong)left < right;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator <=(UInt48 left, UInt48 right) => (ulong)left <= right;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator >(UInt48 left, UInt48 right) => (ulong)left > right;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator >=(UInt48 left, UInt48 right) => (ulong)left >= right;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static implicit operator ulong(UInt48 value)
|
||||
{
|
||||
var temp = value;
|
||||
return Unsafe.As<ushort, ulong>(ref temp._top) & MaxValue;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static implicit operator long(UInt48 value)
|
||||
{
|
||||
var temp = value;
|
||||
return Unsafe.As<ushort, long>(ref temp._top) & (long)MaxValue;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static explicit operator UInt48(ulong value)
|
||||
{
|
||||
Unsafe.SkipInit(out UInt48 result);
|
||||
Unsafe.As<ushort, uint>(ref result._top) = (uint)value;
|
||||
result._bot = (ushort)(value >> 32);
|
||||
return result;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static explicit operator UInt48(long value) => (UInt48)(ulong)value;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static explicit operator UInt48(uint value)
|
||||
{
|
||||
Unsafe.SkipInit(out UInt48 result);
|
||||
Unsafe.As<ushort, uint>(ref result._top) = value;
|
||||
result._bot = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static explicit operator UInt48(int value) => (UInt48)(uint)value;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
public struct Int48 : IComparable<Int48>, IEquatable<Int48>
|
||||
{
|
||||
public const long MaxValue = long.MaxValue >> 16;
|
||||
|
||||
private ushort
|
||||
_top,
|
||||
_mid,
|
||||
_bot;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public Int48(long value)
|
||||
{
|
||||
Unsafe.As<ushort, uint>(ref _top) = (uint)value;
|
||||
_bot = (ushort)((((ulong)value >> 32) & (ulong)short.MaxValue)
|
||||
| ((ulong)(value & long.MinValue) >> 48));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(Int48 other) => this == other;
|
||||
|
||||
public override bool Equals(object? obj) => obj is Int48 value && this == value;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public int CompareTo(Int48 other) => ((long)this).CompareTo(other);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override int GetHashCode() => Unsafe.As<ushort, int>(ref _top) ^ _bot;
|
||||
|
||||
public override string ToString() => ((long)this).ToString();
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator ==(Int48 left, Int48 right)
|
||||
{
|
||||
var x = left;
|
||||
var y = right;
|
||||
return (Unsafe.As<ushort, uint>(ref x._top) == Unsafe.As<ushort, uint>(ref y._top)) & (x._bot == y._bot);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator !=(Int48 left, Int48 right) => !(left == right);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator <(Int48 left, Int48 right) => (long)left < right;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator <=(Int48 left, Int48 right) => (long)left <= right;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator >(Int48 left, Int48 right) => (long)left > right;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator >=(Int48 left, Int48 right) => (long)left >= right;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static implicit operator ulong(Int48 value) => (ulong)(long)value;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static implicit operator long(Int48 value)
|
||||
{
|
||||
var temp = value;
|
||||
return (Unsafe.As<ushort, long>(ref temp._top) & MaxValue)
|
||||
| (long)(((ulong)temp._bot << 48) & unchecked((ulong)long.MinValue));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static explicit operator Int48(ulong value) => (Int48)(long)value;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static explicit operator Int48(long value)
|
||||
{
|
||||
Unsafe.SkipInit(out Int48 result);
|
||||
Unsafe.As<ushort, uint>(ref result._top) = (uint)value;
|
||||
result._bot = (ushort)((((ulong)value >> 32) & (ulong)short.MaxValue)
|
||||
| ((ulong)(value & long.MinValue) >> 48));
|
||||
return result;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static explicit operator Int48(uint value) => (Int48)(int)value;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static explicit operator Int48(int value)
|
||||
{
|
||||
Unsafe.SkipInit(out Int48 result);
|
||||
Unsafe.As<ushort, uint>(ref result._top) = (uint)(value & int.MaxValue);
|
||||
result._bot = (ushort)((uint)(value & int.MinValue) >> 16);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user