Editor/Services/ArchHash.cs
using System;
using Sandbox;
namespace Sunless.Architecture;
// FNV-1a 64-bit; order matters — swapped layers are a different build.
public static class ArchHash {
public const ulong Seed = 14695981039346656037ul;
const ulong Prime = 1099511628211ul;
public static ulong Fold( ulong hash, ulong value ) {
for ( var shift = 0; shift < 64; shift += 8 ) {
hash = (hash ^ ((value >> shift) & 0xFF)) * Prime;
}
return hash;
}
public static ulong Fold( ulong hash, int value ) => Fold( hash, (ulong)(uint)value );
public static ulong Fold( ulong hash, bool value ) => Fold( hash, value ? 1 : 0 );
// Collapse -0 to +0 so the cache does not split on an invisible sign bit.
public static ulong Fold( ulong hash, float value ) {
return Fold( hash, (ulong)(uint)BitConverter.SingleToInt32Bits( value == 0f ? 0f : value ) );
}
public static ulong Fold( ulong hash, Vector2 value ) => Fold( Fold( hash, value.x ), value.y );
public static ulong Fold( ulong hash, Vector3 value ) => Fold( Fold( Fold( hash, value.x ), value.y ), value.z );
public static ulong Fold( ulong hash, string value ) {
if ( value is null ) {
return Fold( hash, -1 );
}
hash = Fold( hash, value.Length );
foreach ( var character in value ) {
hash = Fold( hash, character );
}
return hash;
}
public static ulong Of( string value ) => Fold( Seed, value );
}