diff --git a/package/PikaStdTask/PikaStdTask.py b/package/PikaStdTask/PikaStdTask.py index 7a391e31c..7e11fabab 100644 --- a/package/PikaStdTask/PikaStdTask.py +++ b/package/PikaStdTask/PikaStdTask.py @@ -3,12 +3,7 @@ import PikaStdData class Task(TinyObj): - calls_always = PikaStdData.List() - calls_when = PikaStdData.List() - assert_when = PikaStdData.List() - calls_period = PikaStdData.List() - assert_period = PikaStdData.List() - time_period = PikaStdData.List() + calls = PikaStdData.List() def __init__(): pass @@ -28,5 +23,8 @@ class Task(TinyObj): def run_always(): pass + def run_until_ms(until_ms: int): + pass + def platformGetTick(): pass diff --git a/package/PikaStdTask/PikaStdTask_Task.c b/package/PikaStdTask/PikaStdTask_Task.c index 007054891..555cb9687 100644 --- a/package/PikaStdTask/PikaStdTask_Task.c +++ b/package/PikaStdTask/PikaStdTask_Task.c @@ -4,38 +4,26 @@ extern PikaObj* __pikaMain; void PikaStdTask_Task___init__(PikaObj* self) { - pikaVM_runAsm(self, - "B0\n" - "0 RUN calls_always.__init__\n" - "0 RUN calls_when.__init__\n" - "0 RUN assert_when.__init__\n" - "0 RUN calls_period.__init__\n" - "0 RUN assert_period.__init__\n" - "0 RUN time_period.__init__\n"); - obj_setPtr(__pikaMain, "__calls_always", obj_getPtr(self, "calls_always")); - obj_setPtr(__pikaMain, "__calls_when", obj_getPtr(self, "calls_when")); - obj_setPtr(__pikaMain, "__assert_when", obj_getPtr(self, "assert_when")); - obj_setPtr(__pikaMain, "__calls_period", obj_getPtr(self, "calls_period")); - obj_setPtr(__pikaMain, "__assert_period", - obj_getPtr(self, "assert_period")); - obj_setPtr(__pikaMain, "__time_period", obj_getPtr(self, "time_period")); + obj_run(self, + "calls.__init__()\n" + "is_period = 0\n"); + obj_setPtr(__pikaMain, "__calls", obj_getPtr(self, "calls")); } void PikaStdTask_Task_call_always(PikaObj* self, Arg* fun_todo) { obj_setArg(self, "fun_todo", fun_todo); - pikaVM_runAsm(self, "B0\n1 REF fun_todo\n0 RUN calls_always.append\n"); + obj_run(self, + "calls.append('always')\n" + "calls.append(fun_todo)\n"); } void PikaStdTask_Task_call_when(PikaObj* self, Arg* fun_todo, Arg* fun_when) { obj_setArg(self, "fun_todo", fun_todo); obj_setArg(self, "fun_when", fun_when); - pikaVM_runAsm(self, - "B0\n" - "1 REF fun_todo\n" - "0 RUN calls_when.append\n" - "B0\n" - "1 REF fun_when\n" - "0 RUN assert_when.append\n"); + obj_run(self, + "calls.append('when')\n" + "calls.append(fun_when)\n" + "calls.append(fun_todo)\n"); } void PikaStdTask_Task_call_period_ms(PikaObj* self, @@ -43,141 +31,54 @@ void PikaStdTask_Task_call_period_ms(PikaObj* self, int period_ms) { obj_setArg(self, "fun_todo", fun_todo); obj_setInt(self, "period_ms", period_ms); - pikaVM_runAsm(self, - "B0\n" - "1 REF fun_todo\n" - "0 RUN calls_period.append\n" - "B0\n" - "1 REF period_ms\n" - "0 RUN assert_period.append\n" - "B0\n" - "1 REF 0\n" - "0 RUN time_period.append\n"); + obj_run(self, + "calls.append('period_ms')\n" + "calls.append(period_ms)\n" + "calls.append(fun_todo)\n" + "calls.append(0)\n" + "is_period = 1\n"); } void PikaStdTask_Task_run_once(PikaObj* self) { - /* Python - if calls_period.len() > 0: - platformGetTick() - */ - pikaVM_runAsm(self, - "B0\n" - "1 RUN calls_period.len\n" - "1 NUM 0\n" - "0 OPT >\n" - "0 JEZ 1\n" - "B1\n" - "0 RUN platformGetTick\n" - "B0\n"); /* transfer the tick to pikaMain */ obj_setInt(__pikaMain, "__tick", obj_getInt(self, "tick")); - /* Python - len = __calls_always.len() - for i in range(0, len): - if len == 0: - break - todo = __calls_always[i] - todo() - */ - pikaVM_runAsm(__pikaMain, - "B0\n" - "0 RUN __calls_always.len\n" - "0 OUT len\n" - "B0\n" - "2 NUM 0\n" - "2 REF len\n" - "1 RUN range\n" - "0 RUN iter\n" - "0 OUT _l0\n" - "0 REF _r1\n" - "0 REF _r2\n" - "0 REF _r3\n" - "0 OUT _l0.a1\n" - "0 OUT _l0.a2\n" - "0 OUT _l0.a3\n" - "B0\n" - "0 RUN _l0.__next__\n" - "0 OUT i\n" - "0 EST i\n" - "0 JEZ 2\n" - "B1\n" - "1 REF len\n" - "1 NUM 0\n" - "0 OPT ==\n" - "0 JEZ 1\n" - "B2\n" - "0 BRK\n" - "B1\n" - "1 REF __calls_always\n" - "1 REF i\n" - "0 RUN __get__\n" - "0 OUT todo\n" - "B1\n" - "0 RUN todo\n" - "B0\n" - "0 JMP -1\n" - "B0\n" - "0 DEL _l0\n" - "B0\n"); - - /* Python - __len = __calls_when.len() - for i in range(0, __len): - if __len == 0: - break - when = __assert_when[i] - if when(): - todo = __calls_when[i] - todo() - */ - pikaVM_runAsm(__pikaMain, - "B0\n" - "0 RUN __calls_when.len\n" - "0 OUT __len\n" - "B0\n" - "2 NUM 0\n" - "2 REF __len\n" - "1 RUN range\n" - "0 RUN iter\n" - "0 OUT _l0\n" - "0 REF _r1\n" - "0 REF _r2\n" - "0 REF _r3\n" - "0 OUT _l0.a1\n" - "0 OUT _l0.a2\n" - "0 OUT _l0.a3\n" - "B0\n" - "0 RUN _l0.__next__\n" - "0 OUT i\n" - "0 EST i\n" - "0 JEZ 2\n" - "B1\n" - "1 REF __len\n" - "1 NUM 0\n" - "0 OPT ==\n" - "0 JEZ 1\n" - "B2\n" - "0 BRK\n" - "B1\n" - "1 REF __assert_when\n" - "1 REF i\n" - "0 RUN __get__\n" - "0 OUT when\n" - "B1\n" - "0 RUN when\n" - "0 JEZ 1\n" - "B2\n" - "1 REF __calls_when\n" - "1 REF i\n" - "0 RUN __get__\n" - "0 OUT todo\n" - "B2\n" - "0 RUN todo\n" - "B0\n" - "0 JMP -1\n" - "B0\n" - "0 DEL _l0\n" - "B0\n"); + obj_run(__pikaMain, + "len = __calls.len()\n" + "mode = 'none'\n" + "info_index = 0\n" + "for i in range(0, len):\n" + " if len == 0:\n" + " break\n" + " if info_index == 0:\n" + " mode = __calls[i]\n" + " info_index = 1\n" + " elif info_index == 1:\n" + " if mode == 'always':\n" + " todo = __calls[i]\n" + " todo()\n" + " info_index = 0\n" + " elif mode == 'when':\n" + " when = __calls[i]\n" + " info_index = 2\n" + " elif mode == 'period_ms':\n" + " period_ms = __calls[i]\n" + " info_index = 2\n" + " elif info_index == 2:\n" + " if mode == 'when':\n" + " if when():\n" + " todo = __calls[i]\n" + " todo()\n" + " info_index = 0\n" + " elif mode == 'period_ms':\n" + " todo = __calls[i]\n" + " info_index = 3\n" + " elif info_index == 3:\n" + " if mode == 'period_ms':\n" + " if __tick > __calls[i]:\n" + " todo()\n" + " __calls[i] = __tick + period_ms\n" + " info_index = 0\n" + "\n"); /* Python __len = __calls_period.len() for i in range(0, __len): @@ -189,76 +90,31 @@ void PikaStdTask_Task_run_once(PikaObj* self) { todo() __time_period[i] = __tick + __assert_period[i] */ - pikaVM_runAsm(__pikaMain, - "B0\n" - "0 RUN __calls_period.len\n" - "0 OUT __len\n" - "B0\n" - "2 NUM 0\n" - "2 REF __len\n" - "1 RUN range\n" - "0 RUN iter\n" - "0 OUT _l0\n" - "0 REF _r1\n" - "0 REF _r2\n" - "0 REF _r3\n" - "0 OUT _l0.a1\n" - "0 OUT _l0.a2\n" - "0 OUT _l0.a3\n" - "B0\n" - "0 RUN _l0.__next__\n" - "0 OUT i\n" - "0 EST i\n" - "0 JEZ 2\n" - "B1\n" - "1 REF __len\n" - "1 NUM 0\n" - "0 OPT ==\n" - "0 JEZ 1\n" - "B2\n" - "0 BRK\n" - "B1\n" - "1 REF __time_period\n" - "1 REF i\n" - "0 RUN __get__\n" - "0 OUT time\n" - "B1\n" - "1 REF __tick\n" - "2 REF __time_period\n" - "2 REF i\n" - "1 RUN __get__\n" - "0 OPT >\n" - "0 JEZ 1\n" - "B2\n" - "1 REF __calls_period\n" - "1 REF i\n" - "0 RUN __get__\n" - "0 OUT todo\n" - "B2\n" - "0 RUN todo\n" - "B2\n" - "1 REF __time_period\n" - "1 REF i\n" - "2 REF __tick\n" - "3 REF __assert_period\n" - "3 REF i\n" - "2 RUN __get__\n" - "1 OPT +\n" - "1 STR __time_period\n" - "0 RUN __set__\n" - "B0\n" - "0 JMP -1\n" - "B0\n" - "0 DEL _l0\n" - "B0 \n"); +} + +void __Task_update_tick(PikaObj* self) { + obj_run(self, + "if is_period:\n" + " platformGetTick()\n"); } void PikaStdTask_Task_run_always(PikaObj* self) { while (1) { + __Task_update_tick(self); PikaStdTask_Task_run_once(self); } } +void PikaStdTask_Task_run_until_ms(PikaObj* self, int until_ms) { + while (1) { + __Task_update_tick(self); + PikaStdTask_Task_run_once(self); + if (obj_getInt(self, "tick") > until_ms) { + return; + } + } +} + void PikaStdTask_Task_platformGetTick(PikaObj* self) { obj_setErrorCode(self, 1); obj_setSysOut(self, "[error] platform method need to be override."); diff --git a/port/linux/package/pikascript/PikaStdTask.py b/port/linux/package/pikascript/PikaStdTask.py index 18d0a26a6..7e11fabab 100644 --- a/port/linux/package/pikascript/PikaStdTask.py +++ b/port/linux/package/pikascript/PikaStdTask.py @@ -23,5 +23,8 @@ class Task(TinyObj): def run_always(): pass + def run_until_ms(until_ms: int): + pass + def platformGetTick(): pass diff --git a/port/linux/package/pikascript/main.py b/port/linux/package/pikascript/main.py index 8a2065c22..24bb3627c 100644 --- a/port/linux/package/pikascript/main.py +++ b/port/linux/package/pikascript/main.py @@ -21,10 +21,3 @@ def todo3(): def when3(): return True - -task = GTestTask.Task() -task.call_always(todo1) -task.call_always(todo2) -# task.call_when(todo3, when3) - -task.run_once() diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdTask/PikaStdTask_Task.c b/port/linux/package/pikascript/pikascript-lib/PikaStdTask/PikaStdTask_Task.c index cfa871d7b..555cb9687 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdTask/PikaStdTask_Task.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdTask/PikaStdTask_Task.c @@ -40,9 +40,6 @@ void PikaStdTask_Task_call_period_ms(PikaObj* self, } void PikaStdTask_Task_run_once(PikaObj* self) { - obj_run(self, - "if is_period:\n" - " platformGetTick()\n"); /* transfer the tick to pikaMain */ obj_setInt(__pikaMain, "__tick", obj_getInt(self, "tick")); obj_run(__pikaMain, @@ -95,12 +92,29 @@ void PikaStdTask_Task_run_once(PikaObj* self) { */ } +void __Task_update_tick(PikaObj* self) { + obj_run(self, + "if is_period:\n" + " platformGetTick()\n"); +} + void PikaStdTask_Task_run_always(PikaObj* self) { while (1) { + __Task_update_tick(self); PikaStdTask_Task_run_once(self); } } +void PikaStdTask_Task_run_until_ms(PikaObj* self, int until_ms) { + while (1) { + __Task_update_tick(self); + PikaStdTask_Task_run_once(self); + if (obj_getInt(self, "tick") > until_ms) { + return; + } + } +} + void PikaStdTask_Task_platformGetTick(PikaObj* self) { obj_setErrorCode(self, 1); obj_setSysOut(self, "[error] platform method need to be override."); diff --git a/port/linux/test/pikaMain-test.cpp b/port/linux/test/pikaMain-test.cpp index 0d187c875..72b30adf0 100644 --- a/port/linux/test/pikaMain-test.cpp +++ b/port/linux/test/pikaMain-test.cpp @@ -4,8 +4,8 @@ extern "C" { #include "PikaStdLib_MemChecker.h" #include "dataArgs.h" #include "dataMemory.h" -#include "pika_config_gtest.h" #include "pikaScript.h" +#include "pika_config_gtest.h" } extern PikaMemInfo pikaMemInfo; @@ -928,3 +928,38 @@ TEST(pikaMain, task_run_when) { obj_deinit(pikaMain); EXPECT_EQ(pikaMemNow(), 0); } + +TEST(pikaMain, task_run_period_until) { + /* init */ + pikaMemInfo.heapUsedMax = 0; + /* run */ + PikaObj* pikaMain = newRootObj((char*)"pikaMain", New_PikaMain); + __platform_printf((char*)"BEGIN\r\n"); + obj_run(pikaMain,(char*) + "def todo1():\n" + " print('task 1 running...')\n" + "def todo2():\n" + " print('task 2 running...')\n" + "def todo3():\n" + " print('task 3 running...')\n" + "def when3():\n" + " return True\n" + "task = GTestTask.Task()\n" + "task.call_period_ms(todo1, 200)\n" + "task.call_period_ms(todo2, 500)\n" + "# task.call_when(todo3, when3)\n" + "task.run_until_ms(1000)\n" + "\n"); + /* collect */ + /* assert */ + EXPECT_STREQ(log_buff[0], (char*)"task 1 running...\r\n"); + EXPECT_STREQ(log_buff[1], (char*)"task 2 running...\r\n"); + EXPECT_STREQ(log_buff[2], (char*)"task 1 running...\r\n"); + EXPECT_STREQ(log_buff[3], (char*)"task 1 running...\r\n"); + EXPECT_STREQ(log_buff[4], (char*)"task 2 running...\r\n"); + EXPECT_STREQ(log_buff[5], (char*)"task 1 running...\r\n"); + EXPECT_STREQ(log_buff[6], (char*)"BEGIN\r\n"); + /* deinit */ + obj_deinit(pikaMain); + EXPECT_EQ(pikaMemNow(), 0); +} \ No newline at end of file