Things're gonna get silly...

This commit is contained in:
ThePhD 2016-06-13 22:31:19 -04:00
parent 9352473d59
commit d76b7ebe09
4 changed files with 64 additions and 3 deletions

14
sol/bases_for.hpp Normal file
View File

@ -0,0 +1,14 @@
#pragma once
#include "traits.hpp"
namespace sol {
template <typename T>
struct bases_for {
typedef types<> type;
};
template <typename T>
struct has_bases : std::integral_constant<bool, ( bases_for<T>::type::size() > 0 )> {};
}

View File

@ -23,6 +23,7 @@
#define SOL_INHERITANCE_HPP
#include "types.hpp"
#include "bases_for.hpp"
#if defined(SOL_NO_RTTI) && defined(SOL_NO_EXCEPTIONS)
#include <atomic>
#endif // No Runtime Type Information and No Exceptions

View File

@ -290,7 +290,7 @@ struct getter<T*> {
static T* get_no_nil_from(lua_State* L, void* udata, int index = -1) {
#ifndef SOL_NO_EXCEPTIONS
if (luaL_getmetafield(L, index, &detail::base_class_check_key()[0]) != 0) {
if (has_bases<T>::value && luaL_getmetafield(L, index, &detail::base_class_check_key()[0]) != 0) {
void* basecastdata = lua_touserdata(L, -1);
detail::throw_cast basecast = (detail::throw_cast)basecastdata;
// use the casting function to properly adjust the pointer for the desired T
@ -298,7 +298,7 @@ struct getter<T*> {
lua_pop(L, 1);
}
#elif !defined(SOL_NO_RTTI)
if (luaL_getmetafield(L, index, &detail::base_class_cast_key()[0]) != 0) {
if (has_bases<T>::value && luaL_getmetafield(L, index, &detail::base_class_cast_key()[0]) != 0) {
void* basecastdata = lua_touserdata(L, -1);
detail::inheritance_cast_function ic = (detail::inheritance_cast_function)basecastdata;
// use the casting function to properly adjust the pointer for the desired T
@ -307,7 +307,7 @@ struct getter<T*> {
}
#else
// Lol, you motherfucker
if (luaL_getmetafield(L, index, &detail::base_class_cast_key()[0]) != 0) {
if (has_bases<T>::value && luaL_getmetafield(L, index, &detail::base_class_cast_key()[0]) != 0) {
void* basecastdata = lua_touserdata(L, -1);
detail::inheritance_cast_function ic = (detail::inheritance_cast_function)basecastdata;
// use the casting function to properly adjust the pointer for the desired T

View File

@ -5,6 +5,7 @@
#include <sol.hpp>
#include <vector>
#include <map>
#include <unordered_map>
#include <iostream>
#include "test_stack_guard.hpp"
@ -370,3 +371,48 @@ TEST_CASE("state/multi-require", "make sure that requires transfers across hand-
//REQUIRE(thingy1 == thingy3);
REQUIRE(thingy2 == thingy3);
}
TEST_CASE("misc/indexing_overrides", "make sure index functions can be overridden on types") {
struct PropertySet {
sol::object get_property_lua(const char* name, sol::this_state s)
{
auto& var = props[name];
return sol::make_object(s, var);
}
void set_property_lua(const char* name, sol::stack_object object)
{
props[name] = object.as<std::string>();
}
std::unordered_map<std::string, std::string> props;
};
struct DynamicObject {
PropertySet& get_dynamic_props() {
return dynamic_props;
}
PropertySet dynamic_props;
};
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.new_usertype<PropertySet>("PropertySet"
, sol::meta_function::new_index, &PropertySet::set_property_lua
, sol::meta_function::index, &PropertySet::get_property_lua
);
lua.new_usertype<DynamicObject>("DynamicObject"
, "props", sol::property(&DynamicObject::get_dynamic_props)
);
lua.script(R"__(
obj = DynamicObject:new()
obj.props.name = 'test name'
print('name = ' .. obj.props.name)
)__");
std::string name = lua["obj"]["props"]["name"];
REQUIRE(name == "test name");
}