You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
132 lines
4.6 KiB
132 lines
4.6 KiB
#pragma once |
|
|
|
#include <cstdint> |
|
#include <optional> |
|
#include <string> |
|
#include <string_view> |
|
|
|
#include <sol/sol.hpp> |
|
|
|
#include "utils/str_cat.hpp" |
|
|
|
namespace devilution { |
|
|
|
enum class LuaUserdataMemberType : uint8_t { |
|
ReadonlyProperty, |
|
Property, |
|
MemberFunction, |
|
Constructor, |
|
}; |
|
|
|
inline std::string LuaSignatureKey(std::string_view key) |
|
{ |
|
return StrCat("__sig_", key); |
|
} |
|
|
|
inline std::string LuaDocstringKey(std::string_view key) |
|
{ |
|
return StrCat("__doc_", key); |
|
} |
|
|
|
inline std::string LuaUserdataMemberTypeKey(std::string_view key) |
|
{ |
|
return StrCat("__udt_", key); |
|
} |
|
|
|
namespace lua_metadoc_internal { |
|
template <typename U> |
|
void SetUsertypeSignatureAndDocstring(sol::usertype<U> &table, std::string_view key, const char *signature, const char *doc, LuaUserdataMemberType memberType) |
|
{ |
|
table.set(LuaSignatureKey(key), sol::var(signature)); |
|
table.set(LuaDocstringKey(key), sol::var(doc)); |
|
table.set(LuaUserdataMemberTypeKey(key), sol::var(static_cast<uint8_t>(memberType))); |
|
} |
|
|
|
inline void SetSignatureAndDocstring(sol::table &table, std::string_view key, const char *signature, const char *doc) |
|
{ |
|
table.set(LuaSignatureKey(key), signature); |
|
table.set(LuaDocstringKey(key), doc); |
|
} |
|
} // namespace lua_metadoc_internal |
|
|
|
template <typename U, typename T> |
|
void LuaSetDocFn(sol::usertype<U> &table, std::string_view key, const char *signature, const char *doc, T &&value) |
|
{ |
|
table.set_function(key, std::forward<T>(value)); |
|
lua_metadoc_internal::SetUsertypeSignatureAndDocstring(table, key, signature, doc, LuaUserdataMemberType::MemberFunction); |
|
} |
|
|
|
template <typename U, typename G> |
|
void LuaSetDocReadonlyProperty(sol::usertype<U> &table, std::string_view key, const char *type, const char *doc, G &&getter) |
|
{ |
|
table.set(key, sol::readonly_property(std::forward<G>(getter))); |
|
lua_metadoc_internal::SetUsertypeSignatureAndDocstring(table, key, type, doc, LuaUserdataMemberType::ReadonlyProperty); |
|
} |
|
|
|
template <typename U, typename G, typename S> |
|
void LuaSetDocProperty(sol::usertype<U> &table, std::string_view key, const char *type, const char *doc, G &&getter, S &&setter) |
|
{ |
|
table.set(key, sol::property(std::forward<G>(getter), std::forward<S>(setter))); |
|
lua_metadoc_internal::SetUsertypeSignatureAndDocstring(table, key, type, doc, LuaUserdataMemberType::Property); |
|
} |
|
|
|
template <typename U, typename F> |
|
void LuaSetDocProperty(sol::usertype<U> &table, std::string_view key, const char *type, const char *doc, F U::*&&value) |
|
{ |
|
table.set(key, value); |
|
lua_metadoc_internal::SetUsertypeSignatureAndDocstring(table, key, type, doc, LuaUserdataMemberType::Property); |
|
} |
|
|
|
template <typename T> |
|
void LuaSetDoc(sol::table &table, std::string_view key, const char *signature, const char *doc, T &&value) |
|
{ |
|
table.set(key, std::forward<T>(value)); |
|
lua_metadoc_internal::SetSignatureAndDocstring(table, key, signature, doc); |
|
} |
|
|
|
template <typename T> |
|
void LuaSetDocFn(sol::table &table, std::string_view key, const char *signature, const char *doc, T &&value) |
|
{ |
|
table.set_function(key, std::forward<T>(value)); |
|
lua_metadoc_internal::SetSignatureAndDocstring(table, key, signature, doc); |
|
} |
|
|
|
template <typename T> |
|
void LuaSetDocFn(sol::table &table, std::string_view key, const char *signature, T &&value) |
|
{ |
|
table.set_function(key, std::forward<T>(value)); |
|
table.set(LuaSignatureKey(key), signature); |
|
} |
|
|
|
inline std::optional<std::string> GetSignature(const sol::table &table, std::string_view key) |
|
{ |
|
return table.get<std::optional<std::string>>(LuaSignatureKey(key)); |
|
} |
|
|
|
inline std::optional<std::string> GetDocstring(const sol::table &table, std::string_view key) |
|
{ |
|
return table.get<std::optional<std::string>>(LuaDocstringKey(key)); |
|
} |
|
|
|
inline std::optional<std::string> GetLuaUserdataSignature(const sol::userdata &obj, std::string_view key) |
|
{ |
|
return obj.get<std::optional<std::string>>(LuaSignatureKey(key)); |
|
} |
|
|
|
inline std::optional<std::string> GetLuaUserdataDocstring(const sol::userdata &obj, std::string_view key) |
|
{ |
|
return obj.get<std::optional<std::string>>(LuaDocstringKey(key)); |
|
} |
|
|
|
inline std::optional<LuaUserdataMemberType> GetLuaUserdataMemberType(const sol::userdata &obj, std::string_view key, const sol::object &value) |
|
{ |
|
std::optional<uint8_t> result = obj.get<std::optional<uint8_t>>(LuaUserdataMemberTypeKey(key)); |
|
if (!result.has_value()) { |
|
if (value.get_type() == sol::type::userdata) return LuaUserdataMemberType::Property; |
|
if (value.get_type() == sol::type::function && key == "new") return LuaUserdataMemberType::Constructor; |
|
return std::nullopt; |
|
} |
|
return static_cast<LuaUserdataMemberType>(*result); |
|
} |
|
|
|
} // namespace devilution
|
|
|