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;
}
|