Add timeouts

This commit is contained in:
2026-06-06 10:38:10 -05:00
parent 6f47543720
commit 9068d96130
6 changed files with 132 additions and 2 deletions
+2 -2
View File
@@ -13,9 +13,9 @@ Console.print('Platform: ' + (platformNames[System.platform] || 'Unknown'));
// Testing async/await // Testing async/await
async function testAsync() { async function testAsync() {
Console.print('Testing async/await...'); Console.print('Testing async/await...');
await new Promise(resolve => requestAnimationFrame(resolve)); await frame();
Console.print('First await done!'); Console.print('First await done!');
await new Promise(resolve => setTimeout(resolve, 1000)); await timeout(1000);
Console.print('Async/await works!'); Console.print('Async/await works!');
} }
@@ -0,0 +1,45 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "script/module/modulebase.h"
#define MODULE_FRAME_PENDING_MAX 64
static jerry_value_t MODULE_FRAME_PENDING[MODULE_FRAME_PENDING_MAX];
static uint32_t MODULE_FRAME_PENDING_COUNT = 0;
moduleBaseFunction(moduleFrameFrame) {
if(MODULE_FRAME_PENDING_COUNT >= MODULE_FRAME_PENDING_MAX) {
return moduleBaseThrow("Too many pending frame() calls");
}
jerry_value_t promise = jerry_promise();
MODULE_FRAME_PENDING[MODULE_FRAME_PENDING_COUNT++] = jerry_value_copy(promise);
return promise;
}
static void moduleFrameFlush(void) {
uint32_t count = MODULE_FRAME_PENDING_COUNT;
MODULE_FRAME_PENDING_COUNT = 0;
for(uint32_t i = 0; i < count; i++) {
jerry_value_t ret = jerry_promise_resolve(MODULE_FRAME_PENDING[i], jerry_undefined());
jerry_value_free(ret);
jerry_value_free(MODULE_FRAME_PENDING[i]);
}
}
static void moduleFrameInit(void) {
MODULE_FRAME_PENDING_COUNT = 0;
moduleBaseDefineGlobalMethod("frame", moduleFrameFrame);
}
static void moduleFrameDispose(void) {
for(uint32_t i = 0; i < MODULE_FRAME_PENDING_COUNT; i++) {
jerry_value_free(MODULE_FRAME_PENDING[i]);
}
MODULE_FRAME_PENDING_COUNT = 0;
}
@@ -0,0 +1,67 @@
/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "script/module/modulebase.h"
#include "time/time.h"
#define MODULE_TIMEOUT_PENDING_MAX 64
typedef struct {
jerry_value_t promise;
float_t targetTime;
} moduletimeoutentry_t;
static moduletimeoutentry_t MODULE_TIMEOUT_PENDING[MODULE_TIMEOUT_PENDING_MAX];
static uint32_t MODULE_TIMEOUT_PENDING_COUNT = 0;
moduleBaseFunction(moduleTimeoutTimeout) {
moduleBaseRequireArgs(1);
moduleBaseRequireNumber(0);
if(MODULE_TIMEOUT_PENDING_COUNT >= MODULE_TIMEOUT_PENDING_MAX) {
return moduleBaseThrow("Too many pending timeout() calls");
}
float_t ms = moduleBaseArgFloat(0);
jerry_value_t promise = jerry_promise();
MODULE_TIMEOUT_PENDING[MODULE_TIMEOUT_PENDING_COUNT].promise = jerry_value_copy(promise);
MODULE_TIMEOUT_PENDING[MODULE_TIMEOUT_PENDING_COUNT].targetTime = TIME.time + ms / 1000.0f;
MODULE_TIMEOUT_PENDING_COUNT++;
return promise;
}
static void moduleTimeoutFlush(void) {
uint32_t i = 0;
while(i < MODULE_TIMEOUT_PENDING_COUNT) {
if(TIME.time >= MODULE_TIMEOUT_PENDING[i].targetTime) {
jerry_value_t ret = jerry_promise_resolve(
MODULE_TIMEOUT_PENDING[i].promise, jerry_undefined()
);
jerry_value_free(ret);
jerry_value_free(MODULE_TIMEOUT_PENDING[i].promise);
MODULE_TIMEOUT_PENDING_COUNT--;
if(i < MODULE_TIMEOUT_PENDING_COUNT) {
MODULE_TIMEOUT_PENDING[i] = MODULE_TIMEOUT_PENDING[MODULE_TIMEOUT_PENDING_COUNT];
}
} else {
i++;
}
}
}
static void moduleTimeoutInit(void) {
MODULE_TIMEOUT_PENDING_COUNT = 0;
moduleBaseDefineGlobalMethod("timeout", moduleTimeoutTimeout);
}
static void moduleTimeoutDispose(void) {
for(uint32_t i = 0; i < MODULE_TIMEOUT_PENDING_COUNT; i++) {
jerry_value_free(MODULE_TIMEOUT_PENDING[i].promise);
}
MODULE_TIMEOUT_PENDING_COUNT = 0;
}
+11
View File
@@ -11,6 +11,8 @@
#include "script/module/display/modulecolor.h" #include "script/module/display/modulecolor.h"
#include "script/module/display/modulescreen.h" #include "script/module/display/modulescreen.h"
#include "script/module/engine/moduleengine.h" #include "script/module/engine/moduleengine.h"
#include "script/module/engine/moduleframe.h"
#include "script/module/engine/moduletimeout.h"
#include "script/module/entity/component/modulecomponentlist.h" #include "script/module/entity/component/modulecomponentlist.h"
#include "script/module/entity/modulecomponent.h" #include "script/module/entity/modulecomponent.h"
#include "script/module/entity/moduleentity.h" #include "script/module/entity/moduleentity.h"
@@ -28,6 +30,8 @@ void moduleListInit(void) {
moduleConsoleInit(); moduleConsoleInit();
moduleScreenInit(); moduleScreenInit();
moduleEngineInit(); moduleEngineInit();
moduleFrameInit();
moduleTimeoutInit();
moduleVec3Init(); moduleVec3Init();
moduleComponentInit(); moduleComponentInit();
moduleEntityInit(); moduleEntityInit();
@@ -38,6 +42,11 @@ void moduleListInit(void) {
moduleSystemInit(); moduleSystemInit();
} }
void moduleListUpdate(void) {
moduleFrameFlush();
moduleTimeoutFlush();
}
void moduleListDispose(void) { void moduleListDispose(void) {
moduleSystemDispose(); moduleSystemDispose();
moduleSceneDispose(); moduleSceneDispose();
@@ -47,6 +56,8 @@ void moduleListDispose(void) {
moduleEntityDispose(); moduleEntityDispose();
moduleComponentDispose(); moduleComponentDispose();
moduleVec3Dispose(); moduleVec3Dispose();
moduleTimeoutDispose();
moduleFrameDispose();
moduleEngineDispose(); moduleEngineDispose();
moduleScreenDispose(); moduleScreenDispose();
moduleConsoleDispose(); moduleConsoleDispose();
+6
View File
@@ -13,6 +13,12 @@
*/ */
void moduleListInit(void); void moduleListInit(void);
/**
* Flushes per-frame module state. Must be called once per frame before
* jerry_run_jobs() so that frame() promises resolve in the same tick.
*/
void moduleListUpdate(void);
/** /**
* Disposes all of the internal (C) script modules. * Disposes all of the internal (C) script modules.
*/ */
+1
View File
@@ -28,6 +28,7 @@ errorret_t scriptInit(void) {
} }
errorret_t scriptUpdate() { errorret_t scriptUpdate() {
moduleListUpdate();
jerry_value_t ret = jerry_run_jobs(); jerry_value_t ret = jerry_run_jobs();
if(jerry_value_is_exception(ret)) { if(jerry_value_is_exception(ret)) {