mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-18 18:14:37 +08:00
update EcsDebugUtility/ add cached meta
This commit is contained in:
parent
344f9caca2
commit
2cbdb4f994
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using DCFApixels.DragonECS.Internal;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
@ -56,11 +57,17 @@ namespace DCFApixels.DragonECS
|
|||||||
#pragma warning restore IL2070
|
#pragma warning restore IL2070
|
||||||
string[] values = new string[fields.Length];
|
string[] values = new string[fields.Length];
|
||||||
for (int i = 0; i < fields.Length; i++)
|
for (int i = 0; i < fields.Length; i++)
|
||||||
|
{
|
||||||
values[i] = (fields[i].GetValue(target) ?? "NULL").ToString();
|
values[i] = (fields[i].GetValue(target) ?? "NULL").ToString();
|
||||||
|
}
|
||||||
if (isWriteName)
|
if (isWriteName)
|
||||||
|
{
|
||||||
return $"{type.Name}({string.Join(", ", values)})";
|
return $"{type.Name}({string.Join(", ", values)})";
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
return $"({string.Join(", ", values)})";
|
return $"({string.Join(", ", values)})";
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
EcsDebug.PrintWarning($"Reflection is not available, the {nameof(AutoToString)} method does not work.");
|
EcsDebug.PrintWarning($"Reflection is not available, the {nameof(AutoToString)} method does not work.");
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
@ -153,7 +160,8 @@ namespace DCFApixels.DragonECS
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region GetColor
|
#region GetColor
|
||||||
private static Random random = new Random(100100100);
|
|
||||||
|
#region Auto Color
|
||||||
private static Dictionary<string, WordColor> _words = new Dictionary<string, WordColor>();
|
private static Dictionary<string, WordColor> _words = new Dictionary<string, WordColor>();
|
||||||
private class WordColor
|
private class WordColor
|
||||||
{
|
{
|
||||||
@ -171,7 +179,10 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
color = new WordColor();
|
color = new WordColor();
|
||||||
_words.Add(word, color);
|
_words.Add(word, color);
|
||||||
color.color = new MetaColor((byte)random.Next(), (byte)random.Next(), (byte)random.Next()).UpContrastColor() / 2;
|
|
||||||
|
MetaColor newColor = new MetaColor(BitsUtility.NextXorShiftState(word.GetHashCode()));
|
||||||
|
newColor = new MetaColor(newColor.r, newColor.g, newColor.b);
|
||||||
|
color.color = newColor.UpContrastColor() / 2;
|
||||||
}
|
}
|
||||||
color.wordsCount++;
|
color.wordsCount++;
|
||||||
colors.Add(color);
|
colors.Add(color);
|
||||||
@ -223,15 +234,20 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
subs = s.Substring(start, i - start);
|
subs = s.Substring(start, i - start);
|
||||||
if (subs.Length > 2 && subs.ToLower() != "system")
|
if (subs.Length > 2 && subs.ToLower() != "system")
|
||||||
|
{
|
||||||
words.Add(subs);
|
words.Add(subs);
|
||||||
|
}
|
||||||
start = i;
|
start = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
subs = s.Substring(start);
|
subs = s.Substring(start);
|
||||||
if (subs.Length > 2 && subs.ToLower() != "system")
|
if (subs.Length > 2 && subs.ToLower() != "system")
|
||||||
|
{
|
||||||
words.Add(subs);
|
words.Add(subs);
|
||||||
|
}
|
||||||
return words;
|
return words;
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
public static MetaColor GetColor(object obj)
|
public static MetaColor GetColor(object obj)
|
||||||
{
|
{
|
||||||
@ -239,7 +255,10 @@ namespace DCFApixels.DragonECS
|
|||||||
GetColor(intr.MetaSource) :
|
GetColor(intr.MetaSource) :
|
||||||
GetColor(type: obj.GetType());
|
GetColor(type: obj.GetType());
|
||||||
}
|
}
|
||||||
public static MetaColor GetColor<T>() => GetColor(typeof(T));
|
public static MetaColor GetColor<T>()
|
||||||
|
{
|
||||||
|
return GetColor(typeof(T));
|
||||||
|
}
|
||||||
public static MetaColor GetColor(Type type)
|
public static MetaColor GetColor(Type type)
|
||||||
{
|
{
|
||||||
var atr = type.GetCustomAttribute<MetaColorAttribute>();
|
var atr = type.GetCustomAttribute<MetaColorAttribute>();
|
||||||
@ -256,7 +275,10 @@ namespace DCFApixels.DragonECS
|
|||||||
TryGetColor(intr.MetaSource, out color) :
|
TryGetColor(intr.MetaSource, out color) :
|
||||||
TryGetColor(type: obj.GetType(), out color);
|
TryGetColor(type: obj.GetType(), out color);
|
||||||
}
|
}
|
||||||
public static bool TryGetColor<T>(out MetaColor color) => TryGetColor(typeof(T), out color);
|
public static bool TryGetColor<T>(out MetaColor color)
|
||||||
|
{
|
||||||
|
return TryGetColor(typeof(T), out color);
|
||||||
|
}
|
||||||
public static bool TryGetColor(Type type, out MetaColor color)
|
public static bool TryGetColor(Type type, out MetaColor color)
|
||||||
{
|
{
|
||||||
var atr = type.GetCustomAttribute<MetaColorAttribute>();
|
var atr = type.GetCustomAttribute<MetaColorAttribute>();
|
||||||
@ -277,7 +299,10 @@ namespace DCFApixels.DragonECS
|
|||||||
GetTags(intr.MetaSource) :
|
GetTags(intr.MetaSource) :
|
||||||
GetTags(type: obj.GetType());
|
GetTags(type: obj.GetType());
|
||||||
}
|
}
|
||||||
public static IReadOnlyCollection<string> GetTags<T>() => GetTags(typeof(T));
|
public static IReadOnlyCollection<string> GetTags<T>()
|
||||||
|
{
|
||||||
|
return GetTags(typeof(T));
|
||||||
|
}
|
||||||
public static IReadOnlyCollection<string> GetTags(Type type)
|
public static IReadOnlyCollection<string> GetTags(Type type)
|
||||||
{
|
{
|
||||||
var atr = type.GetCustomAttribute<MetaTagsAttribute>();
|
var atr = type.GetCustomAttribute<MetaTagsAttribute>();
|
||||||
@ -290,7 +315,10 @@ namespace DCFApixels.DragonECS
|
|||||||
TryGetTags(intr.MetaSource, out tags) :
|
TryGetTags(intr.MetaSource, out tags) :
|
||||||
TryGetTags(type: obj.GetType(), out tags);
|
TryGetTags(type: obj.GetType(), out tags);
|
||||||
}
|
}
|
||||||
public static bool TryGetTags<T>(out IReadOnlyCollection<string> tags) => TryGetTags(typeof(T), out tags);
|
public static bool TryGetTags<T>(out IReadOnlyCollection<string> tags)
|
||||||
|
{
|
||||||
|
return TryGetTags(typeof(T), out tags);
|
||||||
|
}
|
||||||
public static bool TryGetTags(Type type, out IReadOnlyCollection<string> tags)
|
public static bool TryGetTags(Type type, out IReadOnlyCollection<string> tags)
|
||||||
{
|
{
|
||||||
var atr = type.GetCustomAttribute<MetaTagsAttribute>();
|
var atr = type.GetCustomAttribute<MetaTagsAttribute>();
|
||||||
@ -311,8 +339,14 @@ namespace DCFApixels.DragonECS
|
|||||||
IsHidden(intr.MetaSource) :
|
IsHidden(intr.MetaSource) :
|
||||||
IsHidden(type: obj.GetType());
|
IsHidden(type: obj.GetType());
|
||||||
}
|
}
|
||||||
public static bool IsHidden<T>() => IsHidden(typeof(T));
|
public static bool IsHidden<T>()
|
||||||
public static bool IsHidden(Type type) => type.TryGetCustomAttribute(out MetaTagsAttribute atr) && atr.Tags.Contains(MetaTags.HIDDEN);
|
{
|
||||||
|
return IsHidden(typeof(T));
|
||||||
|
}
|
||||||
|
public static bool IsHidden(Type type)
|
||||||
|
{
|
||||||
|
return type.TryGetCustomAttribute(out MetaTagsAttribute atr) && atr.Tags.Contains(MetaTags.HIDDEN);
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region MetaSource
|
#region MetaSource
|
||||||
@ -326,15 +360,18 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region GenerateTypeDebugData
|
#region GenerateTypeMeta
|
||||||
public static TypeMetaData GenerateTypeDebugData(object obj)
|
public static TypeMetaData GenerateTypeMeta(object obj)
|
||||||
{
|
{
|
||||||
return obj is IEcsMetaProvider intr ?
|
return obj is IEcsMetaProvider intr ?
|
||||||
GenerateTypeDebugData(intr.MetaSource) :
|
GenerateTypeMeta(intr.MetaSource) :
|
||||||
GenerateTypeDebugData(type: obj.GetType());
|
GenerateTypeMeta(type: obj.GetType());
|
||||||
}
|
}
|
||||||
public static TypeMetaData GenerateTypeDebugData<T>() => GenerateTypeDebugData(typeof(T));
|
public static TypeMetaData GenerateTypeMeta<T>()
|
||||||
public static TypeMetaData GenerateTypeDebugData(Type type)
|
{
|
||||||
|
return GenerateTypeMeta(typeof(T));
|
||||||
|
}
|
||||||
|
public static TypeMetaData GenerateTypeMeta(Type type)
|
||||||
{
|
{
|
||||||
return new TypeMetaData(
|
return new TypeMetaData(
|
||||||
type,
|
type,
|
||||||
@ -342,7 +379,30 @@ namespace DCFApixels.DragonECS
|
|||||||
GetGroup(type),
|
GetGroup(type),
|
||||||
GetColor(type),
|
GetColor(type),
|
||||||
GetDescription(type),
|
GetDescription(type),
|
||||||
GetTags(type).ToArray());
|
GetTags(type));
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region GetCachedTypeMeta
|
||||||
|
private static readonly Dictionary<Type, TypeMetaDataCached> _metaCache = new Dictionary<Type, TypeMetaDataCached>();
|
||||||
|
public static TypeMetaDataCached GetCachedTypeMeta(object obj)
|
||||||
|
{
|
||||||
|
return obj is IEcsMetaProvider intr ?
|
||||||
|
GetCachedTypeMeta(intr.MetaSource) :
|
||||||
|
GetCachedTypeMeta(type: obj.GetType());
|
||||||
|
}
|
||||||
|
public static TypeMetaDataCached GetCachedTypeMeta<T>()
|
||||||
|
{
|
||||||
|
return GetCachedTypeMeta(typeof(T));
|
||||||
|
}
|
||||||
|
public static TypeMetaDataCached GetCachedTypeMeta(Type type)
|
||||||
|
{
|
||||||
|
if(_metaCache.TryGetValue(type, out TypeMetaDataCached result) == false)
|
||||||
|
{
|
||||||
|
result = new TypeMetaDataCached(type);
|
||||||
|
_metaCache.Add(type, result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -362,6 +422,8 @@ namespace DCFApixels.DragonECS
|
|||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public sealed class TypeMetaData
|
public sealed class TypeMetaData
|
||||||
{
|
{
|
||||||
@ -370,8 +432,8 @@ namespace DCFApixels.DragonECS
|
|||||||
public readonly MetaGroup group;
|
public readonly MetaGroup group;
|
||||||
public readonly MetaColor color;
|
public readonly MetaColor color;
|
||||||
public readonly string description;
|
public readonly string description;
|
||||||
public readonly string[] tags;
|
public readonly IReadOnlyCollection<string> tags;
|
||||||
public TypeMetaData(Type type, string name, MetaGroup group, MetaColor color, string description, string[] tags)
|
public TypeMetaData(Type type, string name, MetaGroup group, MetaColor color, string description, IReadOnlyCollection<string> tags)
|
||||||
{
|
{
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
@ -381,4 +443,164 @@ namespace DCFApixels.DragonECS
|
|||||||
this.tags = tags;
|
this.tags = tags;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class TypeMetaDataCached
|
||||||
|
{
|
||||||
|
internal readonly Type _type;
|
||||||
|
|
||||||
|
internal string _name;
|
||||||
|
internal MetaGroup _group;
|
||||||
|
internal MetaColor? _color;
|
||||||
|
internal string _description;
|
||||||
|
internal IReadOnlyCollection<string> _tags;
|
||||||
|
|
||||||
|
private TypeMetaData _typeMetaData = null;
|
||||||
|
private InitFlag _initFlags = InitFlag.None;
|
||||||
|
|
||||||
|
public TypeMetaDataCached(Type type)
|
||||||
|
{
|
||||||
|
_type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type Type
|
||||||
|
{
|
||||||
|
get { return _type; }
|
||||||
|
}
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(_name))
|
||||||
|
{
|
||||||
|
_name = EcsDebugUtility.GetName(_type);
|
||||||
|
_initFlags |= InitFlag.Name;
|
||||||
|
}
|
||||||
|
return _name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public MetaGroup Group
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_group.IsNull)
|
||||||
|
{
|
||||||
|
_group = EcsDebugUtility.GetGroup(_type);
|
||||||
|
_initFlags |= InitFlag.Group;
|
||||||
|
}
|
||||||
|
return _group;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public MetaColor Color
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_color.HasValue == false)
|
||||||
|
{
|
||||||
|
_color = EcsDebugUtility.GetColor(_type);
|
||||||
|
_initFlags |= InitFlag.Color;
|
||||||
|
}
|
||||||
|
return _color.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public string Description
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_description == null)
|
||||||
|
{
|
||||||
|
_description = EcsDebugUtility.GetDescription(_type);
|
||||||
|
_initFlags |= InitFlag.Description;
|
||||||
|
}
|
||||||
|
return _description;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public IReadOnlyCollection<string> Tags
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_tags == null)
|
||||||
|
{
|
||||||
|
_tags = EcsDebugUtility.GetTags(_type);
|
||||||
|
_initFlags |= InitFlag.Tags;
|
||||||
|
}
|
||||||
|
return _tags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public TypeMetaData AllData
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if(_typeMetaData == null)
|
||||||
|
{
|
||||||
|
_typeMetaData = new TypeMetaData(
|
||||||
|
Type,
|
||||||
|
Name,
|
||||||
|
Group,
|
||||||
|
Color,
|
||||||
|
Description,
|
||||||
|
Tags);
|
||||||
|
}
|
||||||
|
return _typeMetaData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InitializeAll()
|
||||||
|
{
|
||||||
|
if (_initFlags == InitFlag.All)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_ = Name;
|
||||||
|
_ = Group;
|
||||||
|
_ = Color;
|
||||||
|
_ = Description;
|
||||||
|
_ = Tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum InitFlag : byte
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Name = 1 << 0,
|
||||||
|
Group = 1 << 1,
|
||||||
|
Color = 1 << 2,
|
||||||
|
Description = 1 << 3,
|
||||||
|
Tags = 1 << 4,
|
||||||
|
All = Name | Group | Color | Description | Tags
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace DCFApixels.DragonECS.Internal
|
||||||
|
{
|
||||||
|
internal static class EcsTypeMeta
|
||||||
|
{
|
||||||
|
private static readonly Dictionary<Type, int> _codes = new Dictionary<Type, int>();
|
||||||
|
private static int _increment = 1;
|
||||||
|
public static int Count
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get { return _codes.Count; }
|
||||||
|
}
|
||||||
|
public static int Get(Type type)
|
||||||
|
{
|
||||||
|
if (!_codes.TryGetValue(type, out int code))
|
||||||
|
{
|
||||||
|
code = _increment++;
|
||||||
|
_codes.Add(type, code);
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static int Get<T>() { return EcsTypeCodeCache<T>.code; }
|
||||||
|
public static bool Has(Type type) { return _codes.ContainsKey(type); }
|
||||||
|
public static bool Has<T>() { return _codes.ContainsKey(typeof(T)); }
|
||||||
|
}
|
||||||
|
internal static class EcsTypeMetaCache<T>
|
||||||
|
{
|
||||||
|
public static readonly int code = EcsTypeMeta.Get(typeof(T));
|
||||||
|
}
|
||||||
}
|
}
|
@ -97,7 +97,9 @@ namespace DCFApixels.DragonECS
|
|||||||
byte minChannel = Math.Min(Math.Min(r, g), b);
|
byte minChannel = Math.Min(Math.Min(r, g), b);
|
||||||
byte maxChannel = Math.Max(Math.Max(r, g), b);
|
byte maxChannel = Math.Max(Math.Max(r, g), b);
|
||||||
if (maxChannel == minChannel)
|
if (maxChannel == minChannel)
|
||||||
|
{
|
||||||
return default;
|
return default;
|
||||||
|
}
|
||||||
float factor = 255f / (maxChannel - minChannel);
|
float factor = 255f / (maxChannel - minChannel);
|
||||||
return new MetaColor((byte)((r - minChannel) * factor), (byte)((g - minChannel) * factor), (byte)((b - minChannel) * factor));
|
return new MetaColor((byte)((r - minChannel) * factor), (byte)((g - minChannel) * factor), (byte)((b - minChannel) * factor));
|
||||||
}
|
}
|
||||||
|
@ -25,9 +25,25 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
public static readonly MetaGroup Empty = new MetaGroup(MetaGroupAttribute.Empty);
|
public static readonly MetaGroup Empty = new MetaGroup(MetaGroupAttribute.Empty);
|
||||||
private readonly MetaGroupAttribute _source;
|
private readonly MetaGroupAttribute _source;
|
||||||
public string Name => _source.name;
|
public string Name
|
||||||
public string RootCategory => _source.rootCategory;
|
{
|
||||||
public MetaGroup(MetaGroupAttribute source) => _source = source;
|
get { return _source.name; }
|
||||||
public string[] SplitCategories() => _source.SplitCategories();
|
}
|
||||||
|
public string RootCategory
|
||||||
|
{
|
||||||
|
get { return _source.rootCategory; }
|
||||||
|
}
|
||||||
|
public bool IsNull
|
||||||
|
{
|
||||||
|
get { return _source == null; }
|
||||||
|
}
|
||||||
|
public MetaGroup(MetaGroupAttribute source)
|
||||||
|
{
|
||||||
|
_source = source;
|
||||||
|
}
|
||||||
|
public string[] SplitCategories()
|
||||||
|
{
|
||||||
|
return _source.SplitCategories();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -521,24 +521,42 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static int NextXorShiftState(int state)
|
public static int NextXorShiftState(int state)
|
||||||
{
|
{
|
||||||
unchecked { return (state << 13) ^ (state >> 17) ^ (state << 5); };
|
unchecked
|
||||||
|
{
|
||||||
|
return (int)NextXorShiftState((uint)state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static uint NextXorShiftState(uint state)
|
public static uint NextXorShiftState(uint state)
|
||||||
{
|
{
|
||||||
unchecked { return (state << 13) ^ (state >> 17) ^ (state << 5); };
|
unchecked
|
||||||
|
{
|
||||||
|
state ^= state << 13;
|
||||||
|
state ^= state >> 17;
|
||||||
|
state ^= state << 5;
|
||||||
|
return state;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static long NextXorShiftState(long state)
|
public static long NextXorShiftState(long state)
|
||||||
{
|
{
|
||||||
const long m = 0x2545F491_4F6CDD1D;
|
unchecked
|
||||||
unchecked { return ((state >> 13) ^ (state << 25) ^ (state >> 27)) * m; };
|
{
|
||||||
|
return (long)NextXorShiftState((ulong)state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static ulong NextXorShiftState(ulong state)
|
public static ulong NextXorShiftState(ulong state)
|
||||||
|
{
|
||||||
|
unchecked
|
||||||
{
|
{
|
||||||
const ulong m = 0x2545F491_4F6CDD1D;
|
const ulong m = 0x2545F491_4F6CDD1D;
|
||||||
unchecked { return ((state >> 13) ^ (state << 25) ^ (state >> 27)) * m; };
|
state ^= state >> 13;
|
||||||
|
state ^= state << 25;
|
||||||
|
state ^= state >> 27;
|
||||||
|
state *= m;
|
||||||
|
return state;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user