.doc/ext/rays/bounds.cpp in rays-0.1.6 vs .doc/ext/rays/bounds.cpp in rays-0.1.7
- old
+ new
@@ -1,74 +1,39 @@
#include "rays/ruby/bounds.h"
#include <rucy.h>
-#include <rays/ruby/point.h>
+#include "rays/ruby/point.h"
#include "defs.h"
using namespace Rucy;
using Rays::coord;
static Class cBounds;
+RUCY_DEFINE_VALUE_FROM_TO(Rays::Bounds, cBounds)
-namespace Rays
-{
+#define THIS to<Rays::Bounds*>(self)
+#define CHECK RUCY_CHECK_OBJ(Rays::Bounds, cBounds, self)
- Class
- bounds_class ()
- {
- return cBounds;
- }
-
-}// Rays
-
-
-namespace Rucy
-{
-
-
- Value
- value (const Rays::Bounds& obj)
- {
- return new_type(cBounds, new Rays::Bounds(obj));
- }
-
- Value
- value (const Rays::Bounds* obj)
- {
- return obj ? value(*obj) : nil();
- }
-
-
-}// Rucy
-
-
-#define THIS to<Rays::Bounds*>(self)
-
-#define CHECK RUCY_CHECK_OBJ(self, Rays::Bounds, cBounds)
-
-
static
VALUE alloc(VALUE klass)
{
return new_type<Rays::Bounds>(klass);
}
static
VALUE initialize(VALUE self)
{
- RUCY_CHECK_OBJ(self, Rays::Bounds, cBounds);
+ CHECK;
+ check_arg_count(__FILE__, __LINE__, "Bounds#initialize", argc, 0, 1, 2, 3, 4, 6);
- if (argc != 0 && argc != 1 && argc != 2 && argc != 3 && argc != 4 && argc != 6)
- arg_count_error("Bounds#initialize", argc, 0, 1, 2, 3, 4, 6);
-
if (argc == 0) return self;
switch (argc)
{
case 1:
@@ -101,20 +66,167 @@
}
static
VALUE initialize_copy(VALUE self, VALUE obj)
{
- RUCY_CHECK_OBJ(self, Rays::Bounds, cBounds);
+ CHECK;
+ *THIS = to<Rays::Bounds&>(obj);
+ return self;
+}
- Rays::Bounds* bounds = to<Rays::Bounds*>(obj);
- if (!bounds) argument_error();
+static
+VALUE intersect(VALUE self)
+{
+ CHECK;
+ check_arg_count(__FILE__, __LINE__, "Bounds#intersect?", argc, 1, 2);
- *THIS = *bounds;
+ const Rays::Bounds& bounds = to<Rays::Bounds&>(argv[0]);
+ int dimension = argc >= 2 ? to<int>(argv[1]) : 2;
+
+ return value(THIS->is_intersect(bounds, dimension));
+}
+
+static
+VALUE include(VALUE self)
+{
+ CHECK;
+ check_arg_count(__FILE__, __LINE__, "Bounds#include?", argc, 1, 2);
+
+ const Rays::Point& point = to<Rays::Point&>(argv[0]);
+ int dimension = argc >= 2 ? to<int>(argv[1]) : 2;
+
+ return value(THIS->is_include(point, dimension));
+}
+
+static
+VALUE move_to(VALUE self)
+{
+ CHECK;
+ check_arg_count(__FILE__, __LINE__, "Bounds#move_to", argc, 1, 2, 3);
+
+ if (argv[0].is_kind_of(Rays::point_class()))
+ THIS->move_to(to<Rays::Point&>(argv[0]));
+ else
+ {
+ if (argv[0].is_array())
+ {
+ argc = argv[0].size();
+ argv = argv[0].as_array();
+ }
+
+ const Rays::Point& p = THIS->position();
+ coord x = (argc >= 1 && argv[0]) ? to<coord>(argv[0]) : p.x;
+ coord y = (argc >= 2 && argv[1]) ? to<coord>(argv[1]) : p.y;
+ coord z = (argc >= 3 && argv[2]) ? to<coord>(argv[2]) : p.z;
+ THIS->move_to(x, y, z);
+ }
+
return self;
}
static
+VALUE move_by(VALUE self)
+{
+ CHECK;
+ check_arg_count(__FILE__, __LINE__, "Bounds#move_by", argc, 1, 2, 3);
+
+ if (argv[0].is_kind_of(Rays::point_class()))
+ THIS->move_by(to<Rays::Point&>(argv[0]));
+ else
+ {
+ if (argv[0].is_array())
+ {
+ argc = argv[0].size();
+ argv = argv[0].as_array();
+ }
+
+ coord x = (argc >= 1 && argv[0]) ? to<coord>(argv[0]) : 0;
+ coord y = (argc >= 2 && argv[1]) ? to<coord>(argv[1]) : 0;
+ coord z = (argc >= 3 && argv[2]) ? to<coord>(argv[2]) : 0;
+ THIS->move_by(x, y, z);
+ }
+
+ return self;
+}
+
+static
+VALUE resize_to(VALUE self)
+{
+ CHECK;
+ check_arg_count(__FILE__, __LINE__, "Bounds#resize_to", argc, 1, 2, 3);
+
+ if (argv[0].is_kind_of(Rays::point_class()))
+ THIS->resize_to(to<Rays::Point&>(argv[0]));
+ else
+ {
+ if (argv[0].is_array())
+ {
+ argc = argv[0].size();
+ argv = argv[0].as_array();
+ }
+
+ const Rays::Point& p = THIS->size();
+ coord x = (argc >= 1 && argv[0]) ? to<coord>(argv[0]) : p.x;
+ coord y = (argc >= 2 && argv[1]) ? to<coord>(argv[1]) : p.y;
+ coord z = (argc >= 3 && argv[2]) ? to<coord>(argv[2]) : p.z;
+ THIS->resize_to(x, y, z);
+ }
+
+ return self;
+}
+
+static
+VALUE resize_by(VALUE self)
+{
+ CHECK;
+ check_arg_count(__FILE__, __LINE__, "Bounds#resize_by", argc, 1, 2, 3);
+
+ if (argv[0].is_kind_of(Rays::point_class()))
+ THIS->resize_by(to<Rays::Point&>(argv[0]));
+ else
+ {
+ if (argv[0].is_array())
+ {
+ argc = argv[0].size();
+ argv = argv[0].as_array();
+ }
+
+ coord x = (argc >= 1 && argv[0]) ? to<coord>(argv[0]) : 0;
+ coord y = (argc >= 2 && argv[1]) ? to<coord>(argv[1]) : 0;
+ coord z = (argc >= 3 && argv[2]) ? to<coord>(argv[2]) : 0;
+ THIS->resize_by(x, y, z);
+ }
+
+ return self;
+}
+
+static
+VALUE inset_by(VALUE self)
+{
+ CHECK;
+ check_arg_count(__FILE__, __LINE__, "Bounds#inset_by", argc, 1, 2, 3);
+
+ if (argv[0].is_kind_of(Rays::point_class()))
+ THIS->inset_by(to<Rays::Point&>(argv[0]));
+ else
+ {
+ if (argv[0].is_array())
+ {
+ argc = argv[0].size();
+ argv = argv[0].as_array();
+ }
+
+ coord x = (argc >= 1 && argv[0]) ? to<coord>(argv[0]) : 0;
+ coord y = (argc >= 2 && argv[1]) ? to<coord>(argv[1]) : 0;
+ coord z = (argc >= 3 && argv[2]) ? to<coord>(argv[2]) : 0;
+ THIS->inset_by(x, y, z);
+ }
+
+ return self;
+}
+
+static
VALUE set_x(VALUE self, VALUE x)
{
CHECK;
return value(THIS->x = to<coord>(x));
@@ -315,18 +427,18 @@
return value(THIS->front());
}
static
-VALUE set_position(VALUE self, VALUE pos)
+VALUE set_position(VALUE self)
{
CHECK;
+ check_arg_count(__FILE__, __LINE__, "Bounds#set_position", argc, 1, 2, 3);
- Rays::Point* p = to<Rays::Point*>(pos);
- if (!p) argument_error("%s is not a Rays::Point.", pos.inspect().c_str());
-
- return value(THIS->position() = *p);
+ coord* pos = THIS->position().array;
+ for (int i = 0; i < 3; ++i)
+ if (argc > i && !argv[i].is_nil()) pos[i] = to<coord>(argv[i]);
}
static
VALUE get_position(VALUE self)
{
@@ -334,38 +446,126 @@
return value(THIS->position());
}
static
-VALUE set_size(VALUE self, VALUE size)
+VALUE set_size(VALUE self)
{
CHECK;
+ check_arg_count(__FILE__, __LINE__, "Bounds#set_size", argc, 1, 2, 3);
- Rays::Point* p = to<Rays::Point*>(size);
- if (!p) argument_error("%s is not a Rays::Point.", size.inspect().c_str());
-
- return value(THIS->size() = *p);
+ coord* size = THIS->size().array;
+ for (int i = 0; i < 3; ++i)
+ if (argc > i && !argv[i].is_nil()) size[i] = to<coord>(argv[i]);
}
static
VALUE get_size(VALUE self)
{
CHECK;
return value(THIS->size());
}
+static
+VALUE set_center(VALUE self)
+{
+ CHECK;
+ check_arg_count(__FILE__, __LINE__, "Bounds#set_center", argc, 1, 2, 3);
+ if (argv[0].is_kind_of(Rays::point_class()))
+ THIS->set_center(to<Rays::Point&>(argv[0]));
+ else
+ {
+ Rays::Point p = THIS->center();
+ coord x = (argc >= 1 && argv[0]) ? to<coord>(argv[0]) : p.x;
+ coord y = (argc >= 2 && argv[1]) ? to<coord>(argv[1]) : p.y;
+ coord z = (argc >= 3 && argv[2]) ? to<coord>(argv[2]) : p.z;
+ THIS->set_center(x, y, z);
+ }
+
+ return value(THIS->center());
+}
+
+static
+VALUE center(VALUE self)
+{
+ CHECK;
+
+ return value(THIS->center());
+}
+
+static
+VALUE array_get(VALUE self, VALUE index)
+{
+ CHECK;
+
+ int i = index.as_i();
+ if (i < 0 || 1 < i)
+ index_error(__FILE__, __LINE__);
+
+ return value((*THIS)[i]);
+}
+
+static
+VALUE array_set(VALUE self, VALUE index, VALUE value)
+{
+ CHECK;
+
+ int i = index.as_i();
+ if (i < 0 || 1 < i)
+ index_error(__FILE__, __LINE__);
+
+ (*THIS)[i] = to<Rays::Point&>(value);
+ return value;
+}
+
+static
+VALUE and_(VALUE self, VALUE bounds)
+{
+ CHECK;
+
+ Rays::Bounds b = *THIS;
+ b &= to<Rays::Bounds&>(bounds);
+ return value(b);
+}
+
+static
+VALUE or_(VALUE self, VALUE bounds)
+{
+ CHECK;
+
+ Rays::Bounds b = *THIS;
+ b |= to<Rays::Bounds&>(bounds);
+ return value(b);
+}
+
+static
+VALUE inspect(VALUE self)
+{
+ CHECK;
+
+ return value(Xot::stringf("#<Rays::Bounds %s>", THIS->inspect().c_str()));
+}
+
+
void
Init_bounds ()
{
Module mRays = rb_define_module("Rays");
cBounds = rb_define_class_under(mRays, "Bounds", rb_cObject);
rb_define_alloc_func(cBounds, alloc);
rb_define_private_method(cBounds, "initialize", RUBY_METHOD_FUNC(initialize), -1);
rb_define_private_method(cBounds, "initialize_copy", RUBY_METHOD_FUNC(initialize_copy), 1);
+ cBounds.define_method("intersect?", intersect);
+ cBounds.define_method("include?", include);
+ cBounds.define_method("move_to!", move_to);
+ cBounds.define_method("move_by!", move_by);
+ cBounds.define_method("resize_to!", resize_to);
+ cBounds.define_method("resize_by!", resize_by);
+ cBounds.define_method("inset_by!", inset_by);
rb_define_method(cBounds, "x=", RUBY_METHOD_FUNC(set_x), 1);
rb_define_method(cBounds, "x", RUBY_METHOD_FUNC(get_x), 0);
rb_define_method(cBounds, "y=", RUBY_METHOD_FUNC(set_y), 1);
rb_define_method(cBounds, "y", RUBY_METHOD_FUNC(get_y), 0);
rb_define_method(cBounds, "z=", RUBY_METHOD_FUNC(set_z), 1);
@@ -386,10 +586,92 @@
rb_define_method(cBounds, "bottom", RUBY_METHOD_FUNC(get_bottom), 0);
rb_define_method(cBounds, "back=", RUBY_METHOD_FUNC(set_back), 1);
rb_define_method(cBounds, "back", RUBY_METHOD_FUNC(get_back), 0);
rb_define_method(cBounds, "front=", RUBY_METHOD_FUNC(set_front), 1);
rb_define_method(cBounds, "front", RUBY_METHOD_FUNC(get_front), 0);
- rb_define_method(cBounds, "position=", RUBY_METHOD_FUNC(set_position), 1);
+ rb_define_method(cBounds, "set_position", RUBY_METHOD_FUNC(set_position), -1);
rb_define_method(cBounds, "position", RUBY_METHOD_FUNC(get_position), 0);
- rb_define_method(cBounds, "size=", RUBY_METHOD_FUNC(set_size), 1);
+ rb_define_method(cBounds, "set_size", RUBY_METHOD_FUNC(set_size), -1);
rb_define_method(cBounds, "size", RUBY_METHOD_FUNC(get_size), 0);
+ rb_define_method(cBounds, "set_center", RUBY_METHOD_FUNC(set_center), -1);
+ rb_define_method(cBounds, "center", RUBY_METHOD_FUNC(center), 0);
+ cBounds.define_method("[]", array_get);
+ cBounds.define_method("[]=", array_set);
+ cBounds.define_method("&", and_);
+ cBounds.define_method("|", or_);
+ rb_define_method(cBounds, "inspect", RUBY_METHOD_FUNC(inspect), 0);
}
+
+
+namespace Rucy
+{
+
+
+ template <> Rays::Bounds
+ value_to<Rays::Bounds> (Value value, bool convert)
+ {
+ if (convert)
+ {
+ size_t argc = 0;
+ Value* argv = NULL;
+ if (value.is_array())
+ {
+ argc = value.size();
+ argv = value.as_array();
+ }
+ else
+ {
+ argc = 1;
+ argv = &value;
+ }
+
+ if (argc < 1)
+ Rucy::argument_error(__FILE__, __LINE__);
+
+ if (argv[0].is_kind_of(Rays::bounds_class()))
+ value = argv[0];
+ else if (argv[0].is_kind_of(Rays::point_class()))
+ {
+ switch (argc)
+ {
+ #define V(i) to<Rays::Point&>(argv[i])
+ case 1: return Rays::Bounds(V(0));
+ case 2: return Rays::Bounds(V(0), V(1));
+ #undef V
+ default: Rucy::argument_error(__FILE__, __LINE__);
+ }
+ }
+ else if (argv[0].is_i() || argv[0].is_f())
+ {
+ switch (argc)
+ {
+ #define V(i) argv[i].as_f(true)
+ case 1: return Rays::Bounds(V(0));
+ case 2: return Rays::Bounds(V(0), V(1));
+ case 3: return Rays::Bounds(V(0), V(1), V(2));
+ case 4: return Rays::Bounds(V(0), V(1), V(2), V(3));
+ case 6: return Rays::Bounds(V(0), V(1), V(2), V(3), V(4), V(5));
+ #undef V
+ default: Rucy::argument_error(__FILE__, __LINE__);
+ }
+ }
+ }
+
+ return value_to<Rays::Bounds&>(value, convert);
+ }
+
+
+}// Rucy
+
+
+namespace Rays
+{
+
+
+ Class
+ bounds_class ()
+ {
+ return cBounds;
+ }
+
+
+}// Rays