/* 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 . */ #include "wrenpp/def_configuration.hpp" #include "wrenpp/vm_fun.hpp" #include "wrenpp/callback_manager.hpp" #include "wrenpp/class_manager.hpp" #include #include #include 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) foreign static base_x() } )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)>") var vec_base_x = MathVector.base_x() System.print("vec_base_x modified by scripting: <%(vec_base_x.x), %(vec_base_x.y), %(vec_base_x.z)>") )script"; template class Vector { public: Vector() = default; explicit Vector (T value) : m_x(value), m_y(value), m_z(value) {} Vector (T x, T y, T z) : m_x(x), m_y(y), m_z(z) {} ~Vector() noexcept = default; T x() const { return m_x; } T y() const { return m_y; } T z() const { return m_z; } void set_x(T x) { m_x = x; } void set_y(T y) { m_y = y; } void set_z(T z) { m_z = z; } static Vector base_x() { return {1.0, 0.0, 0.0}; } private: T 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() + 1; char* const buff = new char[buff_sz]; std::copy(g_math_vector_src.cbegin(), g_math_vector_src.cend(), buff); buff[buff_sz - 1] = '\0'; return buff; } return nullptr; } void load_module_complete_fn(wren::VM*, std::string_view, char* buffer) { delete[] buffer; } }; } //unnamed namespace int main() { using wren::make_function_bindable; using wren::make_foreign_class; MyConf conf; wren::VM vm(&conf, nullptr); vm.callback_manager() .add_callback(false, "math_vector", "MathVector", "x=(_)", make_function_bindable<&Vector::set_x>) .add_callback(false, "math_vector", "MathVector", "y=(_)", make_function_bindable<&Vector::set_y>) .add_callback(false, "math_vector", "MathVector", "z=(_)", make_function_bindable<&Vector::set_z>) .add_callback(false, "math_vector", "MathVector", "x", make_function_bindable<&Vector::x>) .add_callback(false, "math_vector", "MathVector", "y", make_function_bindable<&Vector::y>) .add_callback(false, "math_vector", "MathVector", "z", make_function_bindable<&Vector::z>) .add_callback(true, "math_vector", "MathVector", "base_x()", make_function_bindable<&Vector::base_x>); vm.class_manager() .add_class_maker("math_vector", "MathVector", make_foreign_class, double, //single value constructor std::tuple, //x,y,z constructor std::tuple<> //default constructor >); vm.interpret("main", g_test_script); return 0; }