Files
tbd-station-14/Content.Shared/FixedPoint/FixedPoint2.cs
Javier Guardia Fernández 319aec109d Admin logs (#5419)
* Add admin logging, models, migrations

* Add logging damage changes

* Add Log admin flag, LogFilter, Logs admin menu tab, message
Refactor admin logging API

* Change admin log get method names

* Fix the name again

* Minute amount of reorganization

* Reset Postgres db snapshot

* Reset Sqlite db snapshot

* Make AdminLog have a composite primary key of round, id

* Minute cleanup

* Change admin system to do a type check instead of index check

* Make admin logs use C# 10 interpolated string handlers

* Implement UI on its own window
Custom controls
Searching
Add admin log converters

* Implement limits into the query

* Change logs to be put into an OutputPanel instead for text wrapping

* Add log <-> player m2m relationship back

* UI improvements, make text wrap, add separators

* Remove entity prefix from damaged log

* Add explicit m2m model, fix any players filter

* Add debug command to test bulk adding logs

* Admin logs now just kinda go

* Add histogram for database update time

* Make admin log system update run every 5 seconds

* Add a cap to the log queue and a metric for how many times it has been reached

* Add metric for logs sent in a round

* Make cvars out of admin logs queue send delay and cap

* Merge fixes

* Reset some changes

* Add test for adding and getting a single log

* Add tests for bulk adding logs

* Add test for querying logs

* Add CallerArgumentExpression to LogStringHandler methods and test

* Improve UI, fix SQLite, add searching by round

* Add entities to admin logs

* Move distinct after orderby

* Add migrations

* ef core eat my ass

* Add cvar for client logs batch size

* Sort logs from newest to oldest by default

* Merge fixes

* Reorganize tests and add one for date ordering

* Add note to log types to not change their numeric values

* Add impacts to logs, better UI filtering

* Make log add callable from shared for convenience

* Get current round id directly from game ticker

* Revert namespace change for DamageableSystem
2021-11-22 18:49:26 +01:00

295 lines
7.9 KiB
C#

using System;
using System.Globalization;
using System.Linq;
using Robust.Shared.Serialization;
namespace Content.Shared.FixedPoint
{
/// <summary>
/// Represents a quantity of something, to a precision of 0.01.
/// To enforce this level of precision, floats are shifted by 2 decimal points, rounded, and converted to an int.
/// </summary>
[Serializable]
public struct FixedPoint2 : ISelfSerialize, IComparable<FixedPoint2>, IEquatable<FixedPoint2>, IFormattable
{
private int _value;
private const int Shift = 2;
public static FixedPoint2 MaxValue { get; } = new(int.MaxValue);
public static FixedPoint2 Epsilon { get; } = new(1);
public static FixedPoint2 Zero { get; } = new(0);
private readonly double ShiftDown()
{
return _value / Math.Pow(10, Shift);
}
private FixedPoint2(int value)
{
_value = value;
}
public static FixedPoint2 New(int value)
{
return new(value * (int) Math.Pow(10, Shift));
}
public static FixedPoint2 New(float value)
{
return new(FromFloat(value));
}
private static int FromFloat(float value)
{
return (int) MathF.Round(value * MathF.Pow(10, Shift), MidpointRounding.AwayFromZero);
}
public static FixedPoint2 New(double value)
{
return new((int) Math.Round(value * Math.Pow(10, Shift), MidpointRounding.AwayFromZero));
}
public static FixedPoint2 New(string value)
{
return New(FloatFromString(value));
}
private static float FloatFromString(string value)
{
return float.Parse(value, CultureInfo.InvariantCulture);
}
public static FixedPoint2 operator +(FixedPoint2 a) => a;
public static FixedPoint2 operator -(FixedPoint2 a) => new(-a._value);
public static FixedPoint2 operator +(FixedPoint2 a, FixedPoint2 b)
=> new(a._value + b._value);
public static FixedPoint2 operator -(FixedPoint2 a, FixedPoint2 b)
=> a + -b;
public static FixedPoint2 operator *(FixedPoint2 a, FixedPoint2 b)
{
var aD = a.ShiftDown();
var bD = b.ShiftDown();
return New(aD * bD);
}
public static FixedPoint2 operator *(FixedPoint2 a, float b)
{
var aD = (float) a.ShiftDown();
return New(aD * b);
}
public static FixedPoint2 operator *(FixedPoint2 a, double b)
{
var aD = a.ShiftDown();
return New(aD * b);
}
public static FixedPoint2 operator *(FixedPoint2 a, int b)
{
return new(a._value * b);
}
public static FixedPoint2 operator /(FixedPoint2 a, FixedPoint2 b)
{
if (b._value == 0)
{
throw new DivideByZeroException();
}
var aD = a.ShiftDown();
var bD = b.ShiftDown();
return New(aD / bD);
}
public static FixedPoint2 operator /(FixedPoint2 a, float b)
{
return a / FixedPoint2.New(b);
}
public static bool operator <=(FixedPoint2 a, int b)
{
return a <= New(b);
}
public static bool operator >=(FixedPoint2 a, int b)
{
return a >= New(b);
}
public static bool operator <(FixedPoint2 a, int b)
{
return a < New(b);
}
public static bool operator >(FixedPoint2 a, int b)
{
return a > New(b);
}
public static bool operator ==(FixedPoint2 a, int b)
{
return a == New(b);
}
public static bool operator !=(FixedPoint2 a, int b)
{
return a != New(b);
}
public static bool operator ==(FixedPoint2 a, FixedPoint2 b)
{
return a.Equals(b);
}
public static bool operator !=(FixedPoint2 a, FixedPoint2 b)
{
return !a.Equals(b);
}
public static bool operator <=(FixedPoint2 a, FixedPoint2 b)
{
return a._value <= b._value;
}
public static bool operator >=(FixedPoint2 a, FixedPoint2 b)
{
return a._value >= b._value;
}
public static bool operator <(FixedPoint2 a, FixedPoint2 b)
{
return a._value < b._value;
}
public static bool operator >(FixedPoint2 a, FixedPoint2 b)
{
return a._value > b._value;
}
public readonly float Float()
{
return (float) ShiftDown();
}
public readonly double Double()
{
return ShiftDown();
}
public readonly int Int()
{
return (int) ShiftDown();
}
// Implicit operators ftw
public static implicit operator FixedPoint2(float n) => FixedPoint2.New(n);
public static implicit operator FixedPoint2(double n) => FixedPoint2.New(n);
public static implicit operator FixedPoint2(int n) => FixedPoint2.New(n);
public static explicit operator float(FixedPoint2 n) => n.Float();
public static explicit operator double(FixedPoint2 n) => n.Double();
public static explicit operator int(FixedPoint2 n) => n.Int();
public static FixedPoint2 Min(params FixedPoint2[] fixedPoints)
{
return fixedPoints.Min();
}
public static FixedPoint2 Min(FixedPoint2 a, FixedPoint2 b)
{
return a < b ? a : b;
}
public static FixedPoint2 Max(FixedPoint2 a, FixedPoint2 b)
{
return a > b ? a : b;
}
public static FixedPoint2 Abs(FixedPoint2 a)
{
return FixedPoint2.New(Math.Abs(a._value));
}
public static FixedPoint2 Dist(FixedPoint2 a, FixedPoint2 b)
{
return FixedPoint2.Abs(a - b);
}
public static FixedPoint2 Clamp(FixedPoint2 reagent, FixedPoint2 min, FixedPoint2 max)
{
if (min > max)
{
throw new ArgumentException($"{nameof(min)} {min} cannot be larger than {nameof(max)} {max}");
}
return reagent < min ? min : reagent > max ? max : reagent;
}
public override readonly bool Equals(object? obj)
{
return obj is FixedPoint2 unit &&
_value == unit._value;
}
public override readonly int GetHashCode()
{
// ReSharper disable once NonReadonlyMemberInGetHashCode
return HashCode.Combine(_value);
}
public void Deserialize(string value)
{
_value = FromFloat(FloatFromString(value));
}
public override readonly string ToString() => $"{ShiftDown().ToString(CultureInfo.InvariantCulture)}";
public string ToString(string? format, IFormatProvider? formatProvider)
{
return ToString();
}
public readonly string Serialize()
{
return ToString();
}
public readonly bool Equals(FixedPoint2 other)
{
return _value == other._value;
}
public readonly int CompareTo(FixedPoint2 other)
{
if(other._value > _value)
{
return -1;
}
if(other._value < _value)
{
return 1;
}
return 0;
}
}
public static class FixedPointEnumerableExt
{
public static FixedPoint2 Sum(this System.Collections.Generic.IEnumerable<FixedPoint2> source)
{
var acc = FixedPoint2.Zero;
foreach (var n in source)
{
acc += n;
}
return acc;
}
}
}