forked from ThePhD/sol2
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdynamic_object.cpp
More file actions
88 lines (73 loc) · 1.87 KB
/
dynamic_object.cpp
File metadata and controls
88 lines (73 loc) · 1.87 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
#define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>
#include <iostream>
#include <unordered_map>
// use as-is,
// add as a member of your class,
// or derive from it and bind it appropriately
struct dynamic_object {
std::unordered_map<std::string, sol::object> entries;
void dynamic_set(std::string key, sol::stack_object value) {
auto it = entries.find(key);
if (it == entries.cend()) {
entries.insert(
it, { std::move(key), std::move(value) });
}
else {
std::pair<const std::string, sol::object>& kvp
= *it;
sol::object& entry = kvp.second;
entry = sol::object(std::move(value));
}
}
sol::object dynamic_get(std::string key) {
auto it = entries.find(key);
if (it == entries.cend()) {
return sol::lua_nil;
}
return it->second;
}
};
int main() {
std::cout << "=== dynamic_object ===" << std::endl;
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.new_usertype<dynamic_object>("dynamic_object",
sol::meta_function::index,
&dynamic_object::dynamic_get,
sol::meta_function::new_index,
&dynamic_object::dynamic_set,
sol::meta_function::length,
[](dynamic_object& d) { return d.entries.size(); });
lua.safe_script(R"(
d1 = dynamic_object.new()
d2 = dynamic_object.new()
print(#d1) -- length operator
print(#d2)
function d2:run(lim)
local r = 0
for i=0,lim do
r = r + i
end
if (r % 2) == 1 then
print("odd")
end
return r
end
-- only added an entry to d2
print(#d1)
print(#d2)
-- only works on d2
local value = d2:run(5)
assert(value == 15)
)");
// does not work on d1: 'run' wasn't added to d1, only d2
auto script_result = lua.safe_script(
"local value = d1:run(5)", sol::script_pass_on_error);
sol_c_assert(!script_result.valid());
sol::error err = script_result;
std::cout << "received expected error: " << err.what()
<< std::endl;
std::cout << std::endl;
return 0;
}