wrenpp/examples/math_vector/main.cpp
King_DuckZ 4d3dfce93f Improve and cleanup make_foreign_class()
No need to have two versions of this.
Static assert when users specify ambiguous overloads.
Currently overloads are discriminated only by
parameter count, not types, so we need to enforce this.
2022-05-15 17:01:57 +02:00

118 lines
3.7 KiB
C++

/* Copyright 2020-2022, Michele Santullo
* This file is part of wrenpp.
*
* Wrenpp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Wrenpp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with wrenpp. If not, see <http://www.gnu.org/licenses/>.
*/
#include "wrenpp/def_configuration.hpp"
#include "wrenpp/vm_fun.hpp"
#include "wrenpp/callback_manager.hpp"
#include "wrenpp/class_manager.hpp"
#include <string_view>
#include <algorithm>
#include <iostream>
namespace {
constexpr std::string_view g_math_vector_src{
"foreign class MathVector {" R"script(
construct new() {}
construct new(value) {}
construct new(x, y, z) {}
foreign x
foreign y
foreign z
foreign x=(value)
foreign y=(value)
foreign z=(value)
}
)script"};
constexpr const char g_test_script[] =
R"script(import "math_vector" for MathVector
var vec1 = MathVector.new(15.0)
var vec2 = MathVector.new(10.0, 20.0, 30.0)
var vec3 = MathVector.new()
System.print("vec1 constructed from single value: <%(vec1.x), %(vec1.y), %(vec1.z)>")
System.print("vec2 constructed from three values: <%(vec2.x), %(vec2.y), %(vec2.z)>")
System.print("vec3 default constructed: <%(vec3.x), %(vec3.y), %(vec3.z)>")
vec3.x = 3.5
vec3.y = vec2.x / vec2.z
vec3.z = vec1.x + vec2.y / 4.0
System.print("vec3 modified by scripting: <%(vec3.x), %(vec3.y), %(vec3.z)>")
)script";
class MathVector {
public:
MathVector() = default;
explicit MathVector (double value) :
m_x(value), m_y(value), m_z(value)
{}
MathVector (double x, double y, double z) :
m_x(x), m_y(y), m_z(z)
{}
~MathVector() noexcept = default;
double x() const { return m_x; }
double y() const { return m_y; }
double z() const { return m_z; }
void set_x(double x) { m_x = x; }
void set_y(double y) { m_y = y; }
void set_z(double z) { m_z = z; }
private:
double m_x{}, m_y{}, m_z{};
};
class MyConf : public wren::DefConfiguration {
public:
char* load_module_fn(wren::VM* vm, std::string_view module_name) {
if (module_name == "math_vector") {
constexpr const std::size_t buff_sz = g_math_vector_src.size();
char* const buff = static_cast<char*>(MyConf::reallocate_fn(nullptr, buff_sz));
std::copy(g_math_vector_src.cbegin(), g_math_vector_src.cend(), buff);
return buff;
}
return nullptr;
}
};
} //unnamed namespace
int main() {
using wren::make_method_bindable;
using wren::make_foreign_class;
MyConf conf;
wren::VM vm(&conf, nullptr);
vm.callback_manager()
.add_callback(false, "math_vector", "MathVector", "x=(_)", make_method_bindable<&MathVector::set_x>())
.add_callback(false, "math_vector", "MathVector", "y=(_)", make_method_bindable<&MathVector::set_y>())
.add_callback(false, "math_vector", "MathVector", "z=(_)", make_method_bindable<&MathVector::set_z>())
.add_callback(false, "math_vector", "MathVector", "x", make_method_bindable<&MathVector::x>())
.add_callback(false, "math_vector", "MathVector", "y", make_method_bindable<&MathVector::y>())
.add_callback(false, "math_vector", "MathVector", "z", make_method_bindable<&MathVector::z>());
vm.class_manager()
.add_class_maker("math_vector", "MathVector", &make_foreign_class<MathVector,
double, //single value constructor
std::tuple<double, double, double>, //x,y,z constructor
std::tuple<> //default constructor
>);
vm.interpret("main", g_test_script);
return 0;
}