Add function LuaUtil::cast

backport_gl_clamp_removal
Petr Mikheev 1 year ago
parent 2d25ffeb89
commit 51cbfa84fa

@ -87,6 +87,23 @@ return {
EXPECT_EQ(LuaUtil::toString(sol::make_object(mLua.sol(), "something")), "\"something\"");
}
TEST_F(LuaStateTest, Cast)
{
EXPECT_EQ(LuaUtil::cast<int>(sol::make_object(mLua.sol(), 3.14)), 3);
EXPECT_ERROR(
LuaUtil::cast<int>(sol::make_object(mLua.sol(), "3.14")), "Value \"\"3.14\"\" can not be casted to int");
EXPECT_ERROR(LuaUtil::cast<std::string_view>(sol::make_object(mLua.sol(), sol::nil)),
"Value \"nil\" can not be casted to string");
EXPECT_ERROR(LuaUtil::cast<std::string>(sol::make_object(mLua.sol(), sol::nil)),
"Value \"nil\" can not be casted to string");
EXPECT_ERROR(LuaUtil::cast<sol::table>(sol::make_object(mLua.sol(), sol::nil)),
"Value \"nil\" can not be casted to sol::table");
EXPECT_ERROR(LuaUtil::cast<sol::function>(sol::make_object(mLua.sol(), "3.14")),
"Value \"\"3.14\"\" can not be casted to sol::function");
EXPECT_ERROR(LuaUtil::cast<sol::protected_function>(sol::make_object(mLua.sol(), "3.14")),
"Value \"\"3.14\"\" can not be casted to sol::function");
}
TEST_F(LuaStateTest, ErrorHandling)
{
EXPECT_ERROR(mLua.runInNewSandbox("invalid.lua"), "[string \"invalid.lua\"]:1:");

@ -301,4 +301,25 @@ namespace LuaUtil
return call(sol::state_view(obj.lua_state())["tostring"], obj);
}
std::string internal::formatCastingError(const sol::object& obj, const std::type_info& t)
{
const char* typeName = t.name();
if (t == typeid(int))
typeName = "int";
else if (t == typeid(unsigned))
typeName = "uint32";
else if (t == typeid(size_t))
typeName = "size_t";
else if (t == typeid(float))
typeName = "float";
else if (t == typeid(double))
typeName = "double";
else if (t == typeid(sol::table))
typeName = "sol::table";
else if (t == typeid(sol::function) || t == typeid(sol::protected_function))
typeName = "sol::function";
else if (t == typeid(std::string) || t == typeid(std::string_view))
typeName = "string";
return std::string("Value \"") + toString(obj) + std::string("\" can not be casted to ") + typeName;
}
}

@ -2,6 +2,7 @@
#define COMPONENTS_LUA_LUASTATE_H
#include <map>
#include <typeinfo>
#include <sol/sol.hpp>
@ -129,15 +130,25 @@ namespace LuaUtil
// String representation of a Lua object. Should be used for debugging/logging purposes only.
std::string toString(const sol::object&);
namespace internal
{
std::string formatCastingError(const sol::object& obj, const std::type_info&);
}
template <class T>
decltype(auto) cast(const sol::object& obj)
{
if (!obj.is<T>())
throw std::runtime_error(internal::formatCastingError(obj, typeid(T)));
return obj.as<T>();
}
template <class T>
T getValueOrDefault(const sol::object& obj, const T& defaultValue)
{
if (obj == sol::nil)
return defaultValue;
if (obj.is<T>())
return obj.as<T>();
else
throw std::logic_error(std::string("Value \"") + toString(obj) + std::string("\" has unexpected type"));
return cast<T>(obj);
}
// Makes a table read only (when accessed from Lua) by wrapping it with an empty userdata.

Loading…
Cancel
Save