Add claude docs
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
# Script -- Async Promises (`scriptpromisepend_t`)
|
||||
|
||||
Source: `src/dusk/script/scriptpromisepend.h`
|
||||
|
||||
See also: `.claude/script.md`
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
When a C module needs to resolve a JS `Promise` from an asynchronous
|
||||
C event (e.g. an asset finishing loading, a network response arriving),
|
||||
use `scriptpromisepend_t`. The pattern avoids heap allocation by using
|
||||
a fixed-size pending slot array declared in the module.
|
||||
|
||||
---
|
||||
|
||||
## Declaring the pending array
|
||||
|
||||
```c
|
||||
#define MY_MODULE_PENDING_MAX 8
|
||||
static scriptpromisepend_t MY_PENDING[MY_MODULE_PENDING_MAX];
|
||||
static uint32_t MY_PENDING_COUNT = 0;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Add a pending promise
|
||||
|
||||
Called from the JS-facing function that returns the Promise:
|
||||
|
||||
```c
|
||||
jerry_value_t promise = jerry_create_promise();
|
||||
scriptPromisePendAdd(
|
||||
MY_PENDING, &MY_PENDING_COUNT, MY_MODULE_PENDING_MAX,
|
||||
key, // opaque void * used to match the resolve/reject later
|
||||
promise
|
||||
);
|
||||
return jerry_acquire_value(promise); // return a copy to the caller
|
||||
```
|
||||
|
||||
The `key` should be a stable pointer that uniquely identifies the
|
||||
async operation -- e.g. an `assetentry_t *`, a network request handle,
|
||||
or a pointer to a fixed-size slot in the module.
|
||||
|
||||
---
|
||||
|
||||
## Resolve or reject
|
||||
|
||||
Called when the C event fires, typically from `moduleUpdate` or an
|
||||
event callback:
|
||||
|
||||
```c
|
||||
// On success:
|
||||
scriptPromisePendResolve(
|
||||
MY_PENDING, &MY_PENDING_COUNT,
|
||||
key, jerry_undefined() // or a result value
|
||||
);
|
||||
|
||||
// On failure:
|
||||
jerry_value_t err = jerry_create_error(
|
||||
JERRY_ERROR_COMMON, (const jerry_char_t *)"reason"
|
||||
);
|
||||
scriptPromisePendReject(MY_PENDING, &MY_PENDING_COUNT, key, err);
|
||||
jerry_release_value(err);
|
||||
```
|
||||
|
||||
Both macros remove the slot from the pending array after settling.
|
||||
|
||||
---
|
||||
|
||||
## Guard against double-submit
|
||||
|
||||
```c
|
||||
if(scriptPromisePendHas(MY_PENDING, MY_PENDING_COUNT, key)) {
|
||||
// already waiting -- return the existing promise or an error
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Module teardown
|
||||
|
||||
Free all pending promises before cleaning up events or other state:
|
||||
|
||||
```c
|
||||
scriptPromisePendFreeAll(MY_PENDING, &MY_PENDING_COUNT);
|
||||
```
|
||||
|
||||
This rejects all still-pending promises and resets the count to 0.
|
||||
Call it from the module's `Dispose` function, **before** any backing
|
||||
data (asset entries, event subscriptions) is torn down.
|
||||
|
||||
---
|
||||
|
||||
## Design notes
|
||||
|
||||
- `MY_MODULE_PENDING_MAX` sets a hard cap on concurrent async ops.
|
||||
Exceeding it is a runtime assertion -- size the array to the maximum
|
||||
realistic concurrency for the module.
|
||||
- The key is opaque (`void *`); the system does not dereference it.
|
||||
A raw integer cast to `void *` is fine if no pointer is available.
|
||||
- `scriptUpdate()` runs the JerryScript microjob queue each frame,
|
||||
which is what processes `.then()` chains after a resolve/reject.
|
||||
Reference in New Issue
Block a user