-
Notifications
You must be signed in to change notification settings - Fork 20
Expand file tree
/
Copy pathsample.cpp
More file actions
183 lines (148 loc) · 5.88 KB
/
sample.cpp
File metadata and controls
183 lines (148 loc) · 5.88 KB
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#include <cstddef>
#include <iostream>
#include <map>
#include <stdint.h>
#include <string>
#include <vector>
#include "lua/lua_module/lua_profile.h"
#include "lua/lua_module/lua_table_ext.h"
#include "lua/lua_module/lua_time_ext.h"
#include "lua/lua_engine/lua_binding_class.h"
#include "lua/lua_engine/lua_binding_mgr.h"
#include "lua/lua_engine/lua_binding_namespace.h"
#include "lua/lua_engine/lua_engine.h"
#include <common/file_system.h>
// 测试用的类
class sample_class {
public:
enum STATE_T { CREATED = 0, INITED };
public:
sample_class() : m_(0), state_(CREATED) {}
~sample_class() {}
STATE_T state() const { return state_; }
int get_m() const { return m_; }
void set_m(int m) {
m_ = m;
state_ = INITED;
}
void print_vec(const std::vector<int> &vec) {
std::cout << "print_vec: ";
for (size_t i = 0; i < vec.size(); ++i) {
if (i) {
std::cout << ", ";
}
std::cout << vec[i];
}
std::cout << std::endl;
}
static std::map<std::string, std::string> print_map(const std::map<std::string, std::string> &m) {
std::cout << "print_map: {" << std::endl;
for (std::map<std::string, std::string>::const_iterator iter = m.begin(); iter != m.end(); ++iter) {
std::cout << "\t" << iter->first << " = " << iter->second << std::endl;
}
std::cout << "}" << std::endl;
return m;
}
private:
int m_;
STATE_T state_;
};
// 自定义std::map<std::string, std::string>到luatable的转换规则
namespace script {
namespace lua {
namespace detail {
template <typename... Ty>
struct wraper_var<std::map<std::string, std::string>, Ty...> {
static int wraper(lua_State *L, const std::map<std::string, std::string> &v) {
lua_createtable(L, 0, static_cast<int>(v.size()));
for (std::map<std::string, std::string>::const_iterator iter = v.begin(); iter != v.end(); ++iter) {
lua_pushlstring(L, iter->first.c_str(), iter->first.size());
lua_pushlstring(L, iter->second.c_str(), iter->second.size());
lua_settable(L, -3);
}
return 1;
}
};
template <typename... Ty>
struct unwraper_var<std::map<std::string, std::string>, Ty...> {
static std::map<std::string, std::string> unwraper(lua_State *L, int index) {
// script::lua::lua_auto_block protect_top(L);
std::map<std::string, std::string> ret;
if (lua_gettop(L) < index) {
return ret;
}
luaL_checktype(L, index, LUA_TTABLE);
/* table is in the stack at index 't' */
lua_pushnil(L); /* first key */
while (lua_next(L, index) != 0) {
std::string key = luaL_checkstring(L, -2);
std::string val = luaL_checkstring(L, -1);
ret[key] = val;
lua_pop(L, 1);
}
return std::move(ret);
}
};
} // namespace detail
} // namespace lua
} // namespace script
int main(int argc, char *argv[]) {
script::lua::lua_engine::ptr_t lua_engine = script::lua::lua_engine::create();
lua_engine->add_on_inited([&lua_engine](lua_State *) {
// 初始化完成后加载扩展库
lua_engine->add_ext_lib(script::lua::lua_profile_openlib);
lua_engine->add_ext_lib(script::lua::lua_table_ext_openlib);
lua_engine->add_ext_lib(script::lua::lua_time_ext_openlib);
});
// 对象池管理器初始化
lua_engine->init();
// 添加搜索目录
std::string sample_source_path = util::file_system::get_abs_path(__FILE__);
std::string project_path;
util::file_system::dirname(sample_source_path.c_str(), sample_source_path.size(), project_path, 2);
lua_engine->add_search_path(project_path + util::file_system::DIRECTORY_SEPARATOR + "src");
// 执行参数中的脚本
for (int i = 1; i < argc; ++i) {
lua_engine->run_file(argv[i]);
}
std::string code;
while (std::getline(std::cin, code)) {
// 必须UTF-8编码
lua_engine->run_code(code.c_str());
code.clear();
// 定期调用 lua_engine->proc(); 或 lua_binding_mgr::me()->proc(); 后者会对所有注册的lua_State做处理
// 对C++层的对象回收将会在这里进行
lua_engine->proc();
}
return 0;
}
static void test_namespace_method_and_auto_call(lua_State *L) {
std::vector<std::string> vec;
vec.push_back("hello");
vec.push_back("world");
vec.push_back("!");
script::lua::auto_call(L, "_G.test.auto_call", "ready go", 123, vec);
}
LUA_BIND_OBJECT(sample_class, L) {
script::lua::lua_binding_class<sample_class> clazz("sample_class", "game.logic", L);
// 使用默认的new方法
// 尖括号中是构造函数的参数类型列表
// 如果要自定义new方法请使用set_new函数
clazz.set_default_new<>();
{
script::lua::lua_binding_namespace cs("sample_class_state_t", clazz.get_owner_namespace());
// 常量
cs.add_const("CREATED", sample_class::CREATED);
cs.add_const("INITED", sample_class::INITED);
// 函数
clazz.get_owner_namespace().add_method("auto_call", test_namespace_method_and_auto_call);
}
// 函数
{
clazz.add_method("state", &sample_class::state);
clazz.add_method("get_m", &sample_class::get_m);
clazz.add_method("set_m", &sample_class::set_m);
clazz.add_method("print_vec", &sample_class::print_vec);
clazz.add_method("print_map", &sample_class::print_map);
}
}