修改水
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c5666bcd450914e3e980a32dd866957e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f796ed8d9971b4795b28bcb1c4dc3a01
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c0c68f77a1b8b43359f34cb46ce19801
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user