File: usertype.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,093 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
#include <sol/sol.hpp>

#include <iostream>
#include <cmath>

struct foo {
private:
	std::string name;

public:
	foo(std::string name) : name(std::string(name)) {
	}

	void print() {
		std::cout << name << '\n';
	}

	int test(int x) {
		return static_cast<int>(name.length()) + x;
	}
};

struct vector {
private:
	float x = 0;
	float y = 0;

public:
	vector() = default;
	vector(float x) : x(x) {
	}
	vector(float x, float y) : x(x), y(y) {
	}

	bool is_unit() const {
		return (x * x + y * y) == 1.f;
	}
};

struct variables {
	bool low_gravity = false;
	int boost_level = 0;
};

int main() {
	std::cout << "=== usertype ===" << std::endl;

	sol::state lua;
	lua.open_libraries(sol::lib::base, sol::lib::math);

	// the simplest way to create a class is through
	// sol::state::new_userdata
	// the first template is the class type
	// the rest are the constructor parameters
	// using new_userdata you can only have one constructor


	// you must make sure that the name of the function
	// goes before the member function pointer
	lua.new_usertype<foo>("foo",
	     sol::constructors<foo(std::string)>(),
	     "print",
	     &foo::print,
	     "test",
	     &foo::test);

	// making the class from lua is simple
	// same with calling member functions
	lua.script(
	     "x = foo.new('test')\n"
	     "x:print()\n"
	     "y = x:test(10)");

	auto y = lua.get<int>("y");
	std::cout << y << std::endl; // show 14

	// if you want a class to have more than one constructor
	// the way to do so is through set_userdata and creating
	// a userdata yourself with constructor types

	{
		// Notice the brace: this means we're in a new scope

		// first, define the different types of constructors
		// notice here that the return type
		// on the function-type doesn't exactly matter,
		// which allows you to use a shorter class name/void
		// if necessary
		sol::constructors<vector(),
		     vector(float),
		     void(float, float)>
		     ctor;
		// then you must register it
		sol::usertype<vector> utype
		     = lua.new_usertype<vector>("vector", ctor);

		// add to it as much as you like
		utype["is_unit"] = &vector::is_unit;
		// You can throw away the usertype after
		// you set it: you do NOT
		// have to keep it around
		// cleanup happens automagically!
	}

	// calling it is the same as
	// working with userdata is C++
	lua.script(
	     "v = vector.new()\n"
	     "v = vector.new(12)\n"
	     "v = vector.new(10, 10)\n"
	     "assert(not v:is_unit())\n");

	// You can even have C++-like member-variable-access
	// just pass is public member variables in the same style as
	// functions
	lua.new_usertype<variables>("variables",
	     "low_gravity",
	     &variables::low_gravity,
	     "boost_level",
	     &variables::boost_level);

	// making the class from lua is simple
	// same with calling member functions/variables
	lua.script(
	     "local vars = variables.new()\n"
	     "assert(not vars.low_gravity)\n"
	     "vars.low_gravity = true\n"
	     "local x = vars.low_gravity\n"
	     "assert(x)");

	std::cout << std::endl;

	return 0;
}