From 5dfefb477a18aaeb1c0ea3fafc5bc68238b3e4d6 Mon Sep 17 00:00:00 2001 From: Romain Goyet Date: Thu, 8 Nov 2018 13:29:49 +0100 Subject: [PATCH 1/5] [python] Rename micropython_port_should_interrupt to micropython_port_vm_hook_loop --- build/toolchain.emscripten.mak | 2 +- python/port/helpers.cpp | 14 +++++++++++--- python/port/helpers.h | 4 +--- python/port/mpconfigport.h | 2 +- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/build/toolchain.emscripten.mak b/build/toolchain.emscripten.mak index baabdca9b..7048b6d02 100644 --- a/build/toolchain.emscripten.mak +++ b/build/toolchain.emscripten.mak @@ -63,7 +63,7 @@ _do_load_from_lexer \ _fun_bc_call \ _fun_builtin_var_call \ _main \ -_micropython_port_should_interrupt \ +_micropython_port_vm_hook_loop \ _mp_builtin___import__ \ _mp_builtin_input \ _mp_call_function_0 \ diff --git a/python/port/helpers.cpp b/python/port/helpers.cpp index cda2b53ca..ac0114b02 100644 --- a/python/port/helpers.cpp +++ b/python/port/helpers.cpp @@ -4,15 +4,23 @@ extern "C" { #include "mphalport.h" } -void micropython_port_should_interrupt() { +void micropython_port_vm_hook_loop() { + /* This function is called very frequently by the MicroPython engine. We grab + * this opportunity to interrupt execution and/or refresh the display on + * platforms that need it. */ + + /* Doing too many things here slows down Python execution quite a lot. So we + * only do things once in a while and return as soon as possible otherwise. */ static int c = 0; c++; - if (c%20000 != 0) { + if (c % 20000 != 0) { return; } c = 0; + + /* Check if the user asked for an interruption from the keyboard */ Ion::Keyboard::State scan = Ion::Keyboard::scan(); - if (scan.keyDown((Ion::Keyboard::Key)mp_interrupt_char)) { + if (scan.keyDown(static_cast(mp_interrupt_char))) { mp_keyboard_interrupt(); } } diff --git a/python/port/helpers.h b/python/port/helpers.h index b07c6de29..375256909 100644 --- a/python/port/helpers.h +++ b/python/port/helpers.h @@ -5,9 +5,7 @@ extern "C" { #endif -/* should_interrupt effectively does something once every 20000 calls. It checks - * if a key is down to raise an interruption flag. */ -void micropython_port_should_interrupt(); +void micropython_port_vm_hook_loop(); #ifdef __cplusplus } diff --git a/python/port/mpconfigport.h b/python/port/mpconfigport.h index 17794886b..109a0682c 100644 --- a/python/port/mpconfigport.h +++ b/python/port/mpconfigport.h @@ -90,7 +90,7 @@ // (This scheme won't work if we want to mix Thumb and normal ARM code.) #define MICROPY_MAKE_POINTER_CALLABLE(p) (p) -#define MICROPY_VM_HOOK_LOOP micropython_port_should_interrupt(); +#define MICROPY_VM_HOOK_LOOP micropython_port_vm_hook_loop(); typedef intptr_t mp_int_t; // must be pointer size typedef uintptr_t mp_uint_t; // must be pointer size From f168ba46de20a881b740033df6ab742275b98071 Mon Sep 17 00:00:00 2001 From: Romain Goyet Date: Thu, 8 Nov 2018 13:30:53 +0100 Subject: [PATCH 2/5] [ion/emscripten] Update the display during long-running Python scripts --- ion/src/emscripten/events_keyboard.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ion/src/emscripten/events_keyboard.cpp b/ion/src/emscripten/events_keyboard.cpp index fa19c3191..ce1dcc0b6 100644 --- a/ion/src/emscripten/events_keyboard.cpp +++ b/ion/src/emscripten/events_keyboard.cpp @@ -83,6 +83,13 @@ Ion::Keyboard::State Ion::Keyboard::scan() { * function setTimeout, which can be called with a value of zero. Doing so * puts the callback at the end of the queue of callbacks to be processed. */ emscripten_sleep(0); + + /* Grab this opporunity to refresh the display. In practice, this routine is + * called from micropython_port_vm_hook_loop once in a while, so this gives us + * an opportunity to refresh the display during the execution of a + * long-running Python script. */ + Ion::Display::Emscripten::refresh(); + return sKeyboardState; } From f052bd9088cfb86f84ebd7bdfb29c6c22ebf04b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Fri, 9 Nov 2018 09:47:05 +0100 Subject: [PATCH 3/5] [python/port] Clean some code --- python/port/helpers.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/port/helpers.cpp b/python/port/helpers.cpp index ac0114b02..0bd294ed6 100644 --- a/python/port/helpers.cpp +++ b/python/port/helpers.cpp @@ -12,11 +12,11 @@ void micropython_port_vm_hook_loop() { /* Doing too many things here slows down Python execution quite a lot. So we * only do things once in a while and return as soon as possible otherwise. */ static int c = 0; - c++; - if (c % 20000 != 0) { + + c = (c + 1) % 20000; + if (c != 0) { return; } - c = 0; /* Check if the user asked for an interruption from the keyboard */ Ion::Keyboard::State scan = Ion::Keyboard::scan(); From 8d9ac798db4fa2721087e009bb908ca5acb9e971 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Tue, 13 Nov 2018 14:32:38 +0100 Subject: [PATCH 4/5] [poincare] Dividing 3E-2 in Natural edition should give (3E-2)/| --- poincare/include/poincare/char_layout.h | 4 ++++ poincare/include/poincare/layout.h | 1 + poincare/include/poincare/layout_node.h | 1 + poincare/src/char_layout.cpp | 30 ++++++++++++++++++++----- 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/poincare/include/poincare/char_layout.h b/poincare/include/poincare/char_layout.h index f06808ded..874f9a720 100644 --- a/poincare/include/poincare/char_layout.h +++ b/poincare/include/poincare/char_layout.h @@ -17,6 +17,7 @@ public: // CharLayout virtual void setChar(char c) { m_char = c; } + char character() const { return m_char; } const KDFont * font() const { return m_font; } void setFont(const KDFont * font) { m_font = font; } @@ -24,6 +25,7 @@ public: void moveCursorLeft(LayoutCursor * cursor, bool * shouldRecomputeLayout) override; void moveCursorRight(LayoutCursor * cursor, bool * shouldRecomputeLayout) override; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; + bool isChar() const override { return true; } bool isCollapsable(int * numberOfOpenParenthesis, bool goingLeft) const override; // TreeNode @@ -55,8 +57,10 @@ private: class CharLayout final : public Layout { public: + CharLayout(const CharLayoutNode * n) : Layout(n) {} CharLayout(char c, const KDFont * font = KDFont::LargeFont); const KDFont * font() const { return const_cast(this)->node()->font(); } + char character() const {return const_cast(this)->node()->character();} private: using Layout::node; CharLayoutNode * node() { return static_cast(Layout::node());} diff --git a/poincare/include/poincare/layout.h b/poincare/include/poincare/layout.h index c8f2c6554..acad70aba 100644 --- a/poincare/include/poincare/layout.h +++ b/poincare/include/poincare/layout.h @@ -45,6 +45,7 @@ public: bool isMatrix() const { return const_cast(this)->node()->isMatrix(); } bool isVerticalOffset() const { return const_cast(this)->node()->isVerticalOffset(); } bool isLeftParenthesis() const { return const_cast(this)->node()->isLeftParenthesis(); } + bool isChar() const { return const_cast(this)->node()->isChar(); } bool isCollapsable(int * numberOfOpenParenthesis, bool goingLeft) const { return const_cast(this)->node()->isCollapsable(numberOfOpenParenthesis, goingLeft); } int leftCollapsingAbsorbingChildIndex() const { return const_cast(this)->node()->leftCollapsingAbsorbingChildIndex(); } int rightCollapsingAbsorbingChildIndex() const { return const_cast(this)->node()->rightCollapsingAbsorbingChildIndex(); } diff --git a/poincare/include/poincare/layout_node.h b/poincare/include/poincare/layout_node.h index c474c1c59..f9aa51d50 100644 --- a/poincare/include/poincare/layout_node.h +++ b/poincare/include/poincare/layout_node.h @@ -103,6 +103,7 @@ public: virtual bool isRightBracket() const { return false; } virtual bool isEmpty() const { return false; } virtual bool isMatrix() const { return false; } + virtual bool isChar() const { return false; } virtual bool hasUpperLeftIndex() const { return false; } virtual char XNTChar() const { LayoutNode * p = parent(); diff --git a/poincare/src/char_layout.cpp b/poincare/src/char_layout.cpp index c4813bbae..6f3431924 100644 --- a/poincare/src/char_layout.cpp +++ b/poincare/src/char_layout.cpp @@ -32,17 +32,35 @@ int CharLayoutNode::serialize(char * buffer, int bufferSize, Preferences::PrintF } bool CharLayoutNode::isCollapsable(int * numberOfOpenParenthesis, bool goingLeft) const { - if (*numberOfOpenParenthesis <= 0 - && (m_char == '+' - || m_char == '-' + if (*numberOfOpenParenthesis <= 0) { + if (m_char == '+' || m_char == '*' || m_char == Ion::Charset::MultiplicationSign || m_char == Ion::Charset::MiddleDot || m_char == Ion::Charset::Sto || m_char == '=' - || m_char == ',')) - { - return false; + || m_char == ',') + { + return false; + } + if (m_char == '-') { + /* If the expression is like 3E-200, we want '-' to be collapsable. + * Otherwise, '-' is not collapsable. */ + Layout thisRef = CharLayout(this); + Layout parent = thisRef.parent(); + if (!parent.isUninitialized()) { + int indexOfThis = parent.indexOfChild(thisRef); + if (indexOfThis > 0) { + Layout leftBrother = parent.childAtIndex(indexOfThis-1); + if (leftBrother.isChar() + && static_cast(leftBrother).character() == Ion::Charset::Exponent) + { + return true; + } + } + } + return false; + } } return true; } From 0eae57da09efa786b8874026eb1e556d13282ba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Wed, 14 Nov 2018 09:56:13 +0100 Subject: [PATCH 5/5] [apps/stats] Fix pixel row not drawn when there are 3 histograms --- apps/statistics/multiple_data_view.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/statistics/multiple_data_view.cpp b/apps/statistics/multiple_data_view.cpp index 2f0203ca9..8e6def2fd 100644 --- a/apps/statistics/multiple_data_view.cpp +++ b/apps/statistics/multiple_data_view.cpp @@ -72,7 +72,7 @@ void MultipleDataView::layoutDataSubviews() { int numberDataSubviews = m_store->numberOfNonEmptySeries(); assert(numberDataSubviews > 0); KDCoordinate bannerHeight = bannerFrame().height(); - KDCoordinate subviewHeight = (bounds().height() - bannerHeight)/numberDataSubviews; + KDCoordinate subviewHeight = (bounds().height() - bannerHeight)/numberDataSubviews + 1; // +1 to make sure that all pixel rows are drawn int displayedSubviewIndex = 0; for (int i = 0; i < Store::k_numberOfSeries; i++) { if (!m_store->seriesIsEmpty(i)) {