feat(ble): expose isInitialized and reclaim memory before radios start

The controller and the WiFi driver each need a large aggregate allocation,
which a live app sitting on garbage can deny - that is why a failed connect
often succeeded on retry. Both bindings now collect before initializing, and
the tree reserves its node and spec capacity so a build does not reallocate
into a tight heap.
This commit is contained in:
2026-08-04 13:10:18 -04:00
parent 3416f54c83
commit bf286eefa6
7 changed files with 37 additions and 3 deletions
+11
View File
@@ -13,6 +13,9 @@ namespace {
int init(lua_State* state) {
std::string name;
const bool hasName = optionalString(state, 1, name);
// The controller needs a large aggregate allocation; reclaim app garbage
// first so a live screen's churn does not fail the init.
lua_gc(state, LUA_GCCOLLECT, 0);
return pushStatus(
state, Runtime::from(state)->ble().init(hasName ? &name : nullptr));
}
@@ -22,6 +25,11 @@ int deinit(lua_State* state) {
return 0;
}
int isInitialized(lua_State* state) {
lua_pushboolean(state, Runtime::from(state)->ble().isInitialized());
return 1;
}
int scan(lua_State* state) {
const int32_t durationMs = optionalInt(state, 1, 3000);
luaL_argcheck(state, durationMs > 0, 1, "must be positive");
@@ -97,6 +105,9 @@ const luaL_Reg FUNCTIONS[] = {
{"init", init},
// --- Stops the BLE stack and releases its memory.
{"deinit", deinit},
// --- Whether the BLE stack is running.
// @return boolean
{"isInitialized", isInitialized},
// --- Scans for advertising devices.
// @param durationMs integer|nil Defaults to 3000.
// @return BleDevice[]|nil devices
+3
View File
@@ -41,6 +41,9 @@ int connect(lua_State* state) {
std::string password;
const bool hasSsid = optionalString(state, 1, ssid);
const bool hasPassword = optionalString(state, 2, password);
// The driver needs ~28KB in aggregate and a live app can be sitting on that
// much garbage, which is why a failed connect often succeeds on retry.
lua_gc(state, LUA_GCCOLLECT, 0);
const Status status = Runtime::from(state)->wifi().connect(
hasSsid ? &ssid : nullptr, hasPassword ? &password : nullptr);
return pushStatus(state, status);