sol2库使用
2020-09-11 10:29:52 # c++ # lua

lua_bind.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#pragma once

#include <string>
#include <string_view>

#include "define.h"
#include "logger.h"
#include "sol/sol.hpp"

namespace Sky {
class LuaBind final {
public:
LuaBind() = default;

~LuaBind() = default;

enum lua_msg_type {
LMT_NONE,
LMT_MESSAGE,
LMT_TIMER,
LMT_SERVER_STOP,
LMT_HOTFIX,
LMT_TRIGGER,
LMT_ENTER_GAME,
LMT_DAY_RESET,
LMT_LEAVE_GAME,
LMT_QUERY_SQL,
LMT_EXECUTE_SQL,
};

bool start(std::string_view scriptDir, const std::string& luaName);

void stop();

void callCode(std::string_view code);

void callFile(std::string_view file);

template <typename... Args>
void callFrame(Args&&... args) {
auto res = m_state["onFrame"](std::forward<Args>(args)...);
if (!res.valid()) {
sol::error err = res;
LOG_ERROR("[{}] LuaBind::callFrame error:\n{}", m_luaName, err.what());
}
}

sol::state& get() {
return m_state;
}

private:
void registerClass();

bool registerField(std::string_view scriptPath);

private:
sol::state m_state;
std::string m_scriptPath{};
std::string m_luaName{};
};
} // namespace Sky

lua_bind.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include "lua_bind.h"

#include "comm_func.h"
#include "db_query.h"
#include "packet.h"

namespace Sky {
bool LuaBind::start(std::string_view scriptDir, const std::string& luaName) {
try {
m_luaName = luaName;
m_state.open_libraries();
if (!registerField(scriptDir)) {
return false;
}

registerClass();
} catch (const sol::error& e) {
LOG_ERROR("[{}] LuaBind::start error:{}", m_luaName, e.what());
}

return true;
}

void LuaBind::stop() {
callFrame(lua_msg_type::LMT_SERVER_STOP);
}

void LuaBind::callCode(std::string_view code) {
m_state.script(code, [this](lua_State* L, sol::protected_function_result pfr) {
sol::error err = pfr;
LOG_ERROR("[{}] LuaBind::callCode error:\n{}", m_luaName, err.what());
return pfr;
});
}

void LuaBind::callFile(std::string_view file) {
std::string file_path = m_scriptPath;
file_path.append(file.data()).append(".lua");
m_state.script_file(file_path, [this](lua_State* L, sol::protected_function_result pfr) {
sol::error err = pfr;
LOG_ERROR("[{}] LuaBind::callFile error:\n{}", m_luaName, err.what());
return pfr;
});
}

void LuaBind::registerClass() {
// auto Packet = m_state.new_usertype<Sky::Packet>("Packet", sol::constructors<Sky::Packet(), Sky::Packet(int)>());
auto packet = m_state.new_usertype<Sky::Packet>("Packet");
packet["readInt8"] = &Packet::readInt8;
packet["readUInt8"] = &Packet::readUInt8;
packet["readInt16"] = &Packet::readInt16;
packet["readUInt16"] = &Packet::readUInt16;
packet["readInt32"] = &Packet::readInt32;
packet["readUInt32"] = &Packet::readUInt32;
packet["readInt64"] = &Packet::readInt64;
packet["readUInt64"] = &Packet::readUInt64;
packet["readFloat"] = &Packet::readFloat;
packet["readDouble"] = &Packet::readDouble;
packet["readString"] = &Packet::readString;
packet["getMsgIdx"] = &Packet::getMsgIdx;
packet["canReadMore"] = &Packet::canReadMore;

auto query = m_state.new_usertype<Sky::DBQuery>("DBQuery");
query["readInt8"] = &DBQuery::readInt8;
query["readUInt8"] = &DBQuery::readUInt8;
query["readInt16"] = &DBQuery::readInt16;
query["readUInt16"] = &DBQuery::readUInt16;
query["readInt32"] = &DBQuery::readInt32;
query["readUInt32"] = &DBQuery::readUInt32;
query["readInt64"] = &DBQuery::readInt64;
query["readUInt64"] = &DBQuery::readUInt64;
query["readFloat"] = &DBQuery::readFloat;
query["readDouble"] = &DBQuery::readDouble;
query["readString"] = &DBQuery::readString;
query["getRowCount"] = &DBQuery::getRowCount;
query["getState"] = &DBQuery::getState;
query["getSn"] = &DBQuery::getSn;
query["eof"] = &DBQuery::eof;
}

bool LuaBind::registerField(std::string_view scriptPath) {
std::string path = CommFunc::getCurrentExeDir();
if (path.empty()) {
LOG_ERROR("[{}] LuaBind::registerField exec_path is empty", m_luaName);
return false;
}

if (scriptPath.empty()) {
LOG_ERROR("[{}] LuaBind::registerField script_path is empty", m_luaName);
return false;
}

auto pos = path.find_last_of(SLASH_STR);
if (pos == std::string::npos) {
LOG_ERROR("[{}] LuaBind::registerField path error", m_luaName);
return false;
}

auto root_path = path.substr(0, pos + 1);
m_scriptPath.append(root_path);
m_scriptPath.append("server");
m_scriptPath.append(SLASH_STR);
m_scriptPath.append(scriptPath.data());
m_scriptPath.append(SLASH_STR);

m_state["lRootPath"] = root_path;

m_state["lExecPath"] = path;

m_state["lScriptPath"] = m_scriptPath;

m_state["lGetMilliTime"] = CommFunc::getMilliTime;

m_state["lGetMicroTime"] = CommFunc::getMicroTime;

m_state["lGetSecTime"] = CommFunc::getSecTime;

m_state["lShowMemory"] = [this]() {
m_state.collect_garbage();
LOG_WARN("[{}] [LUA] LUA_MEM: {:.2f}M", m_luaName, static_cast<double>(m_state.memory_used()) / 1024 / 1024);
};

m_state["lShowInfo"] = [this](std::string_view msg) {
LOG_INFO("[{}] [LUA] {}", m_luaName, msg);
};

m_state["lShowError"] = [this](std::string_view msg) {
LOG_ERROR("[{}] [LUA] {}", m_luaName, msg);
};
return true;
}
} // namespace Sky