mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[Update] Upstream
This commit is contained in:
@@ -487,6 +487,7 @@ Q(st)
|
||||
Q(hideturtle)
|
||||
Q(ht)
|
||||
Q(isvisible)
|
||||
Q(colormode)
|
||||
|
||||
// utime QSTRs
|
||||
Q(time)
|
||||
|
||||
@@ -1,33 +1,17 @@
|
||||
extern "C" {
|
||||
#include "modkandinsky.h"
|
||||
#include <py/objtuple.h>
|
||||
#include <py/runtime.h>
|
||||
}
|
||||
#include <kandinsky.h>
|
||||
#include <ion.h>
|
||||
#include "port.h"
|
||||
|
||||
static KDColor ColorForTuple(mp_obj_t tuple) {
|
||||
size_t len;
|
||||
mp_obj_t * elem;
|
||||
|
||||
mp_obj_get_array(tuple, &len, &elem);
|
||||
if (len != 3) {
|
||||
mp_raise_TypeError("color needs 3 components");
|
||||
}
|
||||
|
||||
return KDColor::RGB888(
|
||||
mp_obj_get_int(elem[0]),
|
||||
mp_obj_get_int(elem[1]),
|
||||
mp_obj_get_int(elem[2])
|
||||
);
|
||||
}
|
||||
|
||||
static mp_obj_t TupleForRGB(uint8_t r, uint8_t g, uint8_t b) {
|
||||
static mp_obj_t TupleForKDColor(KDColor c) {
|
||||
mp_obj_tuple_t * t = static_cast<mp_obj_tuple_t *>(MP_OBJ_TO_PTR(mp_obj_new_tuple(3, NULL)));
|
||||
t->items[0] = MP_OBJ_NEW_SMALL_INT(r);
|
||||
t->items[1] = MP_OBJ_NEW_SMALL_INT(g);
|
||||
t->items[2] = MP_OBJ_NEW_SMALL_INT(b);
|
||||
t->items[0] = MP_OBJ_NEW_SMALL_INT(c.red());
|
||||
t->items[1] = MP_OBJ_NEW_SMALL_INT(c.green());
|
||||
t->items[2] = MP_OBJ_NEW_SMALL_INT(c.blue());
|
||||
return MP_OBJ_FROM_PTR(t);
|
||||
}
|
||||
|
||||
@@ -37,12 +21,18 @@ static mp_obj_t TupleForRGB(uint8_t r, uint8_t g, uint8_t b) {
|
||||
* the stackViewController and forces the window to redraw itself.
|
||||
* KDIonContext::sharedContext is set to the frame of the last object drawn. */
|
||||
|
||||
mp_obj_t modkandinsky_color(mp_obj_t red, mp_obj_t green, mp_obj_t blue) {
|
||||
return TupleForRGB(
|
||||
mp_obj_get_int(red),
|
||||
mp_obj_get_int(green),
|
||||
mp_obj_get_int(blue)
|
||||
);
|
||||
mp_obj_t modkandinsky_color(size_t n_args, const mp_obj_t *args) {
|
||||
mp_obj_t color;
|
||||
if (n_args == 1) {
|
||||
color = args[0];
|
||||
} else if (n_args == 2) {
|
||||
mp_raise_TypeError("color takes 1 or 3 arguments");
|
||||
return mp_const_none;
|
||||
} else {
|
||||
assert(n_args == 3);
|
||||
color = mp_obj_new_tuple(n_args, args);
|
||||
}
|
||||
return TupleForKDColor(MicroPython::ColorParser::ParseColor(color));
|
||||
}
|
||||
|
||||
/* Calling ExecutionEnvironment::displaySandbox() hides the console and switches
|
||||
@@ -54,22 +44,23 @@ mp_obj_t modkandinsky_get_pixel(mp_obj_t x, mp_obj_t y) {
|
||||
KDPoint point(mp_obj_get_int(x), mp_obj_get_int(y));
|
||||
KDColor c;
|
||||
KDIonContext::sharedContext()->getPixel(point, &c);
|
||||
return TupleForRGB(c.red(), c.green(), c.blue());
|
||||
return TupleForKDColor(c);
|
||||
}
|
||||
|
||||
mp_obj_t modkandinsky_set_pixel(mp_obj_t x, mp_obj_t y, mp_obj_t color) {
|
||||
mp_obj_t modkandinsky_set_pixel(mp_obj_t x, mp_obj_t y, mp_obj_t input) {
|
||||
KDPoint point(mp_obj_get_int(x), mp_obj_get_int(y));
|
||||
KDColor kdColor = ColorForTuple(color);
|
||||
KDColor kdColor = MicroPython::ColorParser::ParseColor(input);
|
||||
MicroPython::ExecutionEnvironment::currentExecutionEnvironment()->displaySandbox();
|
||||
KDIonContext::sharedContext()->setPixel(point, kdColor);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
//TODO Use good colors
|
||||
mp_obj_t modkandinsky_draw_string(size_t n_args, const mp_obj_t * args) {
|
||||
const char * text = mp_obj_str_get_str(args[0]);
|
||||
KDPoint point(mp_obj_get_int(args[1]), mp_obj_get_int(args[2]));
|
||||
KDColor textColor = (n_args >= 4) ? ColorForTuple(args[3]) : KDColorBlack;
|
||||
KDColor backgroundColor = (n_args >= 5) ? ColorForTuple(args[4]) : KDColorWhite;
|
||||
KDColor textColor = (n_args >= 4) ? MicroPython::ColorParser::ParseColor(args[3]) : KDColorBlack;
|
||||
KDColor backgroundColor = (n_args >= 5) ? MicroPython::ColorParser::ParseColor(args[4]) : KDColorWhite;
|
||||
MicroPython::ExecutionEnvironment::currentExecutionEnvironment()->displaySandbox();
|
||||
KDIonContext::sharedContext()->drawString(text, point, KDFont::LargeFont, textColor, backgroundColor);
|
||||
/* Before and after execution of "modkandinsky_draw_string",
|
||||
@@ -99,8 +90,7 @@ mp_obj_t modkandinsky_fill_rect(size_t n_args, const mp_obj_t * args) {
|
||||
y = y - height;
|
||||
}
|
||||
KDRect rect(x, y, width, height);
|
||||
KDColor color = ColorForTuple(args[4]);
|
||||
|
||||
KDColor color = MicroPython::ColorParser::ParseColor(args[4]);
|
||||
MicroPython::ExecutionEnvironment::currentExecutionEnvironment()->displaySandbox();
|
||||
KDIonContext::sharedContext()->fillRect(rect, color);
|
||||
// Cf comment on modkandinsky_draw_string
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <py/obj.h>
|
||||
|
||||
mp_obj_t modkandinsky_color(mp_obj_t red, mp_obj_t green, mp_obj_t blue);
|
||||
mp_obj_t modkandinsky_color(size_t n_args, const mp_obj_t *args);
|
||||
mp_obj_t modkandinsky_get_pixel(mp_obj_t x, mp_obj_t y);
|
||||
mp_obj_t modkandinsky_set_pixel(mp_obj_t x, mp_obj_t y, mp_obj_t color);
|
||||
mp_obj_t modkandinsky_draw_string(size_t n_args, const mp_obj_t *args);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "modkandinsky.h"
|
||||
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(modkandinsky_color_obj, modkandinsky_color);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modkandinsky_color_obj, 1, 3, modkandinsky_color);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(modkandinsky_get_pixel_obj, modkandinsky_get_pixel);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(modkandinsky_set_pixel_obj, modkandinsky_set_pixel);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modkandinsky_draw_string_obj, 3, 5, modkandinsky_draw_string);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
extern "C" {
|
||||
#include "modturtle.h"
|
||||
#include <py/gc.h>
|
||||
#include <py/objtuple.h>
|
||||
#include <py/runtime.h>
|
||||
}
|
||||
#include "turtle.h"
|
||||
#include "../../port.h"
|
||||
@@ -130,42 +132,54 @@ mp_obj_t modturtle_isdown() {
|
||||
return sTurtle.isPenDown() ? mp_const_true : mp_const_false;
|
||||
}
|
||||
|
||||
mp_float_t uint8tColorToDouble(uint8_t c) { return static_cast<double>(c)/255.0; }
|
||||
|
||||
mp_obj_t modturtle_pencolor(size_t n_args, const mp_obj_t *args) {
|
||||
if (n_args == 0) {
|
||||
// pencolor()
|
||||
KDColor c = sTurtle.color();
|
||||
mp_obj_t mp_col[3];
|
||||
mp_col[0] = mp_obj_new_int_from_uint(c.red());
|
||||
mp_col[1] = mp_obj_new_int_from_uint(c.green());
|
||||
mp_col[2] = mp_obj_new_int_from_uint(c.blue());
|
||||
if(sTurtle.colorMode() == MicroPython::ColorParser::ColorMode::MaxIntensity255){
|
||||
mp_col[0] = mp_obj_new_int_from_uint(c.red());
|
||||
mp_col[1] = mp_obj_new_int_from_uint(c.green());
|
||||
mp_col[2] = mp_obj_new_int_from_uint(c.blue());
|
||||
} else {
|
||||
mp_col[0] = mp_obj_new_float(uint8tColorToDouble(c.red()));
|
||||
mp_col[1] = mp_obj_new_float(uint8tColorToDouble(c.green()));
|
||||
mp_col[2] = mp_obj_new_float(uint8tColorToDouble(c.blue()));
|
||||
}
|
||||
return mp_obj_new_tuple(3, mp_col);
|
||||
}
|
||||
if (n_args == 1) {
|
||||
if (MP_OBJ_IS_STR(args[0])) {
|
||||
// pencolor("blue")
|
||||
size_t l;
|
||||
sTurtle.setColor(mp_obj_str_get_data(args[0], &l));
|
||||
} else {
|
||||
// pencolor((r, g, b))
|
||||
mp_obj_t * rgb;
|
||||
mp_obj_get_array_fixed_n(args[0], 3, &rgb);
|
||||
sTurtle.setColor(
|
||||
KDColor::RGB888(
|
||||
mp_obj_get_int(rgb[0]),
|
||||
mp_obj_get_int(rgb[1]),
|
||||
mp_obj_get_int(rgb[2])));
|
||||
}
|
||||
} else if (n_args == 3) {
|
||||
// pencolor(r, g, b)
|
||||
sTurtle.setColor(
|
||||
KDColor::RGB888(
|
||||
mp_obj_get_int(args[0]),
|
||||
mp_obj_get_int(args[1]),
|
||||
mp_obj_get_int(args[2])));
|
||||
if (n_args == 2) {
|
||||
mp_raise_TypeError("pencolor() takes 0, 1 or 3 arguments");
|
||||
return mp_const_none;
|
||||
}
|
||||
mp_obj_t color;
|
||||
if (n_args == 1) {
|
||||
color = args[0];
|
||||
} else {
|
||||
assert(n_args == 3);
|
||||
color = mp_obj_new_tuple(n_args, args);
|
||||
}
|
||||
sTurtle.setColor(MicroPython::ColorParser::ParseColor(color, sTurtle.colorMode()));
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t modturtle_colormode(size_t n_args, const mp_obj_t *args) {
|
||||
if(n_args == 0){
|
||||
return mp_obj_new_int_from_uint(static_cast<int>(sTurtle.colorMode()));
|
||||
} else{
|
||||
int colorMode = mp_obj_get_int(args[0]);
|
||||
if (colorMode != static_cast<int>(MicroPython::ColorParser::ColorMode::MaxIntensity1) &&
|
||||
colorMode != static_cast<int>(MicroPython::ColorParser::ColorMode::MaxIntensity255)) {
|
||||
mp_raise_ValueError("Colormode can be 1 or 255");
|
||||
return mp_const_none;
|
||||
}
|
||||
sTurtle.setColorMode(static_cast<MicroPython::ColorParser::ColorMode>(colorMode));
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
|
||||
mp_obj_t modturtle_showturtle() {
|
||||
sTurtle.setVisible(true);
|
||||
return mp_const_none;
|
||||
|
||||
@@ -25,6 +25,7 @@ mp_obj_t modturtle_pensize(size_t n_args, const mp_obj_t *args);
|
||||
mp_obj_t modturtle_isvisible();
|
||||
|
||||
mp_obj_t modturtle_pencolor(size_t n_args, const mp_obj_t *args);
|
||||
mp_obj_t modturtle_colormode(size_t n_args, const mp_obj_t *args);
|
||||
|
||||
mp_obj_t modturtle_showturtle();
|
||||
mp_obj_t modturtle_hideturtle();
|
||||
|
||||
@@ -18,6 +18,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modturtle_pensize_obj, 0, 1, modturtl
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(modturtle_isdown_obj, modturtle_isdown);
|
||||
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modturtle_pencolor_obj, 0, 3, modturtle_pencolor);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modturtle_colormode_obj, 0, 1, modturtle_colormode);
|
||||
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(modturtle_reset_obj, modturtle_reset);
|
||||
|
||||
@@ -64,6 +65,7 @@ STATIC const mp_rom_map_elem_t modturtle_module_globals_table[] = {
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_color), (mp_obj_t)&modturtle_pencolor_obj },
|
||||
{ MP_ROM_QSTR(MP_QSTR_pencolor), (mp_obj_t)&modturtle_pencolor_obj },
|
||||
{ MP_ROM_QSTR(MP_QSTR_colormode), (mp_obj_t)&modturtle_colormode_obj },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_reset), (mp_obj_t)&modturtle_reset_obj },
|
||||
|
||||
|
||||
@@ -175,27 +175,6 @@ void Turtle::setVisible(bool visible) {
|
||||
}
|
||||
}
|
||||
|
||||
void Turtle::setColor(const char * color) {
|
||||
constexpr NameColorPair pairs[] = {
|
||||
NameColorPair("blue", KDColorBlue),
|
||||
NameColorPair("red", KDColorRed),
|
||||
NameColorPair("green", Palette::Green),
|
||||
NameColorPair("yellow", KDColorYellow),
|
||||
NameColorPair("brown", Palette::Brown),
|
||||
NameColorPair("black", KDColorBlack),
|
||||
NameColorPair("white", KDColorWhite),
|
||||
NameColorPair("pink", Palette::Pink),
|
||||
NameColorPair("orange", Palette::Orange),
|
||||
NameColorPair("purple", Palette::Purple),
|
||||
NameColorPair("grey", Palette::GreyDark)
|
||||
};
|
||||
for (NameColorPair p : pairs) {
|
||||
if (strcmp(p.name(), color) == 0) {
|
||||
m_color = p.color();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Turtle::viewDidDisappear() {
|
||||
m_drawn = false;
|
||||
|
||||
@@ -8,6 +8,7 @@ extern "C" {
|
||||
#include <escher/metric.h>
|
||||
#include <kandinsky.h>
|
||||
#include <math.h>
|
||||
#include <python/port/port.h>
|
||||
|
||||
/* We check for keyboard interruptions using micropython_port_vm_hook_loop and
|
||||
* micropython_port_interruptible_msleep, but even if we catch an interruption,
|
||||
@@ -29,6 +30,7 @@ public:
|
||||
m_y(0),
|
||||
m_heading(0),
|
||||
m_color(k_defaultColor),
|
||||
m_colorMode(MicroPython::ColorParser::ColorMode::MaxIntensity255),
|
||||
m_penDown(true),
|
||||
m_visible(true),
|
||||
m_speed(k_defaultSpeed),
|
||||
@@ -71,7 +73,10 @@ public:
|
||||
void setColor(uint8_t r, uint8_t g, uint8_t b) {
|
||||
m_color = KDColor::RGB888(r, g, b);
|
||||
}
|
||||
void setColor(const char * color);
|
||||
MicroPython::ColorParser::ColorMode colorMode() const {return m_colorMode; }
|
||||
void setColorMode(MicroPython::ColorParser::ColorMode colorMode){
|
||||
m_colorMode = colorMode;
|
||||
}
|
||||
|
||||
void viewDidDisappear();
|
||||
|
||||
@@ -102,19 +107,6 @@ private:
|
||||
Forward = 2
|
||||
};
|
||||
|
||||
class NameColorPair {
|
||||
public:
|
||||
constexpr NameColorPair(const char * name, KDColor color) :
|
||||
m_name(name),
|
||||
m_color(color)
|
||||
{}
|
||||
const char * name() const { return m_name; }
|
||||
KDColor color() const { return m_color; }
|
||||
private:
|
||||
const char * m_name;
|
||||
KDColor m_color;
|
||||
};
|
||||
|
||||
void setHeadingPrivate(mp_float_t angle);
|
||||
KDPoint position(mp_float_t x, mp_float_t y) const;
|
||||
KDPoint position() const { return position(m_x, m_y); }
|
||||
@@ -149,6 +141,7 @@ private:
|
||||
mp_float_t m_heading;
|
||||
|
||||
KDColor m_color;
|
||||
MicroPython::ColorParser::ColorMode m_colorMode;
|
||||
bool m_penDown;
|
||||
bool m_visible;
|
||||
|
||||
|
||||
@@ -1,12 +1,19 @@
|
||||
#include "port.h"
|
||||
|
||||
#include <ion/keyboard.h>
|
||||
#include <ion.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
/* py/parsenum.h is a C header which uses C keyword restrict.
|
||||
* It does not exist in C++ so we define it here in order to be able to include
|
||||
* py/parsenum.h header. */
|
||||
#ifdef __cplusplus
|
||||
#define restrict // disable
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
#include "py/builtin.h"
|
||||
#include "py/compile.h"
|
||||
@@ -15,6 +22,7 @@ extern "C" {
|
||||
#include "py/mperrno.h"
|
||||
#include "py/mphal.h"
|
||||
#include "py/nlr.h"
|
||||
#include "py/parsenum.h"
|
||||
#include "py/repl.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/stackctrl.h"
|
||||
@@ -23,6 +31,8 @@ extern "C" {
|
||||
#include "mod/matplotlib/pyplot/modpyplot.h"
|
||||
}
|
||||
|
||||
#include <escher/palette.h>
|
||||
|
||||
static MicroPython::ScriptProvider * sScriptProvider = nullptr;
|
||||
static MicroPython::ExecutionEnvironment * sCurrentExecutionEnvironment = nullptr;
|
||||
|
||||
@@ -145,85 +155,130 @@ void MicroPython::registerScriptProvider(ScriptProvider * s) {
|
||||
}
|
||||
|
||||
void MicroPython::collectRootsAtAddress(char * address, int byteLength) {
|
||||
#if __EMSCRIPTEN__
|
||||
// All objects are aligned, as asserted.
|
||||
/* All addresses stored on the stack are aligned on sizeof(void *), as
|
||||
* asserted. This is a consequence of the alignment requirements of compilers
|
||||
* (Cf http://www.catb.org/esr/structure-packing/). */
|
||||
assert(((unsigned long)address) % ((unsigned long)sizeof(void *)) == 0);
|
||||
assert(byteLength % sizeof(void *) == 0);
|
||||
gc_collect_root((void **)address, byteLength / sizeof(void *));
|
||||
#else
|
||||
for (size_t i = 0; i < sizeof(void *); i++) {
|
||||
/* Objects on the stack are not necessarily aligned on sizeof(void *),
|
||||
* which is also true for pointers refering to the heap. MicroPython
|
||||
* gc_collect_root expects a table of void * that will be scanned every
|
||||
* sizeof(void *) step. So we have to scan the stack repetitively with a
|
||||
* increasing offset to be sure to check every byte for a heap address.
|
||||
* If some memory can be reinterpreted as a pointer in the heap, gc_collect_root
|
||||
* will prevent the destruction of the pointed heap memory. At worst (if
|
||||
* the interpreted pointer was in fact an unaligned object or uninitialized
|
||||
* memory), we will just keep extra objects in the heap which is not optimal
|
||||
* but does not cause any crash. */
|
||||
char * addressWithOffset = address + i;
|
||||
// Ensure to round the length to the ceiling
|
||||
size_t lengthInAddressSize = (byteLength - i + sizeof(void *) - 1)/sizeof(void *);
|
||||
gc_collect_root((void **)addressWithOffset, lengthInAddressSize);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void gc_collect(void) {
|
||||
KDColor MicroPython::ColorParser::ParseColor(mp_obj_t input, ColorMode ColorMode){
|
||||
static constexpr int maxColorIntensity = static_cast<int>(ColorMode::MaxIntensity255);
|
||||
if (mp_obj_is_str(input)) {
|
||||
size_t l;
|
||||
const char * color = mp_obj_str_get_data(input, &l);
|
||||
// TODO add cyan
|
||||
constexpr NameColorPair pairs[] = {
|
||||
NameColorPair("blue", KDColorBlue),
|
||||
NameColorPair("b", KDColorBlue),
|
||||
NameColorPair("red", KDColorRed),
|
||||
NameColorPair("r", KDColorRed),
|
||||
NameColorPair("green", Palette::Green),
|
||||
NameColorPair("g", Palette::Green),
|
||||
NameColorPair("yellow", KDColorYellow),
|
||||
NameColorPair("y", KDColorYellow),
|
||||
NameColorPair("brown", Palette::Brown),
|
||||
NameColorPair("black", KDColorBlack),
|
||||
NameColorPair("k", KDColorBlack),
|
||||
NameColorPair("white", KDColorWhite),
|
||||
NameColorPair("w", KDColorWhite),
|
||||
NameColorPair("pink", Palette::Pink),
|
||||
NameColorPair("orange", Palette::Orange),
|
||||
NameColorPair("purple", Palette::Purple),
|
||||
NameColorPair("grey", Palette::GreyDark)
|
||||
};
|
||||
for (NameColorPair p : pairs) {
|
||||
if (strcmp(p.name(), color) == 0) {
|
||||
return p.color();
|
||||
}
|
||||
}
|
||||
|
||||
if (color[0] == '#') {
|
||||
// TODO handle #abc as #aabbcc (see matplotlib spec)
|
||||
if (l != 7) {
|
||||
mp_raise_ValueError("RGB hex values are 6 bytes long");
|
||||
}
|
||||
uint32_t colorInt = mp_obj_get_int(mp_parse_num_integer(color+1, strlen(color+1), 16, NULL));
|
||||
return KDColor::RGB24(colorInt);
|
||||
}
|
||||
|
||||
mp_float_t greyLevel = mp_obj_float_get(mp_parse_num_decimal(color, strlen(color), false, false, NULL));
|
||||
if (greyLevel >= 0.0 && greyLevel <= 1.0) {
|
||||
uint8_t color = maxColorIntensity * (float) greyLevel;
|
||||
return KDColor::RGB888(color, color, color);
|
||||
}
|
||||
mp_raise_ValueError("Grey levels are between 0.0 and 1.0");
|
||||
} else if(mp_obj_is_int(input)) {
|
||||
mp_raise_TypeError("Int are not colors");
|
||||
//See https://github.com/numworks/epsilon/issues/1533#issuecomment-618443492
|
||||
} else {
|
||||
size_t len;
|
||||
mp_obj_t * elem;
|
||||
|
||||
mp_obj_get_array(input, &len, &elem);
|
||||
|
||||
if (len != 3) {
|
||||
mp_raise_TypeError("Color needs 3 components");
|
||||
}
|
||||
int intensityFactor = maxColorIntensity/static_cast<int>(ColorMode);
|
||||
return KDColor::RGB888(
|
||||
intensityFactor * mp_obj_get_float(elem[0]),
|
||||
intensityFactor * mp_obj_get_float(elem[1]),
|
||||
intensityFactor * mp_obj_get_float(elem[2])
|
||||
);
|
||||
}
|
||||
mp_raise_TypeError("Color couldn't be parsed");
|
||||
}
|
||||
|
||||
void gc_collect_regs_and_stack(void) {
|
||||
// get the registers and the sp
|
||||
jmp_buf regs;
|
||||
uintptr_t sp = Ion::collectRegisters(regs);
|
||||
|
||||
void * python_stack_top = MP_STATE_THREAD(stack_top);
|
||||
assert(python_stack_top != NULL);
|
||||
|
||||
gc_collect_start();
|
||||
|
||||
modturtle_gc_collect();
|
||||
modpyplot_gc_collect();
|
||||
|
||||
/* get the registers.
|
||||
* regs is the also the last object on the stack so the stack is bound by
|
||||
* ®s and python_stack_top. */
|
||||
jmp_buf regs;
|
||||
/* TODO: we use setjmp to get the registers values to look for python heap
|
||||
* root. However, the 'setjmp' does not guarantee that it gets all registers
|
||||
* values. We should check our setjmp implementation for the device and
|
||||
* ensure that it also works for other platforms. */
|
||||
setjmp(regs);
|
||||
|
||||
void **regs_ptr = (void**)®s;
|
||||
|
||||
/* On the device, the stack is stored in reverse order, but it might not be
|
||||
* the case on a computer. We thus have to take the absolute value of the
|
||||
* addresses difference. */
|
||||
size_t stackLengthInByte;
|
||||
void ** scanStart;
|
||||
if ((uintptr_t)python_stack_top > (uintptr_t)regs_ptr) {
|
||||
if ((uintptr_t)python_stack_top > sp) {
|
||||
|
||||
/* To compute the stack length:
|
||||
* regs
|
||||
* registers
|
||||
* <----------->
|
||||
* STACK <- ...| | | | | |--|--|--|--| | | | | | |
|
||||
* ^®s ^python_stack_top
|
||||
* ^sp ^python_stack_top
|
||||
* */
|
||||
|
||||
stackLengthInByte = (uintptr_t)python_stack_top - (uintptr_t)regs_ptr;
|
||||
scanStart = regs_ptr;
|
||||
stackLengthInByte = (uintptr_t)python_stack_top - sp;
|
||||
scanStart = (void **)sp;
|
||||
|
||||
} else {
|
||||
|
||||
/* When computing the stack length, take into account regs' size.
|
||||
* regs
|
||||
* registers
|
||||
* <----------->
|
||||
* STACK -> | | | | | | | | | | | |--|--|--|--| | | |...
|
||||
* ^python_stack_top ^®s
|
||||
* ^python_stack_top ^sp
|
||||
* */
|
||||
|
||||
stackLengthInByte = (uintptr_t)regs_ptr - (uintptr_t)python_stack_top + sizeof(regs);
|
||||
stackLengthInByte = sp - (uintptr_t)python_stack_top + sizeof(regs);
|
||||
scanStart = (void **)python_stack_top;
|
||||
|
||||
}
|
||||
/* Memory error detectors might find an error here as they might split regs
|
||||
* and stack memory zones. */
|
||||
MicroPython::collectRootsAtAddress((char *)scanStart, stackLengthInByte);
|
||||
}
|
||||
|
||||
void gc_collect(void) {
|
||||
gc_collect_start();
|
||||
modturtle_gc_collect();
|
||||
modpyplot_gc_collect();
|
||||
gc_collect_regs_and_stack();
|
||||
gc_collect_end();
|
||||
}
|
||||
|
||||
@@ -260,3 +315,4 @@ const char * mp_hal_input(const char * prompt) {
|
||||
assert(sCurrentExecutionEnvironment != nullptr);
|
||||
return sCurrentExecutionEnvironment->inputText(prompt);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
|
||||
extern "C" {
|
||||
#include <stddef.h>
|
||||
#include <py/obj.h>
|
||||
}
|
||||
#include <escher/view_controller.h>
|
||||
|
||||
|
||||
namespace MicroPython {
|
||||
|
||||
class ScriptProvider {
|
||||
@@ -39,6 +41,31 @@ void deinit();
|
||||
void registerScriptProvider(ScriptProvider * s);
|
||||
void collectRootsAtAddress(char * address, int len);
|
||||
|
||||
class ColorParser {
|
||||
private:
|
||||
class NameColorPair {
|
||||
public:
|
||||
constexpr NameColorPair(const char * name, KDColor color) :
|
||||
m_name(name),
|
||||
m_color(color)
|
||||
{}
|
||||
const char * name() const { return m_name; }
|
||||
KDColor color() const { return m_color; }
|
||||
private:
|
||||
const char * m_name;
|
||||
KDColor m_color;
|
||||
};
|
||||
|
||||
public:
|
||||
enum class ColorMode {
|
||||
MaxIntensity1 = 1,
|
||||
MaxIntensity255 = 255,
|
||||
};
|
||||
|
||||
static KDColor ParseColor(mp_obj_t input, ColorMode ColorMode = ColorMode::MaxIntensity255);
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user