File: userdata.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 (105 lines) | stat: -rw-r--r-- 2,525 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
#define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>

#include <iostream>

struct Doge {
	int tailwag = 50;

	Doge() {
	}

	Doge(int wags) : tailwag(wags) {
	}

	~Doge() {
		std::cout << "Dog at " << this
		          << " is being destroyed..." << std::endl;
	}
};

int main(int, char*[]) {
	std::cout << "=== userdata ===" << std::endl;

	sol::state lua;

	Doge dog { 30 };

	// fresh one put into Lua
	lua["dog"] = Doge {};
	// Copy into lua: destroyed by Lua VM during garbage
	// collection
	lua["dog_copy"] = dog;
	// OR: move semantics - will call move constructor if
	// present instead Again, owned by Lua
	lua["dog_move"] = std::move(dog);
	lua["dog_unique_ptr"] = std::make_unique<Doge>(25);
	lua["dog_shared_ptr"] = std::make_shared<Doge>(31);

	// Identical to above
	Doge dog2 { 30 };
	lua.set("dog2", Doge {});
	lua.set("dog2_copy", dog2);
	lua.set("dog2_move", std::move(dog2));
	lua.set("dog2_unique_ptr",
	     std::unique_ptr<Doge>(new Doge(25)));
	lua.set("dog2_shared_ptr",
	     std::shared_ptr<Doge>(new Doge(31)));

	// Note all of them can be retrieved the same way:
	Doge& lua_dog = lua["dog"];
	Doge& lua_dog_copy = lua["dog_copy"];
	Doge& lua_dog_move = lua["dog_move"];
	Doge& lua_dog_unique_ptr = lua["dog_unique_ptr"];
	Doge& lua_dog_shared_ptr = lua["dog_shared_ptr"];
	SOL_ASSERT(lua_dog.tailwag == 50);
	SOL_ASSERT(lua_dog_copy.tailwag == 30);
	SOL_ASSERT(lua_dog_move.tailwag == 30);
	SOL_ASSERT(lua_dog_unique_ptr.tailwag == 25);
	SOL_ASSERT(lua_dog_shared_ptr.tailwag == 31);

	// lua will treat these types as opaque, and you will be
	// able to pass them around to C++ functions and Lua
	// functions alike

	// Use a C++ reference to handle memory directly
	// otherwise take by value, without '&'
	lua["f"] = [](Doge& dog) {
		std::cout << "dog wags its tail " << dog.tailwag
		          << " times!" << std::endl;
	};

	// if you bind a function using a pointer,
	// you can handle when `nil` is passed
	lua["handling_f"] = [](Doge* dog) {
		if (dog == nullptr) {
			std::cout << "dog was nil!" << std::endl;
			return;
		}
		std::cout << "dog wags its tail " << dog->tailwag
		          << " times!" << std::endl;
	};

	lua.script(R"(
		f(dog)
		f(dog_copy)
		f(dog_move)
		f(dog_unique_ptr)
		f(dog_shared_ptr)

		-- C++ arguments that are pointers can handle nil
		handling_f(dog)
		handling_f(dog_copy)
		handling_f(dog_move)
		handling_f(dog_unique_ptr)
		handling_f(dog_shared_ptr)
		handling_f(nil)

		-- never do this
		-- f(nil)
	)");

	std::cout << std::endl;

	return 0;
}