diff options
| author | s-ol <s-ol@users.noreply.github.com> | 2019-11-28 17:12:20 +0000 |
|---|---|---|
| committer | s-ol <s-ol@users.noreply.github.com> | 2019-11-29 16:14:10 +0000 |
| commit | be6bdc9693df634224c3975b8c97924808c040a1 (patch) | |
| tree | be38e954a9412f3b888d71e43138f62adc0fb9cb /src/point.cpp | |
| parent | make compile as a janet module (diff) | |
| download | janet-2geom-be6bdc9693df634224c3975b8c97924808c040a1.tar.gz janet-2geom-be6bdc9693df634224c3975b8c97924808c040a1.zip | |
more point methods
Diffstat (limited to 'src/point.cpp')
| -rw-r--r-- | src/point.cpp | 212 |
1 files changed, 180 insertions, 32 deletions
diff --git a/src/point.cpp b/src/point.cpp index 70a4888..7fccfa0 100644 --- a/src/point.cpp +++ b/src/point.cpp @@ -25,10 +25,15 @@ const JanetAbstractType geom_point_type = { Janet janet_wrap_point(Geom::Point const &x) { Geom::Point *box = (Geom::Point *)janet_abstract(&geom_point_type, sizeof(Geom::Point)); - *box = (Geom::Point)x; + *box = Geom::Point(x); return janet_wrap_abstract(box); } +Janet janet_wrap_point(Geom::IntPoint const &x) { + Geom::Point *box = (Geom::Point *)janet_abstract(&geom_point_type, sizeof(Geom::Point)); + *box = Geom::Point(x); + return janet_wrap_abstract(box); +} Geom::Point janet_unwrap_point(Janet x) { if (janet_checktype(x, JANET_ABSTRACT)) { @@ -37,11 +42,33 @@ Geom::Point janet_unwrap_point(Janet x) { return *(Geom::Point *)abst; } - janet_panic("not a point"); - return Geom::Point(); + janet_panic("expected a geom/point"); +} + +Geom::Point janet_unwrap_point_or_scalar(Janet x) { + if (janet_checktype(x, JANET_ABSTRACT)) { + void *abst = janet_unwrap_abstract(x); + if (janet_abstract_type(abst) == &geom_point_type) + return *(Geom::Point *)abst; + } else if (janet_checktype(x, JANET_NUMBER)) { + double val = janet_unwrap_number(x); + return Geom::Point(val, val); + } + + janet_panic("expected a geom/point"); } +Geom::Point& janet_unwrap_point_ref(Janet x) { + if (janet_checktype(x, JANET_ABSTRACT)) { + void *abst = janet_unwrap_abstract(x); + if (janet_abstract_type(abst) == &geom_point_type) + return *(Geom::Point *)abst; + } + + janet_panic("expected a geom/point"); +} + extern "C" Janet cfun_geom_point_new(int32_t argc, Janet *argv) { janet_fixarity(argc, 2); double x = janet_getnumber(argv, 0); @@ -57,31 +84,159 @@ const JanetReg it_cfuns[] = { {NULL, NULL, NULL} }; +static Janet cfun_geom_point_add(int32_t argc, Janet *argv) { + janet_arity(argc, 2, -1); + Geom::Point *box = (Geom::Point *)janet_abstract(&geom_point_type, sizeof(Geom::Point)); + *box = janet_unwrap_point(argv[0]); + for (int i = 1; i < argc; i++) + *box += janet_unwrap_point(argv[i]); + return janet_wrap_abstract(box); +} -#define OPMETHOD(name, oper) \ +static Janet cfun_geom_point_add_mut(int32_t argc, Janet *argv) { + janet_arity(argc, 2, -1); + Geom::Point *box = (Geom::Point *)janet_getabstract(argv, 0, &geom_point_type); + for (int i = 1; i < argc; i++) + *box += janet_unwrap_point(argv[i]); + return janet_wrap_abstract(box); +} + +static Janet cfun_geom_point_sub(int32_t argc, Janet *argv) { + janet_arity(argc, 2, -1); + Geom::Point *box = (Geom::Point *)janet_abstract(&geom_point_type, sizeof(Geom::Point)); + *box = janet_unwrap_point(argv[0]); + for (int i = 1; i < argc; i++) + *box -= janet_unwrap_point(argv[i]); + return janet_wrap_abstract(box); +} + +static Janet cfun_geom_point_sub_mut(int32_t argc, Janet *argv) { + janet_arity(argc, 2, -1); + Geom::Point *box = (Geom::Point *)janet_getabstract(argv, 0, &geom_point_type); + for (int i = 1; i < argc; i++) + *box -= janet_unwrap_point(argv[i]); + return janet_wrap_abstract(box); +} + +static Janet cfun_geom_point_mul(int32_t argc, Janet *argv) { + janet_arity(argc, 2, -1); + Geom::Point *box = (Geom::Point *)janet_abstract(&geom_point_type, sizeof(Geom::Point)); + *box = janet_unwrap_point(argv[0]); + for (int i = 1; i < argc; i++) { + Geom::Point arg = janet_unwrap_point_or_scalar(argv[i]); + (*box)[0] *= arg[0]; + (*box)[1] *= arg[1]; + } + return janet_wrap_abstract(box); +} + +static Janet cfun_geom_point_mul_mut(int32_t argc, Janet *argv) { + janet_arity(argc, 2, -1); + Geom::Point *box = (Geom::Point *)janet_getabstract(argv, 0, &geom_point_type); + for (int i = 1; i < argc; i++) { + Geom::Point arg = janet_unwrap_point_or_scalar(argv[i]); + (*box)[0] *= arg[0]; + (*box)[1] *= arg[1]; + } + return janet_wrap_abstract(box); +} + +static Janet cfun_geom_point_div(int32_t argc, Janet *argv) { + janet_arity(argc, 2, -1); + Geom::Point *box = (Geom::Point *)janet_abstract(&geom_point_type, sizeof(Geom::Point)); + *box = janet_unwrap_point(argv[0]); + for (int i = 1; i < argc; i++) { + Geom::Point arg = janet_unwrap_point_or_scalar(argv[i]); + (*box)[0] /= arg[0]; + (*box)[1] /= arg[1]; + } + return janet_wrap_abstract(box); +} + +static Janet cfun_geom_point_div_mut(int32_t argc, Janet *argv) { + janet_arity(argc, 2, -1); + Geom::Point *box = (Geom::Point *)janet_getabstract(argv, 0, &geom_point_type); + for (int i = 1; i < argc; i++) { + Geom::Point arg = janet_unwrap_point_or_scalar(argv[i]); + (*box)[0] /= arg[0]; + (*box)[1] /= arg[1]; + } + return janet_wrap_abstract(box); +} + +static Janet cfun_geom_point_eq(int32_t argc, Janet *argv) { + janet_fixarity(argc, 2); + Geom::Point& v1 = janet_unwrap_point_ref(argv[0]); + Geom::Point& v2 = janet_unwrap_point_ref(argv[1]); + return janet_wrap_boolean(v1 == v2); +} + +static Janet cfun_geom_point_lt(int32_t argc, Janet *argv) { + janet_fixarity(argc, 2); + Geom::Point& v1 = janet_unwrap_point_ref(argv[0]); + Geom::Point& v2 = janet_unwrap_point_ref(argv[1]); + return janet_wrap_boolean(v1 < v2); +} + +#define CONSTMETHOD(name, method, type) \ static Janet cfun_geom_point_##name(int32_t argc, Janet *argv) { \ - janet_arity(argc, 2, -1); \ - Geom::Point *box = (Geom::Point *)janet_abstract(&geom_point_type, sizeof(Geom::Point)); \ - *box = janet_unwrap_point(argv[0]); \ - for (int i = 1; i < argc; i++) \ - *box oper##= janet_unwrap_point(argv[i]); \ - return janet_wrap_abstract(box); \ -} \ - \ -static Janet cfun_geom_point_##name##_mut(int32_t argc, Janet *argv) { \ - janet_arity(argc, 2, -1); \ - Geom::Point *box = (Geom::Point *)janet_abstract(&geom_point_type, sizeof(Geom::Point)); \ - for (int i = 1; i < argc; i++) \ - *box oper##= janet_unwrap_point(argv[i]); \ - return janet_wrap_abstract(box); \ -} - -OPMETHOD(add, +) -OPMETHOD(sub, -) + janet_fixarity(argc, 1); \ + Geom::Point *box = (Geom::Point *)janet_getabstract(argv, 0, &geom_point_type); \ + return janet_wrap_##type(box->method()); \ +} + +CONSTMETHOD(is_zero, isZero, boolean) +CONSTMETHOD(is_finite, isFinite, boolean) +CONSTMETHOD(is_normalized, isNormalized, boolean) + +CONSTMETHOD(x, x, number) +CONSTMETHOD(y, y, number) +CONSTMETHOD(length, length, number) + +CONSTMETHOD(cw, cw, point) +CONSTMETHOD(ccw, ccw, point) +CONSTMETHOD(round, round, point) +CONSTMETHOD(floor, floor, point) +CONSTMETHOD(ceil, ceil, point) +CONSTMETHOD(normalize, normalized, point) + +static Janet cfun_geom_point_normalize_mut(int32_t argc, Janet *argv) { + janet_fixarity(argc, 1); + Geom::Point *box = (Geom::Point *)janet_getabstract(argv, 0, &geom_point_type); + box->normalize(); + return janet_wrap_point(*box); +} static JanetMethod geom_point_methods[] = { - {"+", cfun_geom_point_add}, - {"-", cfun_geom_point_sub}, + {"+", cfun_geom_point_add}, + {"-", cfun_geom_point_sub}, + {"*", cfun_geom_point_mul}, + {"/", cfun_geom_point_div}, + {"<", cfun_geom_point_lt}, + {"==", cfun_geom_point_eq}, + + {"+!", cfun_geom_point_add_mut}, + {"-!", cfun_geom_point_sub_mut}, + {"*!", cfun_geom_point_mul_mut}, + {"/!", cfun_geom_point_div_mut}, + + {"zero?", cfun_geom_point_is_zero}, + {"finite?", cfun_geom_point_is_finite}, + {"normalized?", cfun_geom_point_is_normalized}, + + {"x", cfun_geom_point_x}, + {"y", cfun_geom_point_y}, + {"length", cfun_geom_point_length}, + + {"cw", cfun_geom_point_cw}, + {"ccw", cfun_geom_point_ccw}, + {"round", cfun_geom_point_round}, + {"floor", cfun_geom_point_floor}, + {"ceil", cfun_geom_point_ceil}, + {"normalize", cfun_geom_point_normalize}, + + {"normalize!", cfun_geom_point_normalize_mut}, + {NULL, NULL} }; @@ -90,14 +245,7 @@ extern "C" Janet geom_point_get(void *p, Janet key) { if (!janet_checktype(key, JANET_KEYWORD)) janet_panicf("expected keyword, got %v", key); - uint8_t const *keystr = janet_unwrap_keyword(key); - if (janet_string_equal(keystr, janet_cstring("x"))) { - return janet_wrap_number(box->x()); - } else if (janet_string_equal(keystr, janet_cstring("y"))) { - return janet_wrap_number(box->y()); - } else { - return janet_getmethod(keystr, geom_point_methods); - } + return janet_getmethod(janet_unwrap_keyword(key), geom_point_methods); } extern "C" void janet_lib_geom_point(JanetTable *env) { |
