[python] Implement ExecutionEnvironment::input

By using a re-entrant RunLoop call
This commit is contained in:
Romain Goyet
2018-01-30 13:11:23 +01:00
committed by EmilieNumworks
parent 651d5715e4
commit 0682d21a32
6 changed files with 44 additions and 3 deletions

View File

@@ -136,6 +136,11 @@ void AppsContainer::run() {
switchTo(nullptr);
}
void AppsContainer::runWhile(bool (*callback)(void * ctx), void * ctx) {
while (callback(ctx) && RunLoop::step()) {
}
}
bool AppsContainer::updateBatteryState() {
if (m_window.updateBatteryLevel() ||
m_window.updateIsChargingState() ||

View File

@@ -39,6 +39,7 @@ public:
virtual bool dispatchEvent(Ion::Events::Event event) override;
void switchTo(App::Snapshot * snapshot) override;
void run() override;
void runWhile(bool (*callback)(void * ctx), void * ctx);
bool updateBatteryState();
void refreshPreferences();
void displayExamModePopUp(bool activate);

View File

@@ -6,6 +6,7 @@
#include <apps/i18n.h>
#include <assert.h>
#include <escher/metric.h>
#include "../apps_container.h"
extern "C" {
#include <stdlib.h>
@@ -80,7 +81,23 @@ void ConsoleController::runAndPrintForCommand(const char * command) {
}
const char * ConsoleController::input() {
return "1+1";
AppsContainer * a = (AppsContainer *)(app()->container());
m_inputRunLoopActive = true;
m_selectableTableView.reloadData();
m_selectableTableView.selectCellAtLocation(0, m_consoleStore.numberOfLines());
m_editCell.setText("???");
a->redrawWindow();
a->runWhile([](void * a){
ConsoleController * c = static_cast<ConsoleController *>(a);
return c->inputRunLoopActive();
}, this);
flushOutputAccumulationBufferToStore();
m_consoleStore.deleteLastLineIfEmpty();
return m_editCell.text();
}
void ConsoleController::removeExtensionIfAny(char * name) {
@@ -111,6 +128,12 @@ void ConsoleController::didBecomeFirstResponder() {
}
bool ConsoleController::handleEvent(Ion::Events::Event event) {
if (event == Ion::Events::Home && inputRunLoopActive()) {
askInputRunLoopTermination();
// We need to return true here because we want to actually exit from the
// input run loop, which requires ending a dispatchEvent cycle.
return true;
}
if (event == Ion::Events::Up) {
if (m_consoleStore.numberOfLines() > 0 && m_selectableTableView.selectedRow() == m_consoleStore.numberOfLines()) {
m_editCell.setEditing(false);
@@ -245,6 +268,10 @@ bool ConsoleController::textFieldDidReceiveEvent(TextField * textField, Ion::Eve
}
bool ConsoleController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) {
if (inputRunLoopActive()) {
askInputRunLoopTermination();
return false;
}
runAndPrintForCommand(text);
if (m_sandboxIsDisplayed) {
return true;
@@ -257,7 +284,11 @@ bool ConsoleController::textFieldDidFinishEditing(TextField * textField, const c
}
bool ConsoleController::textFieldDidAbortEditing(TextField * textField, const char * text) {
stackViewController()->pop();
if (inputRunLoopActive()) {
askInputRunLoopTermination();
} else {
stackViewController()->pop();
}
return true;
}

View File

@@ -65,6 +65,8 @@ public:
const char * input() override;
private:
bool inputRunLoopActive() { return m_inputRunLoopActive; }
void askInputRunLoopTermination() { m_inputRunLoopActive = false; }
static constexpr int LineCellType = 0;
static constexpr int EditCellType = 1;
static constexpr int k_numberOfLineCells = 15; // May change depending on the screen height
@@ -91,6 +93,7 @@ private:
* ConsoleLine in the ConsoleStore and empty m_outputAccumulationBuffer. */
ScriptStore * m_scriptStore;
SandboxController m_sandboxController;
bool m_inputRunLoopActive;
};
}

View File

@@ -28,6 +28,7 @@ public:
// Edit cell
void setEditing(bool isEditing, bool reinitDraftBuffer = false);
const char * text() const { return m_textField.text(); }
void setText(const char * text);
bool insertText(const char * text);

View File

@@ -12,8 +12,8 @@ protected:
virtual bool dispatchEvent(Ion::Events::Event e) = 0;
virtual int numberOfTimers();
virtual Timer * timerAtIndex(int i);
private:
bool step();
private:
int m_time;
};