修改水

This commit is contained in:
2026-01-01 22:00:33 +08:00
parent 040a222bd6
commit 9ceffccd39
1800 changed files with 103929 additions and 139495 deletions

View File

@@ -0,0 +1,49 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
using System;
using UnityEngine;
namespace WaveHarmonic.Crest.Utility
{
/// <summary>
/// Circular buffer to store a multiple sets of data.
/// </summary>
sealed class BufferedData<T>
{
readonly T[] _Buffers;
int _CurrentFrameIndex;
public T Current { get => _Buffers[_CurrentFrameIndex]; set => _Buffers[_CurrentFrameIndex] = value; }
public int Size => _Buffers.Length;
public BufferedData(int size, Func<T> initialize)
{
_Buffers = new T[size];
for (var i = 0; i < size; i++)
{
_Buffers[i] = initialize();
}
}
public T Previous(int framesBack)
{
Debug.Assert(framesBack >= 0 && framesBack < _Buffers.Length);
return _Buffers[(_CurrentFrameIndex - framesBack + _Buffers.Length) % _Buffers.Length];
}
public void Flip()
{
_CurrentFrameIndex = (_CurrentFrameIndex + 1) % _Buffers.Length;
}
public void RunLambda(Action<T> lambda)
{
foreach (var buffer in _Buffers)
{
lambda(buffer);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c5666bcd450914e3e980a32dd866957e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,109 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
using System.Collections;
using System.Collections.Generic;
namespace WaveHarmonic.Crest.Utility
{
/// <summary>
/// This is a list this is meant to be similar in behaviour to the C#
/// SortedList, but without allocations when used directly in a foreach loop.
///
/// It works by using a regular list as as backing and ensuring that it is
/// sorted when the enumerator is accessed and used. This is a simple approach
/// that means we avoid sorting each time an element is added, and helps us
/// avoid having to develop our own more complex data structure.
/// </summary>
sealed class SortedList<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable
{
public int Count => _BackingList.Count;
readonly List<KeyValuePair<TKey, TValue>> _BackingList = new();
readonly System.Comparison<TKey> _Comparison;
bool _NeedsSorting = false;
int Comparison(KeyValuePair<TKey, TValue> x, KeyValuePair<TKey, TValue> y)
{
return _Comparison(x.Key, y.Key);
}
public SortedList(System.Comparison<TKey> comparison)
{
// We provide the only constructors that SortedList provides that
// we need. We wrap the input IComparer to ensure that our backing list
// is sorted in the same way a SortedList would be with the same one.
_Comparison = comparison;
}
public void Add(TKey key, TValue value)
{
_BackingList.Add(new(key, value));
_NeedsSorting = true;
}
public bool Remove(TValue value)
{
// This remove function has a fairly high complexity, as we need to search
// the list for a matching Key-Value pair, and then remove it. However,
// for the small lists we work with this is fine, as we don't use this
// function more often. But it's worth bearing in mind if we decide to
// expand where we use this list. At that point we might need to take a
// different approach.
var removeIndex = -1;
var index = 0;
foreach (var item in _BackingList)
{
if (item.Value.Equals(value))
{
removeIndex = index;
}
index++;
}
if (removeIndex > -1)
{
// Remove method produces garbage.
_BackingList.RemoveAt(removeIndex);
}
return removeIndex > -1;
}
public void Clear()
{
_BackingList.Clear();
_NeedsSorting = false;
}
#region GetEnumerator
public List<KeyValuePair<TKey, TValue>>.Enumerator GetEnumerator()
{
ResortArrays();
return _BackingList.GetEnumerator();
}
IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator()
{
return GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
void ResortArrays()
{
if (_NeedsSorting)
{
// @GC: Allocates 112B.
_BackingList.Sort(Comparison);
}
_NeedsSorting = false;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f796ed8d9971b4795b28bcb1c4dc3a01
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,58 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
using System.Collections.Generic;
using UnityEngine;
namespace WaveHarmonic.Crest.Utility.Internal
{
/// <summary>
/// A less rigid stack implementation which is easier to use. Prevents duplicates.
/// </summary>
/// <typeparam name="T">Type to store.</typeparam>
public sealed class Stack<T>
{
readonly List<T> _Items = new();
internal Stack() { }
/// <summary>
/// Add item to the end of the stack.
/// </summary>
/// <param name="item">Item to add.</param>
public void Push(T item)
{
Debug.Assert(item != null, "Null item pushed");
// Remove any instances of item already in the stack.
Pop(item);
// Add it to the top.
_Items.Add(item);
}
/// <summary>
/// Removes all instances of item.
/// </summary>
/// <param name="item">The item to be removed.</param>
public void Pop(T item)
{
Debug.Assert(item != null, "Null item popped");
_Items.RemoveAll(candidate => candidate.Equals(item));
}
/// <summary>
/// Returns the object at the top of the Stack without removing it.
/// </summary>
/// <returns>Object at the top of the Stack.</returns>
public T Peek() => _Items[^1];
/// <summary>
/// Number of items.
/// </summary>
public int Count => _Items.Count;
internal void Clear()
{
_Items.Clear();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c0c68f77a1b8b43359f34cb46ce19801
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: