#include "rays/ruby/polyline.h" #include #include "rays/ruby/point.h" #include "rays/ruby/bounds.h" #include "rays/ruby/polygon.h" #include "defs.h" RUCY_DEFINE_VALUE_OR_ARRAY_FROM_TO(Rays::Polyline) #define THIS to(self) #define CHECK RUCY_CHECK_OBJECT(Rays::Polyline, self) static VALUE alloc(VALUE klass) { return new_type(klass); } static VALUE setup(VALUE self, VALUE points, VALUE loop) { CHECK; std::vector array; get_line_args(&array, points.size(), points.as_array()); *THIS = Rays::Polyline(&array[0], array.size(), loop); } static VALUE expand(VALUE self) { CHECK; check_arg_count(__FILE__, __LINE__, "Polyline#expand", argc, 1, 2, 3, 4); coord width = to (argv[0]); Rays::CapType cap = argc >= 2 ? to (argv[1]) : Rays::CAP_DEFAULT; Rays::JoinType join = argc >= 3 ? to(argv[2]) : Rays::JOIN_DEFAULT; coord ml = argc >= 4 ? to (argv[3]) : Rays::JOIN_DEFAULT_MITER_LIMIT; Rays::Polygon polygon; THIS->expand(&polygon, width, cap, join, ml); return value(polygon); } static VALUE bounds(VALUE self) { CHECK; return value(THIS->bounds()); } static VALUE loop(VALUE self) { CHECK; return value(THIS->loop()); } static VALUE size(VALUE self) { CHECK; return value(THIS->size()); } static VALUE empty(VALUE self) { CHECK; return value(THIS->empty()); } static VALUE get_at(VALUE self, VALUE index) { CHECK; int size = (int) THIS->size(); int i = to(index); if (i < 0) i += size; if (i < 0 || size <= i) index_error(__FILE__, __LINE__); return value((*THIS)[i]); } static VALUE each(VALUE self) { CHECK; Value ret = Qnil; for (const auto& point : *THIS) ret = rb_yield(value(point)); return ret; } static Class cPolyline; void Init_polyline () { Module mRays = rb_define_module("Rays"); cPolyline = rb_define_class_under(mRays, "Polyline", rb_cObject); rb_define_alloc_func(cPolyline, alloc); rb_define_private_method(cPolyline, "setup", RUBY_METHOD_FUNC(setup), 2); rb_define_method(cPolyline, "expand", RUBY_METHOD_FUNC(expand), -1); rb_define_method(cPolyline, "bounds", RUBY_METHOD_FUNC(bounds), 0); cPolyline.define_method("loop?", loop); rb_define_method(cPolyline, "size", RUBY_METHOD_FUNC(size), 0); cPolyline.define_method("empty?", empty); cPolyline.define_method("[]", get_at); rb_define_method(cPolyline, "each", RUBY_METHOD_FUNC(each), 0); } namespace Rucy { template <> Rays::Polyline value_to (int argc, const Value* argv, bool convert) { assert(argc == 0 || (argc > 0 && argv)); if (convert) { if (argc <= 0) return Rays::Polyline(); else if (argv->is_num() || argv->is_array()) { std::vector points; get_line_args(&points, argc, argv); return Rays::Polyline(&points[0], points.size()); } } if (argc != 1) argument_error(__FILE__, __LINE__); return value_to(*argv, convert); } }// Rucy namespace Rays { Class polyline_class () { return cPolyline; } }// Rays