File: LuaBridge.cpp

package info (click to toggle)
sol2 3.5.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 23,096 kB
  • sloc: cpp: 43,816; ansic: 1,018; python: 356; sh: 288; makefile: 202
file content (135 lines) | stat: -rw-r--r-- 3,322 bytes parent folder | download
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
#define SOL_ALL_SAFETIES_ON 1
#define SOL_ENABLE_INTEROP \
	1 // MUST be defined to use interop features
#include <sol/sol.hpp>

#include <LuaBridge/LuaBridge.h>

#include <iostream>

// LuaBridge,
// no longer maintained, by VinnieFalco:
// https://github.com/vinniefalco/LuaBridge

struct A {

	A(int v) : v_(v) {
	}

	void print() {
		std::cout << "called A::print" << std::endl;
	}

	int value() const {
		return v_;
	}

private:
	int v_ = 50;
};

template <typename T, typename Handler>
inline bool sol_lua_interop_check(sol::types<T>, lua_State* L,
     int relindex, sol::type index_type, Handler&& handler,
     sol::stack::record& tracking) {
	// just marking unused parameters for no compiler warnings
	(void)index_type;
	(void)handler;
	tracking.use(1);
	int index = lua_absindex(L, relindex);
	T* corrected = luabridge::Userdata::get<T>(L, index, true);
	return corrected != nullptr;
}

template <typename T>
inline std::pair<bool, T*> sol_lua_interop_get(sol::types<T> t,
     lua_State* L, int relindex, void* unadjusted_pointer,
     sol::stack::record& tracking) {
	(void)unadjusted_pointer;
	int index = lua_absindex(L, relindex);
	if (!sol_lua_interop_check(t,
	         L,
	         index,
	         sol::type::userdata,
	         sol::no_panic,
	         tracking)) {
		return { false, nullptr };
	}
	T* corrected = luabridge::Userdata::get<T>(L, index, true);
	return { true, corrected };
}

void register_sol_stuff(lua_State* L) {
	// grab raw state and put into state_view
	// state_view is cheap to construct
	sol::state_view lua(L);
	// bind and set up your things: everything is entirely
	// self-contained
	lua["f"] = sol::overload(
	     [](A& from_luabridge) {
		     std::cout << "calling 1-argument version with "
		                  "luabridge-created A { "
		               << from_luabridge.value() << " }"
		               << std::endl;
		     SOL_ASSERT(from_luabridge.value() == 24);
	     },
	     [](A& from_luabridge, int second_arg) {
		     std::cout << "calling 2-argument version with "
		                  "luabridge-created A { "
		               << from_luabridge.value()
		               << " } and integer argument of "
		               << second_arg << std::endl;
		     SOL_ASSERT(from_luabridge.value() == 24);
		     SOL_ASSERT(second_arg == 5);
	     });
}

void check_with_sol(lua_State* L) {
	sol::state_view lua(L);
	A& obj = lua["obj"];
	(void)obj;
	SOL_ASSERT(obj.value() == 24);
}

int main(int, char*[]) {

	std::cout << "=== interop example (LuaBridge) ==="
	          << std::endl;
	std::cout << "code modified from LuaBridge's examples: "
	             "https://github.com/vinniefalco/LuaBridge"
	          << std::endl;

	struct closer {
		void operator()(lua_State* L) {
			lua_close(L);
		}
	};

	std::unique_ptr<lua_State, closer> state(luaL_newstate());
	lua_State* L = state.get();
	luaL_openlibs(L);

	luabridge::getGlobalNamespace(L)
	     .beginNamespace("test")
	     .beginClass<A>("A")
	     .addConstructor<void (*)(int)>()
	     .addFunction("print", &A::print)
	     .addFunction("value", &A::value)
	     .endClass()
	     .endNamespace();

	register_sol_stuff(L);


	if (luaL_dostring(L, R"(
obj = test.A(24)
f(obj) -- call 1 argument version
f(obj, 5) -- call 2 argument version
)")) {
		lua_error(L);
	}

	check_with_sol(L);

	return 0;
}