Merge branch 'finite_number' into 'master'

Reduce code duplication for finite number and add tests

See merge request OpenMW/openmw!4707
This commit is contained in:
psi29a 2025-06-06 22:14:32 +00:00
commit 1c242425b0
6 changed files with 30 additions and 43 deletions

View File

@ -88,7 +88,7 @@ namespace MWLua
sol::table initAnimationPackage(const Context& context) sol::table initAnimationPackage(const Context& context)
{ {
using FiniteFloat = Misc::FiniteFloat; using Misc::FiniteFloat;
auto view = context.sol(); auto view = context.sol();
auto mechanics = MWBase::Environment::get().getMechanicsManager(); auto mechanics = MWBase::Environment::get().getMechanicsManager();

View File

@ -16,7 +16,7 @@ namespace MWLua
sol::table initCameraPackage(sol::state_view lua) sol::table initCameraPackage(sol::state_view lua)
{ {
using FiniteFloat = Misc::FiniteFloat; using Misc::FiniteFloat;
MWRender::Camera* camera = MWBase::Environment::get().getWorld()->getCamera(); MWRender::Camera* camera = MWBase::Environment::get().getWorld()->getCamera();
MWRender::RenderingManager* renderingManager = MWBase::Environment::get().getWorld()->getRenderingManager(); MWRender::RenderingManager* renderingManager = MWBase::Environment::get().getWorld()->getRenderingManager();

View File

@ -57,7 +57,7 @@ namespace MWLua
static void addWorldTimeBindings(sol::table& api, const Context& context) static void addWorldTimeBindings(sol::table& api, const Context& context)
{ {
using FiniteFloat = Misc::FiniteFloat; using Misc::FiniteFloat;
MWWorld::DateTimeManager* timeManager = MWBase::Environment::get().getWorld()->getTimeManager(); MWWorld::DateTimeManager* timeManager = MWBase::Environment::get().getWorld()->getTimeManager();

View File

@ -5,69 +5,48 @@
#include <cmath> #include <cmath>
#include <stdexcept> #include <stdexcept>
#include <utility>
namespace Misc namespace Misc
{ {
struct FiniteDouble template <class T>
struct FiniteNumber
{ {
double mValue; T mValue;
FiniteDouble(double v)
FiniteNumber(T v)
{ {
if (!std::isfinite(v)) if (!std::isfinite(v))
throw std::invalid_argument("Value must be a finite number"); throw std::invalid_argument("Value must be a finite number");
mValue = v; mValue = v;
} }
operator double() const { return mValue; }
operator T() const { return mValue; }
}; };
struct FiniteFloat using FiniteDouble = FiniteNumber<double>;
{
float mValue; using FiniteFloat = FiniteNumber<float>;
FiniteFloat(float v)
{
if (!std::isfinite(v))
throw std::invalid_argument("Value must be a finite number");
mValue = v;
}
operator float() const { return mValue; }
};
} }
namespace sol namespace sol
{ {
using FiniteDouble = Misc::FiniteDouble; template <class Handler, class T>
using FiniteFloat = Misc::FiniteFloat;
template <typename Handler>
bool sol_lua_check( bool sol_lua_check(
sol::types<FiniteDouble>, lua_State* L, int index, Handler&& handler, sol::stack::record& tracking) types<Misc::FiniteNumber<T>>, lua_State* state, int index, Handler&& handler, stack::record& tracking)
{ {
bool success = sol::stack::check<double>(L, lua_absindex(L, index), handler); bool success = stack::check<T>(state, lua_absindex(state, index), std::forward<Handler>(handler));
tracking.use(1); tracking.use(1);
return success; return success;
} }
static FiniteDouble sol_lua_get(sol::types<FiniteDouble>, lua_State* L, int index, sol::stack::record& tracking) template <class T>
static Misc::FiniteNumber<T> sol_lua_get(
types<Misc::FiniteNumber<T>>, lua_State* state, int index, stack::record& tracking)
{ {
double val = sol::stack::get<double>(L, lua_absindex(L, index)); T value = stack::get<T>(state, lua_absindex(state, index));
tracking.use(1); tracking.use(1);
return FiniteDouble(val); return value;
}
template <typename Handler>
bool sol_lua_check(
sol::types<FiniteFloat>, lua_State* L, int index, Handler&& handler, sol::stack::record& tracking)
{
bool success = sol::stack::check<float>(L, lua_absindex(L, index), handler);
tracking.use(1);
return success;
}
static FiniteFloat sol_lua_get(sol::types<FiniteFloat>, lua_State* L, int index, sol::stack::record& tracking)
{
float val = sol::stack::get<float>(L, lua_absindex(L, index));
tracking.use(1);
return FiniteFloat(val);
} }
} }

View File

@ -344,6 +344,13 @@ testing.registerGlobalTest('load while teleporting - teleport', function()
landracer:teleport(player.cell, player.position) landracer:teleport(player.cell, player.position)
end) end)
testing.registerGlobalTest('nan', function()
local nan = 0.0 / 0.0
local ok, err = pcall(function() world.setGameTimeScale(nan) end)
testing.expectEqual(ok, false)
testing.expectEqual(err, 'Value must be a finite number')
end)
return { return {
engineHandlers = { engineHandlers = {
onUpdate = testing.updateGlobal, onUpdate = testing.updateGlobal,

View File

@ -72,6 +72,7 @@ registerGlobalTest('memory limit')
registerGlobalTest('vfs') registerGlobalTest('vfs')
registerGlobalTest('commit crime') registerGlobalTest('commit crime')
registerGlobalTest('record model property') registerGlobalTest('record model property')
registerGlobalTest('nan', 'world.setGameTimeScale should not accept nan')
registerGlobalTest('player yaw rotation', 'rotating player with controls.yawChange should change rotation') registerGlobalTest('player yaw rotation', 'rotating player with controls.yawChange should change rotation')
registerGlobalTest('player pitch rotation', 'rotating player with controls.pitchChange should change rotation') registerGlobalTest('player pitch rotation', 'rotating player with controls.pitchChange should change rotation')