dep-sol2/examples/source/usertype.cpp

136 lines
3 KiB
C++
Raw Permalink Normal View History

#define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>
2017-03-16 08:51:19 -04:00
#include <iostream>
#include <cmath>
struct foo {
private:
std::string name;
2017-03-16 08:51:19 -04:00
public:
foo(std::string name) : name(std::string(name)) {
}
2017-03-16 08:51:19 -04:00
void print() {
std::cout << name << '\n';
}
2017-03-16 08:51:19 -04:00
int test(int x) {
return static_cast<int>(name.length()) + x;
}
2017-03-16 08:51:19 -04:00
};
struct vector {
private:
float x = 0;
float y = 0;
2017-03-16 08:51:19 -04:00
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;
}
2017-03-16 08:51:19 -04:00
};
struct variables {
bool low_gravity = false;
int boost_level = 0;
2017-03-16 08:51:19 -04:00
};
int main() {
std::cout << "=== usertype ===" << std::endl;
2017-03-16 08:51:19 -04:00
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
2017-03-16 08:51:19 -04:00
// 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);
2017-03-16 08:51:19 -04:00
// 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)");
2017-03-16 08:51:19 -04:00
auto y = lua.get<int>("y");
std::cout << y << std::endl; // show 14
2017-03-16 08:51:19 -04:00
// 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
2017-03-16 08:51:19 -04:00
{
// Notice the brace: this means we're in a new scope
2017-03-16 08:51:19 -04:00
// first, define the different types of constructors
// notice here that the return type
2017-03-16 08:51:19 -04:00
// on the function-type doesn't exactly matter,
// which allows you to use a shorter class name/void
2017-03-16 08:51:19 -04:00
// 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)");
2017-03-16 08:51:19 -04:00
std::cout << std::endl;
return 0;
2017-03-16 08:51:19 -04:00
}