mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-31 04:56:39 +00:00 
			
		
		
		
	Using docs/source/reference/modding/settings/*.rst and files/settings-default.cfg files content.
		
			
				
	
	
		
			210 lines
		
	
	
	
		
			5.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			210 lines
		
	
	
	
		
			5.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include "sanitizerimpl.hpp"
 | |
| 
 | |
| #include <osg/Vec3f>
 | |
| 
 | |
| #include <algorithm>
 | |
| #include <cassert>
 | |
| #include <cmath>
 | |
| #include <limits>
 | |
| #include <sstream>
 | |
| #include <stdexcept>
 | |
| #include <type_traits>
 | |
| #include <utility>
 | |
| #include <vector>
 | |
| 
 | |
| namespace Settings
 | |
| {
 | |
|     namespace
 | |
|     {
 | |
|         template <class T>
 | |
|         struct Max final : Sanitizer<T>
 | |
|         {
 | |
|             T mMax;
 | |
| 
 | |
|             explicit Max(const T& max)
 | |
|                 : mMax(max)
 | |
|             {
 | |
|             }
 | |
| 
 | |
|             T apply(const T& value) const override { return std::max(value, mMax); }
 | |
|         };
 | |
| 
 | |
|         template <class T>
 | |
|         struct MaxStrict final : Sanitizer<T>
 | |
|         {
 | |
|             static_assert(std::is_floating_point_v<T>);
 | |
| 
 | |
|             T mMax;
 | |
| 
 | |
|             explicit MaxStrict(const T& max)
 | |
|                 : mMax(std::nextafter(max, std::numeric_limits<T>::max()))
 | |
|             {
 | |
|             }
 | |
| 
 | |
|             T apply(const T& value) const override { return std::max(value, mMax); }
 | |
|         };
 | |
| 
 | |
|         template <>
 | |
|         struct MaxStrict<osg::Vec3f> final : Sanitizer<osg::Vec3f>
 | |
|         {
 | |
|             osg::Vec3f mMax;
 | |
| 
 | |
|             explicit MaxStrict(const osg::Vec3f& max)
 | |
|                 : mMax(std::nextafter(max.x(), std::numeric_limits<float>::max()),
 | |
|                     std::nextafter(max.y(), std::numeric_limits<float>::max()),
 | |
|                     std::nextafter(max.z(), std::numeric_limits<float>::max()))
 | |
|             {
 | |
|             }
 | |
| 
 | |
|             osg::Vec3f apply(const osg::Vec3f& value) const override
 | |
|             {
 | |
|                 return osg::Vec3f(
 | |
|                     std::max(value.x(), mMax.x()), std::max(value.y(), mMax.y()), std::max(value.z(), mMax.z()));
 | |
|             }
 | |
|         };
 | |
| 
 | |
|         template <class T>
 | |
|         struct Clamp final : Sanitizer<T>
 | |
|         {
 | |
|             T mMin;
 | |
|             T mMax;
 | |
| 
 | |
|             explicit Clamp(const T& min, const T& max)
 | |
|                 : mMin(min)
 | |
|                 , mMax(max)
 | |
|             {
 | |
|             }
 | |
| 
 | |
|             T apply(const T& value) const override { return std::clamp(value, mMin, mMax); }
 | |
|         };
 | |
| 
 | |
|         template <class T>
 | |
|         auto getPrev(const T& value) -> std::enable_if_t<std::is_floating_point_v<T>, T>
 | |
|         {
 | |
|             assert(value > -std::numeric_limits<T>::max());
 | |
|             return std::nextafter(value, -std::numeric_limits<T>::max());
 | |
|         }
 | |
| 
 | |
|         template <class T>
 | |
|         struct ClampStrictMax final : Sanitizer<T>
 | |
|         {
 | |
|             T mMin;
 | |
|             T mMax;
 | |
| 
 | |
|             explicit ClampStrictMax(const T& min, const T& max)
 | |
|                 : mMin(min)
 | |
|                 , mMax(getPrev(max))
 | |
|             {
 | |
|             }
 | |
| 
 | |
|             T apply(const T& value) const override { return std::clamp(value, mMin, mMax); }
 | |
|         };
 | |
| 
 | |
|         template <class T>
 | |
|         struct Enum final : Sanitizer<T>
 | |
|         {
 | |
|             std::vector<T> mValues;
 | |
| 
 | |
|             explicit Enum(std::initializer_list<T> value)
 | |
|                 : mValues(std::make_move_iterator(value.begin()), std::make_move_iterator(value.end()))
 | |
|             {
 | |
|             }
 | |
| 
 | |
|             T apply(const T& value) const override
 | |
|             {
 | |
|                 if (std::find(mValues.begin(), mValues.end(), value) == mValues.end())
 | |
|                 {
 | |
|                     std::ostringstream message;
 | |
|                     message << "Invalid enum value: " << value;
 | |
|                     throw std::runtime_error(message.str());
 | |
|                 }
 | |
|                 return value;
 | |
|             }
 | |
|         };
 | |
| 
 | |
|         template <class T>
 | |
|         struct EqualOrMax final : Sanitizer<T>
 | |
|         {
 | |
|             T mEqual;
 | |
|             T mMax;
 | |
| 
 | |
|             explicit EqualOrMax(const T& equal, const T& max)
 | |
|                 : mEqual(equal)
 | |
|                 , mMax(max)
 | |
|             {
 | |
|             }
 | |
| 
 | |
|             T apply(const T& value) const override
 | |
|             {
 | |
|                 if (value == mEqual)
 | |
|                     return value;
 | |
|                 return std::max(value, mMax);
 | |
|             }
 | |
|         };
 | |
|     }
 | |
| 
 | |
|     std::unique_ptr<Sanitizer<float>> makeMaxSanitizerFloat(float max)
 | |
|     {
 | |
|         return std::make_unique<Max<float>>(max);
 | |
|     }
 | |
| 
 | |
|     std::unique_ptr<Sanitizer<int>> makeMaxSanitizerInt(int max)
 | |
|     {
 | |
|         return std::make_unique<Max<int>>(max);
 | |
|     }
 | |
| 
 | |
|     std::unique_ptr<Sanitizer<std::size_t>> makeMaxSanitizerSize(std::size_t max)
 | |
|     {
 | |
|         return std::make_unique<Max<std::size_t>>(max);
 | |
|     }
 | |
| 
 | |
|     std::unique_ptr<Sanitizer<std::uint64_t>> makeMaxSanitizerUInt64(std::uint64_t max)
 | |
|     {
 | |
|         return std::make_unique<Max<std::uint64_t>>(max);
 | |
|     }
 | |
| 
 | |
|     std::unique_ptr<Sanitizer<float>> makeMaxStrictSanitizerFloat(float max)
 | |
|     {
 | |
|         return std::make_unique<MaxStrict<float>>(max);
 | |
|     }
 | |
| 
 | |
|     std::unique_ptr<Sanitizer<osg::Vec3f>> makeMaxStrictSanitizerVec3f(const osg::Vec3f& max)
 | |
|     {
 | |
|         return std::make_unique<MaxStrict<osg::Vec3f>>(max);
 | |
|     }
 | |
| 
 | |
|     std::unique_ptr<Sanitizer<float>> makeClampSanitizerFloat(float min, float max)
 | |
|     {
 | |
|         return std::make_unique<Clamp<float>>(min, max);
 | |
|     }
 | |
| 
 | |
|     std::unique_ptr<Sanitizer<double>> makeClampSanitizerDouble(double min, double max)
 | |
|     {
 | |
|         return std::make_unique<Clamp<double>>(min, max);
 | |
|     }
 | |
| 
 | |
|     std::unique_ptr<Sanitizer<int>> makeClampSanitizerInt(int min, int max)
 | |
|     {
 | |
|         return std::make_unique<Clamp<int>>(min, max);
 | |
|     }
 | |
| 
 | |
|     std::unique_ptr<Sanitizer<float>> makeClampStrictMaxSanitizerFloat(float min, float max)
 | |
|     {
 | |
|         return std::make_unique<ClampStrictMax<float>>(min, max);
 | |
|     }
 | |
| 
 | |
|     std::unique_ptr<Sanitizer<int>> makeEnumSanitizerInt(std::initializer_list<int> values)
 | |
|     {
 | |
|         return std::make_unique<Enum<int>>(values);
 | |
|     }
 | |
| 
 | |
|     std::unique_ptr<Sanitizer<std::string>> makeEnumSanitizerString(std::initializer_list<std::string> values)
 | |
|     {
 | |
|         return std::make_unique<Enum<std::string>>(values);
 | |
|     }
 | |
| 
 | |
|     std::unique_ptr<Sanitizer<float>> makeEqualOrMaxSanitizerFloat(float equal, float max)
 | |
|     {
 | |
|         return std::make_unique<EqualOrMax<float>>(equal, max);
 | |
|     }
 | |
| }
 |