diff options
| author | s-ol <s-ol@users.noreply.github.com> | 2019-12-02 14:32:42 +0000 |
|---|---|---|
| committer | s-ol <s-ol@users.noreply.github.com> | 2019-12-02 14:32:42 +0000 |
| commit | 81fe2250a70c892eeb195725117d566a042e5c93 (patch) | |
| tree | e2c70bd1b0f9e9d9063f6ff7aa11f6fa6b8ced80 /src/livecode/api | |
| parent | add basic livecode toolbar (diff) | |
| download | inkscape-81fe2250a70c892eeb195725117d566a042e5c93.tar.gz inkscape-81fe2250a70c892eeb195725117d566a042e5c93.zip | |
add draft janet interface for livecoding
Diffstat (limited to 'src/livecode/api')
| -rw-r--r-- | src/livecode/api/api.h | 34 | ||||
| -rw-r--r-- | src/livecode/api/context.cpp | 21 | ||||
| -rw-r--r-- | src/livecode/api/input.cpp | 113 | ||||
| -rw-r--r-- | src/livecode/api/point.cpp | 298 |
4 files changed, 466 insertions, 0 deletions
diff --git a/src/livecode/api/api.h b/src/livecode/api/api.h new file mode 100644 index 000000000..94694ca56 --- /dev/null +++ b/src/livecode/api/api.h @@ -0,0 +1,34 @@ +#ifndef JANET_2GEOM_POINT_INCLUDED +#define JANET_2GEOM_POINT_INCLUDED + +#include <janet.h> +#include <2geom/point.h> +#include "livecode/context.h" +#include "livecode/input.h" + +namespace Inkscape { +namespace Livecode { + +/* context.cpp */ +void janet_lib_context(JanetTable *env, Context &context); + +Context &ctx(); + +/* point.cpp */ +void janet_lib_geom_point(JanetTable *env); + +extern const JanetAbstractType geom_point_type; + +Janet janet_wrap_point(Geom::Point const &x); +Janet janet_wrap_point(Geom::IntPoint const &x); +Geom::Point janet_unwrap_point(Janet x); + +/* input.cpp */ +void janet_lib_input(JanetTable *env); + +Janet janet_wrap_inputstate(InputState const &state); + +} +} + +#endif // JANET_2GEOM_POINT_INCLUDED diff --git a/src/livecode/api/context.cpp b/src/livecode/api/context.cpp new file mode 100644 index 000000000..43c6881d1 --- /dev/null +++ b/src/livecode/api/context.cpp @@ -0,0 +1,21 @@ +#include "livecode/api/api.h" + +namespace Inkscape { +namespace Livecode { + +static Context *_context = nullptr; + +Context &ctx() { + if (!_context) { + janet_panic("Livecode Context uninitialized!!"); + } + + return *_context; +} + +void janet_lib_context(JanetTable *env, Context &context) { + _context = &context; +} + +} +} diff --git a/src/livecode/api/input.cpp b/src/livecode/api/input.cpp new file mode 100644 index 000000000..0fc820bbd --- /dev/null +++ b/src/livecode/api/input.cpp @@ -0,0 +1,113 @@ +#include "livecode/api/api.h" + +#include <sstream> + +namespace Inkscape { +namespace Livecode { + +extern "C" Janet cfun_mouse_pos(int32_t argc, Janet *argv) { + janet_fixarity(argc, 0); + return janet_wrap_point(ctx().mouse().pos()); +} + +extern "C" Janet cfun_mouse_delta(int32_t argc, Janet *argv) { + janet_fixarity(argc, 0); + return janet_wrap_point(ctx().mouse().delta()); +} + +extern "C" Janet cfun_mouse_ui_pos(int32_t argc, Janet *argv) { + janet_fixarity(argc, 0); + return janet_wrap_point(ctx().mouse().ui_pos()); +} + +extern "C" Janet cfun_mouse_ui_delta(int32_t argc, Janet *argv) { + janet_fixarity(argc, 0); + return janet_wrap_point(ctx().mouse().ui_delta()); +} + +Janet janet_wrap_inputstate(InputState const &state) { + switch (state) { + case INPUTSTATE_NONE: + return janet_wrap_nil(); + case INPUTSTATE_HOVER: + return janet_ckeywordv("hover"); + case INPUTSTATE_PRESSED: + return janet_ckeywordv("pressed"); + case INPUTSTATE_HELD: + return janet_ckeywordv("held"); + case INPUTSTATE_RELEASED: + return janet_ckeywordv("released"); + default: + janet_panic("unexpected event value"); + } +} + +extern "C" Janet cfun_mouse_event(int32_t argc, Janet *argv) { + janet_arity(argc, 0, 1); + + guint button = janet_getsize(argv, 1); + if (button < 1 || button > 5) { + janet_panic("expected button to be between 1 and 5"); + } + + return janet_wrap_inputstate(ctx().mouse().event(button)); +} + +#define BUTTONMETHOD(name) \ +extern "C" Janet cfun_mouse_##name(int32_t argc, Janet *argv) { \ + janet_arity(argc, 0, 1); \ + guint button = janet_getsize(argv, 1); \ + if (button < 1 || button > 5) { \ + janet_panic("expected button to be between 1 and 5"); \ + } \ + return janet_wrap_boolean(ctx().mouse().name(button)); \ +} + +BUTTONMETHOD(pressed) +BUTTONMETHOD(held) +BUTTONMETHOD(released) + +const JanetReg it_cfuns[] = { + { + "mouse/pos", cfun_mouse_pos, + "(mouse/pos)\n\nGet the current mouse position as a geom/point." + }, + { + "mouse/delta", cfun_mouse_delta, + "(mouse/pos)\n\nGet the mouse motion since last frame as a geom/point." + }, + { + "mouse/ui-pos", cfun_mouse_ui_pos, + "(mouse/pos)\n\nGet the current mouse position as a geom/point, in UI space." + }, + { + "mouse/ui-delta", cfun_mouse_ui_delta, + "(mouse/pos)\n\nGet the mouse motion since last frame as a geom/point, in UI space." + }, + { + "mouse/event", cfun_mouse_event, + "(mouse/event [button])\n\nGet the current event/status for a mouse button.\n" + "Returns either nil, :pressed, :held or :released." + }, + { + "mouse/pressed", cfun_mouse_pressed, + "(mouse/pressed [button])\n\nCheck whether a mouse button was pressed this frame.\n" + }, + { + "mouse/held", cfun_mouse_held, + "(mouse/held [button])\n\nCheck whether a mouse button was held down this frame.\n" + }, + { + "mouse/released", cfun_mouse_released, + "(mouse/released [button])\n\nCheck whether a mouse button was released this frame.\n" + }, + {NULL, NULL, NULL} +}; + + +void janet_lib_input(JanetTable *env) { + janet_cfuns(env, NULL, it_cfuns); +} + +} +} diff --git a/src/livecode/api/point.cpp b/src/livecode/api/point.cpp new file mode 100644 index 000000000..6eab6af1d --- /dev/null +++ b/src/livecode/api/point.cpp @@ -0,0 +1,298 @@ +#include "livecode/api/api.h" + +#include <sstream> + +namespace Inkscape { +namespace Livecode { + +extern "C" Janet geom_point_get(void *p, Janet key); +extern "C" void geom_point_set(void *p, Janet key, Janet value); + +extern "C" void geom_point_tostring(void *p, JanetBuffer *buffer) { + std::stringstream stream; + stream << "<2geom/point " << *static_cast<Geom::Point *>(p) << ">"; + janet_buffer_push_cstring(buffer, stream.str().c_str()); +} + + +const JanetAbstractType geom_point_type = { + "2geom/point", + NULL, + NULL, + geom_point_get, + geom_point_set, + NULL, + NULL, + geom_point_tostring +}; + + +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); + 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)) { + void *abst = janet_unwrap_abstract(x); + if (janet_abstract_type(abst) == &geom_point_type) + return *(Geom::Point *)abst; + } + + 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_arity(argc, 0, 2); + double x = 0; + double y = 0; + if (argc == 2) { + x = janet_getnumber(argv, 0); + y = janet_getnumber(argv, 1); + } else if (argc == 1) { + x = janet_getnumber(argv, 0); + y = x; + } + return janet_wrap_point(Geom::Point(x, y)); +} + +const JanetReg it_cfuns[] = { + { + "point", cfun_geom_point_new, + "(geom/point x y)\n\nCreate a Point from x/y coordinate values." + }, + {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); +} + +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_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_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} +}; + +extern "C" Janet geom_point_get(void *p, Janet key) { + Geom::Point *box = (Geom::Point *)p; + + if (janet_checktype(key, JANET_KEYWORD)) + return janet_getmethod(janet_unwrap_keyword(key), geom_point_methods); + + if (!janet_checksize(key)) janet_panic("expected size as key"); + + size_t const index = (size_t) janet_unwrap_number(key); + switch (index) { + case 0: + return janet_wrap_number((*box)[0]); + case 1: + return janet_wrap_number((*box)[1]); + default: + return janet_wrap_nil(); + } +} + +extern "C" void geom_point_set(void *p, Janet key, Janet value) { + Geom::Point *box = (Geom::Point *)p; + + if (!janet_checksize(key)) janet_panic("expected size as key"); + if (!janet_checktype(key, JANET_NUMBER)) janet_panic("expected number as value"); + + size_t const index = (size_t) janet_unwrap_number(key); + switch (index) { + case 0: + (*box)[0] = janet_unwrap_number(value); + break; + case 1: + (*box)[1] = janet_unwrap_number(value); + break; + default: + janet_panic("index out of bounds"); + } +} + +void janet_lib_geom_point(JanetTable *env) { + janet_cfuns(env, NULL, it_cfuns); + janet_register_abstract_type(&geom_point_type); +} + +} +} |
