C++에서 선언한 enum class의 이름 그대로 Lua 스크립트에서 번거롭지 않은 느낌에 사용하고 싶다 (C++/Boost/Sol/Siv3D)
무엇을 원하십니까?
enum class MyEnum {
A,
B,
C,
}
이런 enum class가 있었기 때문에 Lua에서
local e = MyEnum.B
라는 느낌으로 사용하고 싶다.
하지만 일일이 Lua 측에서 MyEnum={}; MyEnum.A=0; MyEnum.B=1; ...
같은 것을 수작업으로 하고 싶지 않다.
접근
enum class MyEnum {
A,
B,
C,
}
local e = MyEnum.B
소스 코드
개발 환경:
Siv3D August 2016 v2 (문자열 처리가 편리하기 때문에)
#include <Siv3D.hpp>
#include <boost/bimap/bimap.hpp>
#include <sol.hpp>
#pragma comment(lib, "lua52.lib")
#define ENUM_CLASS(NAME, ...) \
enum class NAME : int { __VA_ARGS__ }; \
struct NAME##_ { \
using bimap_t = boost::bimaps::bimap<NAME, String>; \
using value_t = bimap_t::value_type; \
using enum_t = NAME; \
template <class T> static String toString(const T v) { return bimap_holder::get().left.at((NAME)v); } \
static auto toEnum(const String& v) { return bimap_holder::get().right.at(v); } \
static const size_t size() { return bimap_holder::get().size(); } \
static const String name() { return Widen(#NAME); } \
template <class Fn> static void forEach(Fn f) { \
using iterator = bimap_t::left_const_iterator; \
for (iterator it = bimap_holder::get().left.begin(); it != bimap_holder::get().left.end(); it++) { \
f(it->first, it->second); \
} \
} \
private: \
struct bimap_holder { \
static bimap_t& get() { \
static bimap_t m_; \
static bool init = false; \
if (!init) { \
init = true; \
initialize(); \
} \
return m_; \
} \
}; \
static void initialize() { \
bimap_t& m = bimap_holder::get(); \
Array<String> arr = Widen(#__VA_ARGS__).split(L','); \
int enum_val = 0; \
for (auto s : arr) { \
Array<Match> match = Regex::Search(s, L"\\s*=\\s*(.+)$"); \
if (!match.empty()) { \
enum_val = Parse<int>(match[0].str(1)); \
} \
m.insert(value_t((NAME)enum_val, Regex::ReplaceAll(s, L"\\s*=.+$", L"").trim())); \
++enum_val; \
} \
} \
};
template <class Enum>
void registerEnum(sol::state& lua)
{
lua[Enum::name().str()] = lua.create_table();
Enum::forEach([&](Enum::enum_t e, String s) {
lua[Enum::name().str()][s.str()] = (int)e;
});
}
// enum class TestEnum の宣言
// このようにする:
ENUM_CLASS(TestEnum,
A = 100,
B,
C,
D,
X,
Y,
Z);
void Main()
{
// Lua初期化
sol::state lua;
lua.open_libraries();
// Luaの環境にenumの値を設定
registerEnum<TestEnum_>(lua);
// Lua スクリプトで TestEnum.B という書き方ができる
lua.script("function f() return TestEnum.B end");
Println((int)(lua["f"]())); // => 101 (TestEnum::B)
WaitKey();
}
실행 결과
잡기
Reference
이 문제에 관하여(C++에서 선언한 enum class의 이름 그대로 Lua 스크립트에서 번거롭지 않은 느낌에 사용하고 싶다 (C++/Boost/Sol/Siv3D)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/voidProc/items/b2b46cb23dba0f86c232텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)