File: usertype_advanced.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 (145 lines) | stat: -rw-r--r-- 2,995 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
136
137
138
139
140
141
142
143
144
145
#define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>

/*
#include "player.hpp"
*/

#include <iostream>

struct player {
public:
	int bullets;
	int speed;

	player() : player(3, 100) {
	}

	player(int ammo) : player(ammo, 100) {
	}

	player(int ammo, int hitpoints)
	: bullets(ammo), hp(hitpoints) {
	}

	void boost() {
		speed += 10;
	}

	bool shoot() {
		if (bullets < 1)
			return false;
		--bullets;
		return true;
	}

	void set_hp(int value) {
		hp = value;
	}

	int get_hp() const {
		return hp;
	}

private:
	int hp;
};

int main() {
	std::cout << "=== usertype_advanced ===" << std::endl;
	sol::state lua;

	lua.open_libraries(sol::lib::base);

	// note that you can set a
	// userdata before you register a usertype,
	// and it will still carry
	// the right metatable if you register it later

	// set a variable "p2" of type "player" with 0 ammo
	lua["p2"] = player(0);

	// make usertype metatable
	sol::usertype<player> player_type
	     = lua.new_usertype<player>("player",
	          // 3 constructors
	          sol::constructors<player(),
	               player(int),
	               player(int, int)>());

	// typical member function that returns a variable
	player_type["shoot"] = &player::shoot;
	// typical member function
	player_type["boost"] = &player::boost;

	// gets or set the value using member variable syntax
	player_type["hp"]
	     = sol::property(&player::get_hp, &player::set_hp);

	// read and write variable
	player_type["speed"] = &player::speed;
	// can only read from, not write to
	// .set(foo, bar) is the same as [foo] = bar;
	player_type.set("bullets", sol::readonly(&player::bullets));

	// You can also add members to the code, defined in Lua!
	// This lets you have a high degree of flexibility in the
	// code
	std::string prelude_script = R"(
function player:brake ()
	self.speed = 0
	print("we hit the brakes!")
end
)";

	std::string player_script = R"(
-- call single argument integer constructor
p1 = player.new(2)

-- p2 is still here from being 
-- set with lua["p2"] = player(0); below
local p2shoots = p2:shoot()
assert(not p2shoots)
-- had 0 ammo
	
-- set variable property setter
p1.hp = 545
-- get variable through property unqualified_getter
print(p1.hp)
assert(p1.hp == 545)

local did_shoot_1 = p1:shoot()
print(did_shoot_1)
print(p1.bullets)
local did_shoot_2 = p1:shoot()
print(did_shoot_2)
print(p1.bullets)
local did_shoot_3 = p1:shoot()
print(did_shoot_3)
	
-- can read
print(p1.bullets)
-- would error: is a readonly variable, cannot write
-- p1.bullets = 20

p1:boost()
-- call the function we define at runtime from a Lua script
p1:brake()
)";

	// Uncomment and use the file to try that out, too!
	// Make sure it's in the local directory of the executable
	// after you build, or adjust the filename path Or whatever
	// else you like!
	//
	/*
	lua.script_file("prelude_script.lua");
	lua.script_file("player_script.lua");
	*/
	lua.script(prelude_script);
	lua.script(player_script);

	std::cout << std::endl;

	return 0;
}