Ark Server API (ASA) - Wiki
Loading...
Searching...
No Matches
UnitConversion.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "Containers/Array.h"
6#include "Containers/UnrealString.h"
7#include "CoreTypes.h"
8#include "Delegates/Delegate.h"
9#include "Internationalization/Text.h"
10#include "Misc/Optional.h"
11#include "Templates/ValueOrError.h"
12
13class FText;
14template<typename NumericType> struct FNumericUnit;
15
16/** Enum *must* be zero-indexed and sequential. Must be grouped by relevance and ordered by magnitude. */
17/** Enum *must* match the mirrored enum that exists in CoreUObject/Classes/Object.h for the purposes of UObject reflection */
18enum class EUnit : uint8
19{
20 /** Scalar distance/length units */
24
25 /** Angular units */
27
28 /** Speed units */
30
31 /** Temperature units */
33
34 /** Mass units */
37
38 /** Force units */
40
41 /** Frequency units */
43
44 /** Data Size units */
46
47 /** Luminous flux units, luminous intensity, illuminance, luminance */
49
50 /** Time units */
52
53 /** Pixel density units */
55
56 /** Arbitrary multipliers */
58
59 /** Symbolic entry, not specifiable on meta data */
61};
62
63/** Enumeration that specifies particular classes of unit */
64enum class EUnitType
65{
67
68 // Symbolic entry - do not use directly
70};
71
72template<typename NumericType> struct FNumericUnit;
73
74/** Unit settings accessed globally through FUnitConversion::Settings() */
76{
77public:
78
80
81 /** Check whether unit display is globally enabled or disabled */
82 bool ShouldDisplayUnits() const;
83 void SetShouldDisplayUnits(bool bInGlobalUnitDisplay);
84
85 /** Get/Set the specific valid units to display the specified type of unit in */
87 void SetDisplayUnits(EUnitType InType, const TArray<EUnit>& Units);
88 void SetDisplayUnits(EUnitType InType, EUnit Units);
89
90 /** Returns an event delegate that is executed when a display setting has changed. (GlobalUnitDisplay or DefaultInputUnits) */
91 DECLARE_EVENT(FUnitSettings, FDisplaySettingChanged);
92 FDisplaySettingChanged& OnDisplaySettingsChanged() { return SettingChangedEvent; }
93
94private:
95
96 /** Global toggle controlling whether we should display units or not */
98
99 /** Arrays of units that are valid to display on interfaces */
101
102 /** Holds an event delegate that is executed when a display setting has changed. */
103 FDisplaySettingChanged SettingChangedEvent;
104};
105
107{
108 /** Get the global settings for unit conversion/display */
110
111 /** Check whether it is possible to convert a number between the two specified units */
112 static bool AreUnitsCompatible(EUnit From, EUnit To);
113
114 /** Check whether a unit is of the specified type */
115 static bool IsUnitOfType(EUnit Unit, EUnitType Type);
116
117 /** Get the type of the specified unit */
119
120 /** Get the display string for the the specified unit type */
121 static const TCHAR* GetUnitDisplayString(EUnit Unit);
122
123 /** Helper function to find a unit from a string (name or display string) */
124 static TOptional<EUnit> UnitFromString(const TCHAR* UnitString);
125
126public:
127
128 /** Convert the specified number from one unit to another. Does nothing if the units are incompatible. */
129 template<typename T>
130 static T Convert(T InValue, EUnit From, EUnit To);
131
132 /** Quantizes this number to the most appropriate unit for user friendly presentation (e.g. 1000m returns 1km). */
133 template<typename T>
134 static FNumericUnit<T> QuantizeUnitsToBestFit(T Value, EUnit Units);
135
136 /** Quantizes this number to the most appropriate unit for user friendly presentation (e.g. 1000m returns 1km), adhereing to global display settings. */
137 template<typename T>
138 static EUnit CalculateDisplayUnit(T Value, EUnit InUnits);
139
140};
141
142
143/**
144 * FNumericUnit is a numeric type that wraps the templated type, whilst a specified unit.
145 * It handles conversion to/from related units automatically. The units are considered not to contribute to the type's state, and as such should be considered immutable once set.
146 */
147template<typename NumericType>
148struct FNumericUnit
149{
150 /** The numeric (scalar) value */
151 NumericType Value;
152 /** The associated units for the value. Can never change once set to anything other than EUnit::Unspecified. */
154
155 /** Constructors */
156 FNumericUnit();
157 FNumericUnit(const NumericType& InValue, EUnit InUnits = EUnit::Unspecified);
158
159 /** Copy construction/assignment from the same type */
160 FNumericUnit(const FNumericUnit& Other);
161 FNumericUnit& operator=(const FNumericUnit& Other);
162
163 /** Templated Copy construction/assignment from differing numeric types. Relies on implicit conversion of the two numeric types. */
164 template<typename OtherType> FNumericUnit(const FNumericUnit<OtherType>& Other);
165 template<typename OtherType> FNumericUnit& operator=(const FNumericUnit<OtherType>& Other);
166
167 /** Convert this quantity to a different unit */
168 TOptional<FNumericUnit<NumericType>> ConvertTo(EUnit ToUnits) const;
169
170public:
171
172 /** Quantizes this number to the most appropriate unit for user friendly presentation (e.g. 1000m returns 1km). */
173 FNumericUnit<NumericType> QuantizeUnitsToBestFit() const;
174
175 /** Try and parse an expression into a numeric unit */
176 static TValueOrError<FNumericUnit<NumericType>, FText> TryParseExpression(const TCHAR* InExpression, EUnit InDefaultUnit, const FNumericUnit<NumericType>& InExistingValue);
177
178 /** Parse a numeric unit from a string */
179 static TOptional<FNumericUnit<NumericType>> TryParseString(const TCHAR* InSource);
180
181private:
182 /** Conversion to the numeric type disabled as coupled with implicit construction from NumericType can easily lead to loss of associated units. */
183 operator const NumericType&() const;
184
185 /** Copy another unit into this one, taking account of its units, and applying necessary conversion */
186 template<typename OtherType>
187 void CopyValueWithConversion(const FNumericUnit<OtherType>& Other);
188
189 /** Given a string, skip past whitespace, then any numeric characters. Set End pointer to the end of the last numeric character. */
190 static bool ExtractNumberBoundary(const TCHAR* Start, const TCHAR*& End);
191
192 /** Global arithmetic operators for number types. Deals with conversion from related units correctly. Note must be inlined for hidden friend optimization to work */
193 template<typename OtherType>
194 friend inline bool operator==(const FNumericUnit<NumericType>& LHS, const FNumericUnit<OtherType>& RHS)
195 {
196 if (LHS.Units != EUnit::Unspecified && RHS.Units != EUnit::Unspecified)
197 {
198 if (LHS.Units == RHS.Units)
199 {
200 return LHS.Value == RHS.Value;
201 }
202 else if (FUnitConversion::AreUnitsCompatible(LHS.Units, RHS.Units))
203 {
204 return LHS.Value == FUnitConversion::Convert(RHS.Value, RHS.Units, LHS.Units);
205 }
206 else
207 {
208 // Invalid conversion
209 return false;
210 }
211 }
212 else
213 {
214 return LHS.Value == RHS.Value;
215 }
216 }
217
218 template<typename OtherType>
219 friend inline bool operator!=(const FNumericUnit<NumericType>& LHS, const FNumericUnit<OtherType>& RHS)
220 {
221 return !(LHS == RHS);
222 }
223};
224
225template<typename T>
226FString LexToString(const FNumericUnit<T>& NumericUnit);
227
228template<typename T>
229FString LexToSanitizedString(const FNumericUnit<T>& NumericUnit);
230
231template<typename T>
232void LexFromString(FNumericUnit<T>& OutValue, const TCHAR* String);
233
234template<typename T>
235bool LexTryParseString(FNumericUnit<T>& OutValue, const TCHAR* String);
236
237
238// Include template definitions
239#include "Math/UnitConversion.inl" // IWYU pragma: export
#define DECLARE_EVENT(OwningType, EventName)
EUnitType
Definition Enums.h:23284
@ LuminousIntensity
EUnit
Definition Enums.h:23304
@ CentimetersPerSecond
@ Milligrams
@ Megabytes
@ KilometersPerHour
@ Centimeters
@ Megahertz
@ Farenheit
@ Percentage
@ Micrometers
@ Milliseconds
@ Millimeters
@ RevolutionsPerMinute
@ Gigahertz
@ KilogramsForce
@ Microseconds
@ Unspecified
@ Kilograms
@ MetricTons
@ CandelaPerMeter2
@ Terabytes
@ Kilobytes
@ Lightyears
@ PixelsPerInch
@ Kilohertz
@ MilesPerHour
@ Micrograms
@ Multiplier
@ Kilometers
@ PoundsForce
@ Gigabytes
@ MetersPerSecond
@ Nanoseconds
FString LexToSanitizedString(const FNumericUnit< T > &NumericUnit)
bool LexTryParseString(FNumericUnit< T > &OutValue, const TCHAR *String)
void LexFromString(FNumericUnit< T > &OutValue, const TCHAR *String)
FString LexToString(const FNumericUnit< T > &NumericUnit)
Definition Text.h:357
bool ShouldDisplayUnits() const
const TArray< EUnit > & GetDisplayUnits(EUnitType InType) const
void SetShouldDisplayUnits(bool bInGlobalUnitDisplay)
void SetDisplayUnits(EUnitType InType, EUnit Units)
FDisplaySettingChanged & OnDisplaySettingsChanged()
void SetDisplayUnits(EUnitType InType, const TArray< EUnit > &Units)
FDisplaySettingChanged SettingChangedEvent
TOptional< FNumericUnit< NumericType > > ConvertTo(EUnit ToUnits) const
FNumericUnit & operator=(const FNumericUnit< OtherType > &Other)
static bool ExtractNumberBoundary(const TCHAR *Start, const TCHAR *&End)
operator const NumericType &() const
void CopyValueWithConversion(const FNumericUnit< OtherType > &Other)
static TValueOrError< FNumericUnit< NumericType >, FText > TryParseExpression(const TCHAR *InExpression, EUnit InDefaultUnit, const FNumericUnit< NumericType > &InExistingValue)
FNumericUnit(const NumericType &InValue, EUnit InUnits=EUnit::Unspecified)
FNumericUnit & operator=(const FNumericUnit &Other)
const EUnit Units
friend bool operator==(const FNumericUnit< NumericType > &LHS, const FNumericUnit< OtherType > &RHS)
FNumericUnit(const FNumericUnit &Other)
static TOptional< FNumericUnit< NumericType > > TryParseString(const TCHAR *InSource)
FNumericUnit< NumericType > QuantizeUnitsToBestFit() const
friend bool operator!=(const FNumericUnit< NumericType > &LHS, const FNumericUnit< OtherType > &RHS)
NumericType Value
FNumericUnit(const FNumericUnit< OtherType > &Other)
static TOptional< EUnit > UnitFromString(const TCHAR *UnitString)
static FUnitSettings & Settings()
static bool IsUnitOfType(EUnit Unit, EUnitType Type)
static EUnitType GetUnitType(EUnit)
static EUnit CalculateDisplayUnit(T Value, EUnit InUnits)
static const TCHAR * GetUnitDisplayString(EUnit Unit)
static FNumericUnit< T > QuantizeUnitsToBestFit(T Value, EUnit Units)
static bool AreUnitsCompatible(EUnit From, EUnit To)
static T Convert(T InValue, EUnit From, EUnit To)