mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-26 05:54:46 -07:00
Merge remote-tracking branch 'OFW/dev' into dev
This commit is contained in:
@@ -144,10 +144,16 @@ static void js_event_loop_subscribe(struct mjs* mjs) {
|
||||
JsEventLoop* module = JS_GET_CONTEXT(mjs);
|
||||
|
||||
// get arguments
|
||||
static const JsValueDeclaration js_loop_subscribe_arg_list[] = {
|
||||
JS_VALUE_SIMPLE(JsValueTypeRawPointer),
|
||||
JS_VALUE_SIMPLE(JsValueTypeFunction),
|
||||
};
|
||||
static const JsValueArguments js_loop_subscribe_args =
|
||||
JS_VALUE_ARGS(js_loop_subscribe_arg_list);
|
||||
|
||||
JsEventLoopContract* contract;
|
||||
mjs_val_t callback;
|
||||
JS_FETCH_ARGS_OR_RETURN(
|
||||
mjs, JS_AT_LEAST, JS_ARG_STRUCT(JsEventLoopContract, &contract), JS_ARG_FN(&callback));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_loop_subscribe_args, &contract, &callback);
|
||||
|
||||
// create subscription object
|
||||
JsEventLoopSubscription* subscription = malloc(sizeof(JsEventLoopSubscription));
|
||||
@@ -242,20 +248,22 @@ static void js_event_loop_stop(struct mjs* mjs) {
|
||||
* event
|
||||
*/
|
||||
static void js_event_loop_timer(struct mjs* mjs) {
|
||||
// get arguments
|
||||
const char* mode_str;
|
||||
int32_t interval;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_STR(&mode_str), JS_ARG_INT32(&interval));
|
||||
JsEventLoop* module = JS_GET_CONTEXT(mjs);
|
||||
static const JsValueEnumVariant js_loop_timer_mode_variants[] = {
|
||||
{"periodic", FuriEventLoopTimerTypePeriodic},
|
||||
{"oneshot", FuriEventLoopTimerTypeOnce},
|
||||
};
|
||||
|
||||
static const JsValueDeclaration js_loop_timer_arg_list[] = {
|
||||
JS_VALUE_ENUM(FuriEventLoopTimerType, js_loop_timer_mode_variants),
|
||||
JS_VALUE_SIMPLE(JsValueTypeInt32),
|
||||
};
|
||||
static const JsValueArguments js_loop_timer_args = JS_VALUE_ARGS(js_loop_timer_arg_list);
|
||||
|
||||
FuriEventLoopTimerType mode;
|
||||
if(strcasecmp(mode_str, "periodic") == 0) {
|
||||
mode = FuriEventLoopTimerTypePeriodic;
|
||||
} else if(strcasecmp(mode_str, "oneshot") == 0) {
|
||||
mode = FuriEventLoopTimerTypeOnce;
|
||||
} else {
|
||||
JS_ERROR_AND_RETURN(mjs, MJS_BAD_ARGS_ERROR, "argument 0: unknown mode");
|
||||
}
|
||||
int32_t interval;
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_loop_timer_args, &mode, &interval);
|
||||
|
||||
JsEventLoop* module = JS_GET_CONTEXT(mjs);
|
||||
|
||||
// make timer contract
|
||||
JsEventLoopContract* contract = malloc(sizeof(JsEventLoopContract));
|
||||
@@ -293,8 +301,14 @@ static mjs_val_t
|
||||
*/
|
||||
static void js_event_loop_queue_send(struct mjs* mjs) {
|
||||
// get arguments
|
||||
static const JsValueDeclaration js_loop_q_send_arg_list[] = {
|
||||
JS_VALUE_SIMPLE(JsValueTypeAny),
|
||||
};
|
||||
static const JsValueArguments js_loop_q_send_args = JS_VALUE_ARGS(js_loop_q_send_arg_list);
|
||||
|
||||
mjs_val_t message;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_ANY(&message));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_loop_q_send_args, &message);
|
||||
|
||||
JsEventLoopContract* contract = JS_GET_CONTEXT(mjs);
|
||||
|
||||
// send message
|
||||
@@ -311,8 +325,14 @@ static void js_event_loop_queue_send(struct mjs* mjs) {
|
||||
*/
|
||||
static void js_event_loop_queue(struct mjs* mjs) {
|
||||
// get arguments
|
||||
static const JsValueDeclaration js_loop_q_arg_list[] = {
|
||||
JS_VALUE_SIMPLE(JsValueTypeInt32),
|
||||
};
|
||||
static const JsValueArguments js_loop_q_args = JS_VALUE_ARGS(js_loop_q_arg_list);
|
||||
|
||||
int32_t length;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_INT32(&length));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_loop_q_args, &length);
|
||||
|
||||
JsEventLoop* module = JS_GET_CONTEXT(mjs);
|
||||
|
||||
// make queue contract
|
||||
|
||||
@@ -54,83 +54,114 @@ static void js_gpio_int_cb(void* arg) {
|
||||
* ```
|
||||
*/
|
||||
static void js_gpio_init(struct mjs* mjs) {
|
||||
// deconstruct mode object
|
||||
mjs_val_t mode_arg;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_OBJ(&mode_arg));
|
||||
mjs_val_t direction_arg = mjs_get(mjs, mode_arg, "direction", ~0);
|
||||
mjs_val_t out_mode_arg = mjs_get(mjs, mode_arg, "outMode", ~0);
|
||||
mjs_val_t in_mode_arg = mjs_get(mjs, mode_arg, "inMode", ~0);
|
||||
mjs_val_t edge_arg = mjs_get(mjs, mode_arg, "edge", ~0);
|
||||
mjs_val_t pull_arg = mjs_get(mjs, mode_arg, "pull", ~0);
|
||||
// direction variants
|
||||
typedef enum {
|
||||
JsGpioDirectionIn,
|
||||
JsGpioDirectionOut,
|
||||
} JsGpioDirection;
|
||||
static const JsValueEnumVariant js_gpio_direction_variants[] = {
|
||||
{"in", JsGpioDirectionIn},
|
||||
{"out", JsGpioDirectionOut},
|
||||
};
|
||||
static const JsValueDeclaration js_gpio_direction =
|
||||
JS_VALUE_ENUM(JsGpioDirection, js_gpio_direction_variants);
|
||||
|
||||
// get strings
|
||||
const char* direction = mjs_get_string(mjs, &direction_arg, NULL);
|
||||
const char* out_mode = mjs_get_string(mjs, &out_mode_arg, NULL);
|
||||
const char* in_mode = mjs_get_string(mjs, &in_mode_arg, NULL);
|
||||
const char* edge = mjs_get_string(mjs, &edge_arg, NULL);
|
||||
const char* pull = mjs_get_string(mjs, &pull_arg, NULL);
|
||||
if(!direction)
|
||||
JS_ERROR_AND_RETURN(
|
||||
mjs, MJS_BAD_ARGS_ERROR, "Expected string in \"direction\" field of mode object");
|
||||
if(!out_mode) out_mode = "open_drain";
|
||||
if(!in_mode) in_mode = "plain_digital";
|
||||
if(!edge) edge = "rising";
|
||||
// inMode variants
|
||||
typedef enum {
|
||||
JsGpioInModeAnalog = (0 << 0),
|
||||
JsGpioInModePlainDigital = (1 << 0),
|
||||
JsGpioInModeInterrupt = (2 << 0),
|
||||
JsGpioInModeEvent = (3 << 0),
|
||||
} JsGpioInMode;
|
||||
static const JsValueEnumVariant js_gpio_in_mode_variants[] = {
|
||||
{"analog", JsGpioInModeAnalog},
|
||||
{"plain_digital", JsGpioInModePlainDigital},
|
||||
{"interrupt", JsGpioInModeInterrupt},
|
||||
{"event", JsGpioInModeEvent},
|
||||
};
|
||||
static const JsValueDeclaration js_gpio_in_mode =
|
||||
JS_VALUE_ENUM_W_DEFAULT(JsGpioInMode, js_gpio_in_mode_variants, JsGpioInModePlainDigital);
|
||||
|
||||
// outMode variants
|
||||
typedef enum {
|
||||
JsGpioOutModePushPull,
|
||||
JsGpioOutModeOpenDrain,
|
||||
} JsGpioOutMode;
|
||||
static const JsValueEnumVariant js_gpio_out_mode_variants[] = {
|
||||
{"push_pull", JsGpioOutModePushPull},
|
||||
{"open_drain", JsGpioOutModeOpenDrain},
|
||||
};
|
||||
static const JsValueDeclaration js_gpio_out_mode =
|
||||
JS_VALUE_ENUM_W_DEFAULT(JsGpioOutMode, js_gpio_out_mode_variants, JsGpioOutModeOpenDrain);
|
||||
|
||||
// edge variants
|
||||
typedef enum {
|
||||
JsGpioEdgeRising = (0 << 2),
|
||||
JsGpioEdgeFalling = (1 << 2),
|
||||
JsGpioEdgeBoth = (2 << 2),
|
||||
} JsGpioEdge;
|
||||
static const JsValueEnumVariant js_gpio_edge_variants[] = {
|
||||
{"rising", JsGpioEdgeRising},
|
||||
{"falling", JsGpioEdgeFalling},
|
||||
{"both", JsGpioEdgeBoth},
|
||||
};
|
||||
static const JsValueDeclaration js_gpio_edge =
|
||||
JS_VALUE_ENUM_W_DEFAULT(JsGpioEdge, js_gpio_edge_variants, JsGpioEdgeRising);
|
||||
|
||||
// pull variants
|
||||
static const JsValueEnumVariant js_gpio_pull_variants[] = {
|
||||
{"up", GpioPullUp},
|
||||
{"down", GpioPullDown},
|
||||
};
|
||||
static const JsValueDeclaration js_gpio_pull =
|
||||
JS_VALUE_ENUM_W_DEFAULT(GpioPull, js_gpio_pull_variants, GpioPullNo);
|
||||
|
||||
// complete mode object
|
||||
static const JsValueObjectField js_gpio_mode_object_fields[] = {
|
||||
{"direction", &js_gpio_direction},
|
||||
{"inMode", &js_gpio_in_mode},
|
||||
{"outMode", &js_gpio_out_mode},
|
||||
{"edge", &js_gpio_edge},
|
||||
{"pull", &js_gpio_pull},
|
||||
};
|
||||
|
||||
// function args
|
||||
static const JsValueDeclaration js_gpio_init_arg_list[] = {
|
||||
JS_VALUE_OBJECT_W_DEFAULTS(js_gpio_mode_object_fields),
|
||||
};
|
||||
static const JsValueArguments js_gpio_init_args = JS_VALUE_ARGS(js_gpio_init_arg_list);
|
||||
|
||||
JsGpioDirection direction;
|
||||
JsGpioInMode in_mode;
|
||||
JsGpioOutMode out_mode;
|
||||
JsGpioEdge edge;
|
||||
GpioPull pull;
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(
|
||||
mjs, &js_gpio_init_args, &direction, &in_mode, &out_mode, &edge, &pull);
|
||||
|
||||
// convert strings to mode
|
||||
GpioMode mode;
|
||||
if(strcmp(direction, "out") == 0) {
|
||||
if(strcmp(out_mode, "push_pull") == 0)
|
||||
mode = GpioModeOutputPushPull;
|
||||
else if(strcmp(out_mode, "open_drain") == 0)
|
||||
mode = GpioModeOutputOpenDrain;
|
||||
else
|
||||
JS_ERROR_AND_RETURN(mjs, MJS_BAD_ARGS_ERROR, "invalid outMode");
|
||||
} else if(strcmp(direction, "in") == 0) {
|
||||
if(strcmp(in_mode, "analog") == 0) {
|
||||
mode = GpioModeAnalog;
|
||||
} else if(strcmp(in_mode, "plain_digital") == 0) {
|
||||
mode = GpioModeInput;
|
||||
} else if(strcmp(in_mode, "interrupt") == 0) {
|
||||
if(strcmp(edge, "rising") == 0)
|
||||
mode = GpioModeInterruptRise;
|
||||
else if(strcmp(edge, "falling") == 0)
|
||||
mode = GpioModeInterruptFall;
|
||||
else if(strcmp(edge, "both") == 0)
|
||||
mode = GpioModeInterruptRiseFall;
|
||||
else
|
||||
JS_ERROR_AND_RETURN(mjs, MJS_BAD_ARGS_ERROR, "invalid edge");
|
||||
} else if(strcmp(in_mode, "event") == 0) {
|
||||
if(strcmp(edge, "rising") == 0)
|
||||
mode = GpioModeEventRise;
|
||||
else if(strcmp(edge, "falling") == 0)
|
||||
mode = GpioModeEventFall;
|
||||
else if(strcmp(edge, "both") == 0)
|
||||
mode = GpioModeEventRiseFall;
|
||||
else
|
||||
JS_ERROR_AND_RETURN(mjs, MJS_BAD_ARGS_ERROR, "invalid edge");
|
||||
} else {
|
||||
JS_ERROR_AND_RETURN(mjs, MJS_BAD_ARGS_ERROR, "invalid inMode");
|
||||
}
|
||||
if(direction == JsGpioDirectionOut) {
|
||||
static const GpioMode js_gpio_out_mode_lut[] = {
|
||||
[JsGpioOutModePushPull] = GpioModeOutputPushPull,
|
||||
[JsGpioOutModeOpenDrain] = GpioModeOutputOpenDrain,
|
||||
};
|
||||
mode = js_gpio_out_mode_lut[out_mode];
|
||||
} else {
|
||||
JS_ERROR_AND_RETURN(mjs, MJS_BAD_ARGS_ERROR, "invalid direction");
|
||||
static const GpioMode js_gpio_in_mode_lut[] = {
|
||||
[JsGpioInModeAnalog] = GpioModeAnalog,
|
||||
[JsGpioInModePlainDigital] = GpioModeInput,
|
||||
[JsGpioInModeInterrupt | JsGpioEdgeRising] = GpioModeInterruptRise,
|
||||
[JsGpioInModeInterrupt | JsGpioEdgeFalling] = GpioModeInterruptFall,
|
||||
[JsGpioInModeInterrupt | JsGpioEdgeBoth] = GpioModeInterruptRiseFall,
|
||||
[JsGpioInModeEvent | JsGpioEdgeRising] = GpioModeEventRise,
|
||||
[JsGpioInModeEvent | JsGpioEdgeFalling] = GpioModeEventFall,
|
||||
[JsGpioInModeEvent | JsGpioEdgeBoth] = GpioModeEventRiseFall,
|
||||
};
|
||||
mode = js_gpio_in_mode_lut[in_mode | edge];
|
||||
}
|
||||
|
||||
// convert pull
|
||||
GpioPull pull_mode;
|
||||
if(!pull) {
|
||||
pull_mode = GpioPullNo;
|
||||
} else if(strcmp(pull, "up") == 0) {
|
||||
pull_mode = GpioPullUp;
|
||||
} else if(strcmp(pull, "down") == 0) {
|
||||
pull_mode = GpioPullDown;
|
||||
} else {
|
||||
JS_ERROR_AND_RETURN(mjs, MJS_BAD_ARGS_ERROR, "invalid pull");
|
||||
}
|
||||
|
||||
// init GPIO
|
||||
JsGpioPinInst* manager_data = JS_GET_CONTEXT(mjs);
|
||||
furi_hal_gpio_init(manager_data->pin, mode, pull_mode, GpioSpeedVeryHigh);
|
||||
mjs_return(mjs, MJS_UNDEFINED);
|
||||
furi_hal_gpio_init(manager_data->pin, mode, pull, GpioSpeedVeryHigh);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -146,8 +177,13 @@ static void js_gpio_init(struct mjs* mjs) {
|
||||
* ```
|
||||
*/
|
||||
static void js_gpio_write(struct mjs* mjs) {
|
||||
static const JsValueDeclaration js_gpio_write_arg_list[] = {
|
||||
JS_VALUE_SIMPLE(JsValueTypeBool),
|
||||
};
|
||||
static const JsValueArguments js_gpio_write_args = JS_VALUE_ARGS(js_gpio_write_arg_list);
|
||||
bool level;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_BOOL(&level));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_gpio_write_args, &level);
|
||||
|
||||
JsGpioPinInst* manager_data = JS_GET_CONTEXT(mjs);
|
||||
furi_hal_gpio_write(manager_data->pin, level);
|
||||
mjs_return(mjs, MJS_UNDEFINED);
|
||||
@@ -261,9 +297,16 @@ static void js_gpio_is_pwm_supported(struct mjs* mjs) {
|
||||
* ```
|
||||
*/
|
||||
static void js_gpio_pwm_write(struct mjs* mjs) {
|
||||
JsGpioPinInst* manager_data = JS_GET_CONTEXT(mjs);
|
||||
static const JsValueDeclaration js_gpio_pwm_write_arg_list[] = {
|
||||
JS_VALUE_SIMPLE(JsValueTypeInt32),
|
||||
JS_VALUE_SIMPLE(JsValueTypeInt32),
|
||||
};
|
||||
static const JsValueArguments js_gpio_pwm_write_args =
|
||||
JS_VALUE_ARGS(js_gpio_pwm_write_arg_list);
|
||||
int32_t frequency, duty;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_INT32(&frequency), JS_ARG_INT32(&duty));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_gpio_pwm_write_args, &frequency, &duty);
|
||||
|
||||
JsGpioPinInst* manager_data = JS_GET_CONTEXT(mjs);
|
||||
if(manager_data->pwm_output == FuriHalPwmOutputIdNone) {
|
||||
JS_ERROR_AND_RETURN(mjs, MJS_BAD_ARGS_ERROR, "PWM is not supported on this pin");
|
||||
}
|
||||
@@ -326,8 +369,13 @@ static void js_gpio_pwm_stop(struct mjs* mjs) {
|
||||
* ```
|
||||
*/
|
||||
static void js_gpio_get(struct mjs* mjs) {
|
||||
static const JsValueDeclaration js_gpio_get_arg_list[] = {
|
||||
JS_VALUE_SIMPLE(JsValueTypeAny),
|
||||
};
|
||||
static const JsValueArguments js_gpio_get_args = JS_VALUE_ARGS(js_gpio_get_arg_list);
|
||||
mjs_val_t name_arg;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_ANY(&name_arg));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_gpio_get_args, &name_arg);
|
||||
|
||||
const char* name_string = mjs_get_string(mjs, &name_arg, NULL);
|
||||
const GpioPinRecord* pin_record = NULL;
|
||||
|
||||
|
||||
@@ -3,8 +3,14 @@
|
||||
#include <assets_icons.h>
|
||||
|
||||
static void js_gui_file_picker_pick_file(struct mjs* mjs) {
|
||||
static const JsValueDeclaration js_picker_arg_list[] = {
|
||||
JS_VALUE_SIMPLE(JsValueTypeString),
|
||||
JS_VALUE_SIMPLE(JsValueTypeString),
|
||||
};
|
||||
static const JsValueArguments js_picker_args = JS_VALUE_ARGS(js_picker_arg_list);
|
||||
|
||||
const char *base_path, *extension;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_STR(&base_path), JS_ARG_STR(&extension));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_picker_args, &base_path, &extension);
|
||||
|
||||
DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS);
|
||||
const DialogsFileBrowserOptions browser_options = {
|
||||
|
||||
@@ -39,9 +39,14 @@ typedef struct {
|
||||
FxbmIconWrapperList_t fxbm_list;
|
||||
} JsGuiIconInst;
|
||||
|
||||
static const JsValueDeclaration js_icon_get_arg_list[] = {
|
||||
JS_VALUE_SIMPLE(JsValueTypeString),
|
||||
};
|
||||
static const JsValueArguments js_icon_get_args = JS_VALUE_ARGS(js_icon_get_arg_list);
|
||||
|
||||
static void js_gui_icon_get_builtin(struct mjs* mjs) {
|
||||
const char* icon_name;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_STR(&icon_name));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_icon_get_args, &icon_name);
|
||||
|
||||
for(size_t i = 0; i < COUNT_OF(builtin_icons); i++) {
|
||||
if(strcmp(icon_name, builtin_icons[i].name) == 0) {
|
||||
@@ -55,7 +60,7 @@ static void js_gui_icon_get_builtin(struct mjs* mjs) {
|
||||
|
||||
static void js_gui_icon_load_fxbm(struct mjs* mjs) {
|
||||
const char* fxbm_path;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_STR(&fxbm_path));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_icon_get_args, &fxbm_path);
|
||||
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
File* file = storage_file_alloc(storage);
|
||||
|
||||
@@ -68,8 +68,14 @@ static bool js_gui_vd_nav_callback(void* context) {
|
||||
* @brief `viewDispatcher.sendCustom`
|
||||
*/
|
||||
static void js_gui_vd_send_custom(struct mjs* mjs) {
|
||||
static const JsValueDeclaration js_gui_vd_send_custom_arg_list[] = {
|
||||
JS_VALUE_SIMPLE(JsValueTypeInt32),
|
||||
};
|
||||
static const JsValueArguments js_gui_vd_send_custom_args =
|
||||
JS_VALUE_ARGS(js_gui_vd_send_custom_arg_list);
|
||||
|
||||
int32_t event;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_INT32(&event));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_gui_vd_send_custom_args, &event);
|
||||
|
||||
JsGui* module = JS_GET_CONTEXT(mjs);
|
||||
view_dispatcher_send_custom_event(module->dispatcher, (uint32_t)event);
|
||||
@@ -79,15 +85,25 @@ static void js_gui_vd_send_custom(struct mjs* mjs) {
|
||||
* @brief `viewDispatcher.sendTo`
|
||||
*/
|
||||
static void js_gui_vd_send_to(struct mjs* mjs) {
|
||||
enum {
|
||||
SendDirToFront,
|
||||
SendDirToBack,
|
||||
} send_direction;
|
||||
JS_ENUM_MAP(send_direction, {"front", SendDirToFront}, {"back", SendDirToBack});
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_ENUM(send_direction, "SendDirection"));
|
||||
typedef enum {
|
||||
JsSendDirToFront,
|
||||
JsSendDirToBack,
|
||||
} JsSendDir;
|
||||
static const JsValueEnumVariant js_send_dir_variants[] = {
|
||||
{"front", JsSendDirToFront},
|
||||
{"back", JsSendDirToBack},
|
||||
};
|
||||
static const JsValueDeclaration js_gui_vd_send_to_arg_list[] = {
|
||||
JS_VALUE_ENUM(JsSendDir, js_send_dir_variants),
|
||||
};
|
||||
static const JsValueArguments js_gui_vd_send_to_args =
|
||||
JS_VALUE_ARGS(js_gui_vd_send_to_arg_list);
|
||||
|
||||
JsSendDir send_direction;
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_gui_vd_send_to_args, &send_direction);
|
||||
|
||||
JsGui* module = JS_GET_CONTEXT(mjs);
|
||||
if(send_direction == SendDirToBack) {
|
||||
if(send_direction == JsSendDirToBack) {
|
||||
view_dispatcher_send_to_back(module->dispatcher);
|
||||
} else {
|
||||
view_dispatcher_send_to_front(module->dispatcher);
|
||||
@@ -98,8 +114,15 @@ static void js_gui_vd_send_to(struct mjs* mjs) {
|
||||
* @brief `viewDispatcher.switchTo`
|
||||
*/
|
||||
static void js_gui_vd_switch_to(struct mjs* mjs) {
|
||||
static const JsValueDeclaration js_gui_vd_switch_to_arg_list[] = {
|
||||
JS_VALUE_SIMPLE(JsValueTypeAny),
|
||||
};
|
||||
static const JsValueArguments js_gui_vd_switch_to_args =
|
||||
JS_VALUE_ARGS(js_gui_vd_switch_to_arg_list);
|
||||
|
||||
mjs_val_t view;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_OBJ(&view));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_gui_vd_switch_to_args, &view);
|
||||
|
||||
JsGuiViewData* view_data = JS_GET_INST(mjs, view);
|
||||
mjs_val_t vd_obj = mjs_get_this(mjs);
|
||||
JsGui* module = JS_GET_INST(mjs, vd_obj);
|
||||
@@ -267,9 +290,16 @@ static bool
|
||||
* @brief `View.set`
|
||||
*/
|
||||
static void js_gui_view_set(struct mjs* mjs) {
|
||||
static const JsValueDeclaration js_gui_view_set_arg_list[] = {
|
||||
JS_VALUE_SIMPLE(JsValueTypeString),
|
||||
JS_VALUE_SIMPLE(JsValueTypeAny),
|
||||
};
|
||||
static const JsValueArguments js_gui_view_set_args = JS_VALUE_ARGS(js_gui_view_set_arg_list);
|
||||
|
||||
const char* name;
|
||||
mjs_val_t value;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_STR(&name), JS_ARG_ANY(&value));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_gui_view_set_args, &name, &value);
|
||||
|
||||
JsGuiViewData* data = JS_GET_CONTEXT(mjs);
|
||||
bool success = js_gui_view_assign(mjs, name, value, data);
|
||||
UNUSED(success);
|
||||
@@ -280,12 +310,19 @@ static void js_gui_view_set(struct mjs* mjs) {
|
||||
* @brief `View.addChild`
|
||||
*/
|
||||
static void js_gui_view_add_child(struct mjs* mjs) {
|
||||
static const JsValueDeclaration js_gui_view_add_child_arg_list[] = {
|
||||
JS_VALUE_SIMPLE(JsValueTypeAny),
|
||||
};
|
||||
static const JsValueArguments js_gui_view_add_child_args =
|
||||
JS_VALUE_ARGS(js_gui_view_add_child_arg_list);
|
||||
|
||||
mjs_val_t child;
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_gui_view_add_child_args, &child);
|
||||
|
||||
JsGuiViewData* data = JS_GET_CONTEXT(mjs);
|
||||
if(!data->descriptor->add_child || !data->descriptor->reset_children)
|
||||
JS_ERROR_AND_RETURN(mjs, MJS_BAD_ARGS_ERROR, "this View can't have children");
|
||||
|
||||
mjs_val_t child;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_ANY(&child));
|
||||
bool success = data->descriptor->add_child(mjs, data->specific_view, data->custom_data, child);
|
||||
UNUSED(success);
|
||||
mjs_return(mjs, MJS_UNDEFINED);
|
||||
@@ -307,12 +344,19 @@ static void js_gui_view_reset_children(struct mjs* mjs) {
|
||||
* @brief `View.setChildren`
|
||||
*/
|
||||
static void js_gui_view_set_children(struct mjs* mjs) {
|
||||
static const JsValueDeclaration js_gui_view_set_children_arg_list[] = {
|
||||
JS_VALUE_SIMPLE(JsValueTypeAnyArray),
|
||||
};
|
||||
static const JsValueArguments js_gui_view_set_children_args =
|
||||
JS_VALUE_ARGS(js_gui_view_set_children_arg_list);
|
||||
|
||||
mjs_val_t children;
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_gui_view_set_children_args, &children);
|
||||
|
||||
JsGuiViewData* data = JS_GET_CONTEXT(mjs);
|
||||
if(!data->descriptor->add_child || !data->descriptor->reset_children)
|
||||
JS_ERROR_AND_RETURN(mjs, MJS_BAD_ARGS_ERROR, "this View can't have children");
|
||||
|
||||
mjs_val_t children;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_ARR(&children));
|
||||
js_gui_view_internal_set_children(mjs, children, data);
|
||||
}
|
||||
|
||||
@@ -365,7 +409,6 @@ static mjs_val_t js_gui_make_view(struct mjs* mjs, const JsViewDescriptor* descr
|
||||
* @brief `ViewFactory.make`
|
||||
*/
|
||||
static void js_gui_vf_make(struct mjs* mjs) {
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY); // 0 args
|
||||
const JsViewDescriptor* descriptor = JS_GET_CONTEXT(mjs);
|
||||
mjs_return(mjs, js_gui_make_view(mjs, descriptor));
|
||||
}
|
||||
@@ -374,8 +417,15 @@ static void js_gui_vf_make(struct mjs* mjs) {
|
||||
* @brief `ViewFactory.makeWith`
|
||||
*/
|
||||
static void js_gui_vf_make_with(struct mjs* mjs) {
|
||||
mjs_val_t props;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_AT_LEAST, JS_ARG_OBJ(&props));
|
||||
static const JsValueDeclaration js_gui_vf_make_with_arg_list[] = {
|
||||
JS_VALUE_SIMPLE(JsValueTypeAnyObject),
|
||||
JS_VALUE_SIMPLE(JsValueTypeAny),
|
||||
};
|
||||
static const JsValueArguments js_gui_vf_make_with_args =
|
||||
JS_VALUE_ARGS(js_gui_vf_make_with_arg_list);
|
||||
|
||||
mjs_val_t props, children;
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_gui_vf_make_with_args, &props, &children);
|
||||
const JsViewDescriptor* descriptor = JS_GET_CONTEXT(mjs);
|
||||
|
||||
// make the object like normal
|
||||
@@ -396,14 +446,10 @@ static void js_gui_vf_make_with(struct mjs* mjs) {
|
||||
}
|
||||
|
||||
// assign children
|
||||
if(mjs_nargs(mjs) >= 2) {
|
||||
if(mjs_is_array(children)) {
|
||||
if(!data->descriptor->add_child || !data->descriptor->reset_children)
|
||||
JS_ERROR_AND_RETURN(mjs, MJS_BAD_ARGS_ERROR, "this View can't have children");
|
||||
|
||||
mjs_val_t children = mjs_arg(mjs, 1);
|
||||
if(!mjs_is_array(children))
|
||||
JS_ERROR_AND_RETURN(mjs, MJS_BAD_ARGS_ERROR, "argument 1: expected array");
|
||||
|
||||
if(!js_gui_view_internal_set_children(mjs, children, data)) return;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,60 +35,62 @@ static void
|
||||
}
|
||||
|
||||
static void js_serial_setup(struct mjs* mjs) {
|
||||
static const JsValueEnumVariant js_serial_id_variants[] = {
|
||||
{"lpuart", FuriHalSerialIdLpuart},
|
||||
{"usart", FuriHalSerialIdUsart},
|
||||
};
|
||||
|
||||
static const JsValueEnumVariant js_serial_data_bit_variants[] = {
|
||||
{"6", FuriHalSerialDataBits6},
|
||||
{"7", FuriHalSerialDataBits7},
|
||||
{"8", FuriHalSerialDataBits8},
|
||||
{"9", FuriHalSerialDataBits9},
|
||||
};
|
||||
static const JsValueDeclaration js_serial_data_bits = JS_VALUE_ENUM_W_DEFAULT(
|
||||
FuriHalSerialDataBits, js_serial_data_bit_variants, FuriHalSerialDataBits8);
|
||||
|
||||
static const JsValueEnumVariant js_serial_parity_variants[] = {
|
||||
{"none", FuriHalSerialParityNone},
|
||||
{"even", FuriHalSerialParityEven},
|
||||
{"odd", FuriHalSerialParityOdd},
|
||||
};
|
||||
static const JsValueDeclaration js_serial_parity = JS_VALUE_ENUM_W_DEFAULT(
|
||||
FuriHalSerialParity, js_serial_parity_variants, FuriHalSerialParityNone);
|
||||
|
||||
static const JsValueEnumVariant js_serial_stop_bit_variants[] = {
|
||||
{"0.5", FuriHalSerialStopBits0_5},
|
||||
{"1", FuriHalSerialStopBits1},
|
||||
{"1.5", FuriHalSerialStopBits1_5},
|
||||
{"2", FuriHalSerialStopBits2},
|
||||
};
|
||||
static const JsValueDeclaration js_serial_stop_bits = JS_VALUE_ENUM_W_DEFAULT(
|
||||
FuriHalSerialStopBits, js_serial_stop_bit_variants, FuriHalSerialStopBits1);
|
||||
|
||||
static const JsValueObjectField js_serial_framing_fields[] = {
|
||||
{"dataBits", &js_serial_data_bits},
|
||||
{"parity", &js_serial_parity},
|
||||
{"stopBits", &js_serial_stop_bits},
|
||||
};
|
||||
|
||||
static const JsValueDeclaration js_serial_setup_arg_list[] = {
|
||||
JS_VALUE_ENUM(FuriHalSerialId, js_serial_id_variants),
|
||||
JS_VALUE_SIMPLE(JsValueTypeInt32),
|
||||
JS_VALUE_OBJECT_W_DEFAULTS(js_serial_framing_fields),
|
||||
};
|
||||
static const JsValueArguments js_serial_setup_args = JS_VALUE_ARGS(js_serial_setup_arg_list);
|
||||
|
||||
FuriHalSerialId serial_id;
|
||||
int32_t baudrate;
|
||||
JS_ENUM_MAP(serial_id, {"lpuart", FuriHalSerialIdLpuart}, {"usart", FuriHalSerialIdUsart});
|
||||
JS_FETCH_ARGS_OR_RETURN(
|
||||
mjs, JS_AT_LEAST, JS_ARG_ENUM(serial_id, "SerialId"), JS_ARG_INT32(&baudrate));
|
||||
|
||||
FuriHalSerialDataBits data_bits = FuriHalSerialDataBits8;
|
||||
FuriHalSerialParity parity = FuriHalSerialParityNone;
|
||||
FuriHalSerialStopBits stop_bits = FuriHalSerialStopBits1;
|
||||
if(mjs_nargs(mjs) > 2) {
|
||||
struct framing {
|
||||
mjs_val_t data_bits;
|
||||
mjs_val_t parity;
|
||||
mjs_val_t stop_bits;
|
||||
} framing;
|
||||
JS_OBJ_MAP(
|
||||
framing,
|
||||
{"dataBits", offsetof(struct framing, data_bits)},
|
||||
{"parity", offsetof(struct framing, parity)},
|
||||
{"stopBits", offsetof(struct framing, stop_bits)});
|
||||
JS_ENUM_MAP(
|
||||
data_bits,
|
||||
{"6", FuriHalSerialDataBits6},
|
||||
{"7", FuriHalSerialDataBits7},
|
||||
{"8", FuriHalSerialDataBits8},
|
||||
{"9", FuriHalSerialDataBits9});
|
||||
JS_ENUM_MAP(
|
||||
parity,
|
||||
{"none", FuriHalSerialParityNone},
|
||||
{"even", FuriHalSerialParityEven},
|
||||
{"odd", FuriHalSerialParityOdd});
|
||||
JS_ENUM_MAP(
|
||||
stop_bits,
|
||||
{"0.5", FuriHalSerialStopBits0_5},
|
||||
{"1", FuriHalSerialStopBits1},
|
||||
{"1.5", FuriHalSerialStopBits1_5},
|
||||
{"2", FuriHalSerialStopBits2});
|
||||
mjs_val_t framing_obj = mjs_arg(mjs, 2);
|
||||
JS_CONVERT_OR_RETURN(mjs, &framing_obj, JS_ARG_OBJECT(framing, "Framing"), "argument 2");
|
||||
JS_CONVERT_OR_RETURN(
|
||||
mjs, &framing.data_bits, JS_ARG_ENUM(data_bits, "DataBits"), "argument 2: dataBits");
|
||||
JS_CONVERT_OR_RETURN(
|
||||
mjs, &framing.parity, JS_ARG_ENUM(parity, "Parity"), "argument 2: parity");
|
||||
JS_CONVERT_OR_RETURN(
|
||||
mjs, &framing.stop_bits, JS_ARG_ENUM(stop_bits, "StopBits"), "argument 2: stopBits");
|
||||
}
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(
|
||||
mjs, &js_serial_setup_args, &serial_id, &baudrate, &data_bits, &parity, &stop_bits);
|
||||
|
||||
JsSerialInst* serial = JS_GET_CONTEXT(mjs);
|
||||
|
||||
if(serial->setup_done) {
|
||||
mjs_prepend_errorf(mjs, MJS_INTERNAL_ERROR, "Serial is already configured");
|
||||
mjs_return(mjs, MJS_UNDEFINED);
|
||||
return;
|
||||
}
|
||||
if(serial->setup_done)
|
||||
JS_ERROR_AND_RETURN(mjs, MJS_INTERNAL_ERROR, "Serial is already configured");
|
||||
|
||||
expansion_disable(furi_record_open(RECORD_EXPANSION));
|
||||
furi_record_close(RECORD_EXPANSION);
|
||||
@@ -123,28 +125,20 @@ static void js_serial_deinit(JsSerialInst* js_serial) {
|
||||
}
|
||||
|
||||
static void js_serial_end(struct mjs* mjs) {
|
||||
mjs_val_t obj_inst = mjs_get(mjs, mjs_get_this(mjs), INST_PROP_NAME, ~0);
|
||||
JsSerialInst* serial = mjs_get_ptr(mjs, obj_inst);
|
||||
JsSerialInst* serial = JS_GET_CONTEXT(mjs);
|
||||
furi_assert(serial);
|
||||
|
||||
if(!serial->setup_done) {
|
||||
mjs_prepend_errorf(mjs, MJS_INTERNAL_ERROR, "Serial is not configured");
|
||||
mjs_return(mjs, MJS_UNDEFINED);
|
||||
return;
|
||||
}
|
||||
if(!serial->setup_done)
|
||||
JS_ERROR_AND_RETURN(mjs, MJS_INTERNAL_ERROR, "Serial is not configured");
|
||||
|
||||
js_serial_deinit(serial);
|
||||
}
|
||||
|
||||
static void js_serial_write(struct mjs* mjs) {
|
||||
mjs_val_t obj_inst = mjs_get(mjs, mjs_get_this(mjs), INST_PROP_NAME, ~0);
|
||||
JsSerialInst* serial = mjs_get_ptr(mjs, obj_inst);
|
||||
JsSerialInst* serial = JS_GET_CONTEXT(mjs);
|
||||
furi_assert(serial);
|
||||
if(!serial->setup_done) {
|
||||
mjs_prepend_errorf(mjs, MJS_INTERNAL_ERROR, "Serial is not configured");
|
||||
mjs_return(mjs, MJS_UNDEFINED);
|
||||
return;
|
||||
}
|
||||
if(!serial->setup_done)
|
||||
JS_ERROR_AND_RETURN(mjs, MJS_INTERNAL_ERROR, "Serial is not configured");
|
||||
|
||||
bool args_correct = true;
|
||||
|
||||
@@ -228,43 +222,20 @@ static size_t js_serial_receive(JsSerialInst* serial, char* buf, size_t len, uin
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
static const JsValueDeclaration js_serial_read_arg_list[] = {
|
||||
JS_VALUE_SIMPLE(JsValueTypeInt32),
|
||||
JS_VALUE_SIMPLE_W_DEFAULT(JsValueTypeInt32, int32_val, INT32_MAX),
|
||||
};
|
||||
static const JsValueArguments js_serial_read_args = JS_VALUE_ARGS(js_serial_read_arg_list);
|
||||
|
||||
static void js_serial_read(struct mjs* mjs) {
|
||||
mjs_val_t obj_inst = mjs_get(mjs, mjs_get_this(mjs), INST_PROP_NAME, ~0);
|
||||
JsSerialInst* serial = mjs_get_ptr(mjs, obj_inst);
|
||||
JsSerialInst* serial = JS_GET_CONTEXT(mjs);
|
||||
furi_assert(serial);
|
||||
if(!serial->setup_done) {
|
||||
mjs_prepend_errorf(mjs, MJS_INTERNAL_ERROR, "Serial is not configured");
|
||||
mjs_return(mjs, MJS_UNDEFINED);
|
||||
return;
|
||||
}
|
||||
if(!serial->setup_done)
|
||||
JS_ERROR_AND_RETURN(mjs, MJS_INTERNAL_ERROR, "Serial is not configured");
|
||||
|
||||
size_t read_len = 0;
|
||||
uint32_t timeout = FuriWaitForever;
|
||||
|
||||
do {
|
||||
size_t num_args = mjs_nargs(mjs);
|
||||
if(num_args == 1) {
|
||||
mjs_val_t arg = mjs_arg(mjs, 0);
|
||||
if(!mjs_is_number(arg)) {
|
||||
break;
|
||||
}
|
||||
read_len = mjs_get_int32(mjs, arg);
|
||||
} else if(num_args == 2) {
|
||||
mjs_val_t len_arg = mjs_arg(mjs, 0);
|
||||
mjs_val_t timeout_arg = mjs_arg(mjs, 1);
|
||||
if((!mjs_is_number(len_arg)) || (!mjs_is_number(timeout_arg))) {
|
||||
break;
|
||||
}
|
||||
read_len = mjs_get_int32(mjs, len_arg);
|
||||
timeout = mjs_get_int32(mjs, timeout_arg);
|
||||
}
|
||||
} while(0);
|
||||
|
||||
if(read_len == 0) {
|
||||
mjs_prepend_errorf(mjs, MJS_BAD_ARGS_ERROR, "");
|
||||
mjs_return(mjs, MJS_UNDEFINED);
|
||||
return;
|
||||
}
|
||||
int32_t read_len, timeout;
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_serial_read_args, &read_len, &timeout);
|
||||
|
||||
char* read_buf = malloc(read_len);
|
||||
size_t bytes_read = js_serial_receive(serial, read_buf, read_len, timeout);
|
||||
@@ -278,37 +249,19 @@ static void js_serial_read(struct mjs* mjs) {
|
||||
}
|
||||
|
||||
static void js_serial_readln(struct mjs* mjs) {
|
||||
mjs_val_t obj_inst = mjs_get(mjs, mjs_get_this(mjs), INST_PROP_NAME, ~0);
|
||||
JsSerialInst* serial = mjs_get_ptr(mjs, obj_inst);
|
||||
JsSerialInst* serial = JS_GET_CONTEXT(mjs);
|
||||
furi_assert(serial);
|
||||
if(!serial->setup_done) {
|
||||
mjs_prepend_errorf(mjs, MJS_INTERNAL_ERROR, "Serial is not configured");
|
||||
mjs_return(mjs, MJS_UNDEFINED);
|
||||
return;
|
||||
}
|
||||
if(!serial->setup_done)
|
||||
JS_ERROR_AND_RETURN(mjs, MJS_INTERNAL_ERROR, "Serial is not configured");
|
||||
|
||||
bool args_correct = false;
|
||||
uint32_t timeout = FuriWaitForever;
|
||||
static const JsValueDeclaration js_serial_readln_arg_list[] = {
|
||||
JS_VALUE_SIMPLE(JsValueTypeInt32),
|
||||
};
|
||||
static const JsValueArguments js_serial_readln_args = JS_VALUE_ARGS(js_serial_readln_arg_list);
|
||||
|
||||
do {
|
||||
size_t num_args = mjs_nargs(mjs);
|
||||
if(num_args > 1) {
|
||||
break;
|
||||
} else if(num_args == 1) {
|
||||
mjs_val_t arg = mjs_arg(mjs, 0);
|
||||
if(!mjs_is_number(arg)) {
|
||||
break;
|
||||
}
|
||||
timeout = mjs_get_int32(mjs, arg);
|
||||
}
|
||||
args_correct = true;
|
||||
} while(0);
|
||||
int32_t timeout;
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_serial_readln_args, &timeout);
|
||||
|
||||
if(!args_correct) {
|
||||
mjs_prepend_errorf(mjs, MJS_BAD_ARGS_ERROR, "");
|
||||
mjs_return(mjs, MJS_UNDEFINED);
|
||||
return;
|
||||
}
|
||||
FuriString* rx_buf = furi_string_alloc();
|
||||
size_t bytes_read = 0;
|
||||
char read_char = 0;
|
||||
@@ -335,42 +288,13 @@ static void js_serial_readln(struct mjs* mjs) {
|
||||
}
|
||||
|
||||
static void js_serial_read_bytes(struct mjs* mjs) {
|
||||
mjs_val_t obj_inst = mjs_get(mjs, mjs_get_this(mjs), INST_PROP_NAME, ~0);
|
||||
JsSerialInst* serial = mjs_get_ptr(mjs, obj_inst);
|
||||
JsSerialInst* serial = JS_GET_CONTEXT(mjs);
|
||||
furi_assert(serial);
|
||||
if(!serial->setup_done) {
|
||||
mjs_prepend_errorf(mjs, MJS_INTERNAL_ERROR, "Serial is not configured");
|
||||
mjs_return(mjs, MJS_UNDEFINED);
|
||||
return;
|
||||
}
|
||||
if(!serial->setup_done)
|
||||
JS_ERROR_AND_RETURN(mjs, MJS_INTERNAL_ERROR, "Serial is not configured");
|
||||
|
||||
size_t read_len = 0;
|
||||
uint32_t timeout = FuriWaitForever;
|
||||
|
||||
do {
|
||||
size_t num_args = mjs_nargs(mjs);
|
||||
if(num_args == 1) {
|
||||
mjs_val_t arg = mjs_arg(mjs, 0);
|
||||
if(!mjs_is_number(arg)) {
|
||||
break;
|
||||
}
|
||||
read_len = mjs_get_int32(mjs, arg);
|
||||
} else if(num_args == 2) {
|
||||
mjs_val_t len_arg = mjs_arg(mjs, 0);
|
||||
mjs_val_t timeout_arg = mjs_arg(mjs, 1);
|
||||
if((!mjs_is_number(len_arg)) || (!mjs_is_number(timeout_arg))) {
|
||||
break;
|
||||
}
|
||||
read_len = mjs_get_int32(mjs, len_arg);
|
||||
timeout = mjs_get_int32(mjs, timeout_arg);
|
||||
}
|
||||
} while(0);
|
||||
|
||||
if(read_len == 0) {
|
||||
mjs_prepend_errorf(mjs, MJS_BAD_ARGS_ERROR, "");
|
||||
mjs_return(mjs, MJS_UNDEFINED);
|
||||
return;
|
||||
}
|
||||
int32_t read_len, timeout;
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_serial_read_args, &read_len, &timeout);
|
||||
|
||||
char* read_buf = malloc(read_len);
|
||||
size_t bytes_read = js_serial_receive(serial, read_buf, read_len, timeout);
|
||||
@@ -399,27 +323,19 @@ static char* js_serial_receive_any(JsSerialInst* serial, size_t* len, uint32_t t
|
||||
}
|
||||
|
||||
static void js_serial_read_any(struct mjs* mjs) {
|
||||
mjs_val_t obj_inst = mjs_get(mjs, mjs_get_this(mjs), INST_PROP_NAME, ~0);
|
||||
JsSerialInst* serial = mjs_get_ptr(mjs, obj_inst);
|
||||
JsSerialInst* serial = JS_GET_CONTEXT(mjs);
|
||||
furi_assert(serial);
|
||||
if(!serial->setup_done) {
|
||||
mjs_prepend_errorf(mjs, MJS_INTERNAL_ERROR, "Serial is not configured");
|
||||
mjs_return(mjs, MJS_UNDEFINED);
|
||||
return;
|
||||
}
|
||||
if(!serial->setup_done)
|
||||
JS_ERROR_AND_RETURN(mjs, MJS_INTERNAL_ERROR, "Serial is not configured");
|
||||
|
||||
uint32_t timeout = FuriWaitForever;
|
||||
static const JsValueDeclaration js_serial_read_any_arg_list[] = {
|
||||
JS_VALUE_SIMPLE_W_DEFAULT(JsValueTypeInt32, int32_val, INT32_MAX),
|
||||
};
|
||||
static const JsValueArguments js_serial_read_any_args =
|
||||
JS_VALUE_ARGS(js_serial_read_any_arg_list);
|
||||
|
||||
do {
|
||||
size_t num_args = mjs_nargs(mjs);
|
||||
if(num_args == 1) {
|
||||
mjs_val_t timeout_arg = mjs_arg(mjs, 0);
|
||||
if(!mjs_is_number(timeout_arg)) {
|
||||
break;
|
||||
}
|
||||
timeout = mjs_get_int32(mjs, timeout_arg);
|
||||
}
|
||||
} while(0);
|
||||
int32_t timeout;
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_serial_read_any_args, &timeout);
|
||||
|
||||
size_t bytes_read = 0;
|
||||
char* read_buf = js_serial_receive_any(serial, &bytes_read, timeout);
|
||||
@@ -663,16 +579,19 @@ static void* js_serial_create(struct mjs* mjs, mjs_val_t* object, JsModules* mod
|
||||
UNUSED(modules);
|
||||
JsSerialInst* js_serial = malloc(sizeof(JsSerialInst));
|
||||
js_serial->mjs = mjs;
|
||||
|
||||
mjs_val_t serial_obj = mjs_mk_object(mjs);
|
||||
mjs_set(mjs, serial_obj, INST_PROP_NAME, ~0, mjs_mk_foreign(mjs, js_serial));
|
||||
mjs_set(mjs, serial_obj, "setup", ~0, MJS_MK_FN(js_serial_setup));
|
||||
mjs_set(mjs, serial_obj, "end", ~0, MJS_MK_FN(js_serial_end));
|
||||
mjs_set(mjs, serial_obj, "write", ~0, MJS_MK_FN(js_serial_write));
|
||||
mjs_set(mjs, serial_obj, "read", ~0, MJS_MK_FN(js_serial_read));
|
||||
mjs_set(mjs, serial_obj, "readln", ~0, MJS_MK_FN(js_serial_readln));
|
||||
mjs_set(mjs, serial_obj, "readBytes", ~0, MJS_MK_FN(js_serial_read_bytes));
|
||||
mjs_set(mjs, serial_obj, "readAny", ~0, MJS_MK_FN(js_serial_read_any));
|
||||
mjs_set(mjs, serial_obj, "expect", ~0, MJS_MK_FN(js_serial_expect));
|
||||
JS_ASSIGN_MULTI(mjs, serial_obj) {
|
||||
JS_FIELD(INST_PROP_NAME, mjs_mk_foreign(mjs, js_serial));
|
||||
JS_FIELD("setup", MJS_MK_FN(js_serial_setup));
|
||||
JS_FIELD("end", MJS_MK_FN(js_serial_end));
|
||||
JS_FIELD("write", MJS_MK_FN(js_serial_write));
|
||||
JS_FIELD("read", MJS_MK_FN(js_serial_read));
|
||||
JS_FIELD("readln", MJS_MK_FN(js_serial_readln));
|
||||
JS_FIELD("readBytes", MJS_MK_FN(js_serial_read_bytes));
|
||||
JS_FIELD("readAny", MJS_MK_FN(js_serial_read_any));
|
||||
JS_FIELD("expect", MJS_MK_FN(js_serial_expect));
|
||||
}
|
||||
*object = serial_obj;
|
||||
|
||||
return js_serial;
|
||||
|
||||
@@ -1,42 +1,79 @@
|
||||
#include "../js_modules.h" // IWYU pragma: keep
|
||||
#include <path.h>
|
||||
|
||||
// ---=== file ops ===---
|
||||
// ==========================
|
||||
// Common argument signatures
|
||||
// ==========================
|
||||
|
||||
static const JsValueDeclaration js_storage_1_int_arg_list[] = {
|
||||
JS_VALUE_SIMPLE(JsValueTypeInt32),
|
||||
};
|
||||
static const JsValueArguments js_storage_1_int_args = JS_VALUE_ARGS(js_storage_1_int_arg_list);
|
||||
|
||||
static const JsValueDeclaration js_storage_1_str_arg_list[] = {
|
||||
JS_VALUE_SIMPLE(JsValueTypeString),
|
||||
};
|
||||
static const JsValueArguments js_storage_1_str_args = JS_VALUE_ARGS(js_storage_1_str_arg_list);
|
||||
|
||||
static const JsValueDeclaration js_storage_2_str_arg_list[] = {
|
||||
JS_VALUE_SIMPLE(JsValueTypeString),
|
||||
JS_VALUE_SIMPLE(JsValueTypeString),
|
||||
};
|
||||
static const JsValueArguments js_storage_2_str_args = JS_VALUE_ARGS(js_storage_2_str_arg_list);
|
||||
|
||||
// ======================
|
||||
// File object operations
|
||||
// ======================
|
||||
|
||||
static void js_storage_file_close(struct mjs* mjs) {
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY); // 0 args
|
||||
File* file = JS_GET_CONTEXT(mjs);
|
||||
mjs_return(mjs, mjs_mk_boolean(mjs, storage_file_close(file)));
|
||||
}
|
||||
|
||||
static void js_storage_file_is_open(struct mjs* mjs) {
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY); // 0 args
|
||||
File* file = JS_GET_CONTEXT(mjs);
|
||||
mjs_return(mjs, mjs_mk_boolean(mjs, storage_file_is_open(file)));
|
||||
}
|
||||
|
||||
static void js_storage_file_read(struct mjs* mjs) {
|
||||
enum {
|
||||
ReadModeAscii,
|
||||
ReadModeBinary,
|
||||
} read_mode;
|
||||
JS_ENUM_MAP(read_mode, {"ascii", ReadModeAscii}, {"binary", ReadModeBinary});
|
||||
typedef enum {
|
||||
JsStorageReadModeAscii,
|
||||
JsStorageReadModeBinary,
|
||||
} JsStorageReadMode;
|
||||
static const JsValueEnumVariant js_storage_read_mode_variants[] = {
|
||||
{"ascii", JsStorageReadModeAscii},
|
||||
{"binary", JsStorageReadModeBinary},
|
||||
};
|
||||
static const JsValueDeclaration js_storage_read_arg_list[] = {
|
||||
JS_VALUE_ENUM(JsStorageReadMode, js_storage_read_mode_variants),
|
||||
JS_VALUE_SIMPLE(JsValueTypeInt32),
|
||||
};
|
||||
static const JsValueArguments js_storage_read_args = JS_VALUE_ARGS(js_storage_read_arg_list);
|
||||
|
||||
JsStorageReadMode read_mode;
|
||||
int32_t length;
|
||||
JS_FETCH_ARGS_OR_RETURN(
|
||||
mjs, JS_EXACTLY, JS_ARG_ENUM(read_mode, "ReadMode"), JS_ARG_INT32(&length));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_storage_read_args, &read_mode, &length);
|
||||
|
||||
File* file = JS_GET_CONTEXT(mjs);
|
||||
char buffer[length];
|
||||
size_t actually_read = storage_file_read(file, buffer, length);
|
||||
if(read_mode == ReadModeAscii) {
|
||||
if(read_mode == JsStorageReadModeAscii) {
|
||||
mjs_return(mjs, mjs_mk_string(mjs, buffer, actually_read, true));
|
||||
} else if(read_mode == ReadModeBinary) {
|
||||
} else if(read_mode == JsStorageReadModeBinary) {
|
||||
mjs_return(mjs, mjs_mk_array_buf(mjs, buffer, actually_read));
|
||||
}
|
||||
}
|
||||
|
||||
static void js_storage_file_write(struct mjs* mjs) {
|
||||
static const JsValueDeclaration js_storage_file_write_arg_list[] = {
|
||||
JS_VALUE_SIMPLE(JsValueTypeAny),
|
||||
};
|
||||
static const JsValueArguments js_storage_file_write_args =
|
||||
JS_VALUE_ARGS(js_storage_file_write_arg_list);
|
||||
|
||||
mjs_val_t data;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_ANY(&data));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_storage_file_write_args, &data);
|
||||
|
||||
const void* buf;
|
||||
size_t len;
|
||||
if(mjs_is_string(data)) {
|
||||
@@ -52,52 +89,58 @@ static void js_storage_file_write(struct mjs* mjs) {
|
||||
|
||||
static void js_storage_file_seek_relative(struct mjs* mjs) {
|
||||
int32_t offset;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_INT32(&offset));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_storage_1_int_args, &offset);
|
||||
File* file = JS_GET_CONTEXT(mjs);
|
||||
mjs_return(mjs, mjs_mk_boolean(mjs, storage_file_seek(file, offset, false)));
|
||||
}
|
||||
|
||||
static void js_storage_file_seek_absolute(struct mjs* mjs) {
|
||||
int32_t offset;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_INT32(&offset));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_storage_1_int_args, &offset);
|
||||
File* file = JS_GET_CONTEXT(mjs);
|
||||
mjs_return(mjs, mjs_mk_boolean(mjs, storage_file_seek(file, offset, true)));
|
||||
}
|
||||
|
||||
static void js_storage_file_tell(struct mjs* mjs) {
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY); // 0 args
|
||||
File* file = JS_GET_CONTEXT(mjs);
|
||||
mjs_return(mjs, mjs_mk_number(mjs, storage_file_tell(file)));
|
||||
}
|
||||
|
||||
static void js_storage_file_truncate(struct mjs* mjs) {
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY); // 0 args
|
||||
File* file = JS_GET_CONTEXT(mjs);
|
||||
mjs_return(mjs, mjs_mk_boolean(mjs, storage_file_truncate(file)));
|
||||
}
|
||||
|
||||
static void js_storage_file_size(struct mjs* mjs) {
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY); // 0 args
|
||||
File* file = JS_GET_CONTEXT(mjs);
|
||||
mjs_return(mjs, mjs_mk_number(mjs, storage_file_size(file)));
|
||||
}
|
||||
|
||||
static void js_storage_file_eof(struct mjs* mjs) {
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY); // 0 args
|
||||
File* file = JS_GET_CONTEXT(mjs);
|
||||
mjs_return(mjs, mjs_mk_boolean(mjs, storage_file_eof(file)));
|
||||
}
|
||||
|
||||
static void js_storage_file_copy_to(struct mjs* mjs) {
|
||||
File* source = JS_GET_CONTEXT(mjs);
|
||||
static const JsValueDeclaration js_storage_file_write_arg_list[] = {
|
||||
JS_VALUE_SIMPLE(JsValueTypeAny),
|
||||
JS_VALUE_SIMPLE(JsValueTypeInt32),
|
||||
};
|
||||
static const JsValueArguments js_storage_file_write_args =
|
||||
JS_VALUE_ARGS(js_storage_file_write_arg_list);
|
||||
|
||||
mjs_val_t dest_obj;
|
||||
int32_t bytes;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_OBJ(&dest_obj), JS_ARG_INT32(&bytes));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_storage_file_write_args, &dest_obj, &bytes);
|
||||
|
||||
File* source = JS_GET_CONTEXT(mjs);
|
||||
File* destination = JS_GET_INST(mjs, dest_obj);
|
||||
mjs_return(mjs, mjs_mk_boolean(mjs, storage_file_copy_to_file(source, destination, bytes)));
|
||||
}
|
||||
|
||||
// ---=== top-level file ops ===---
|
||||
// =========================
|
||||
// Top-level file operations
|
||||
// =========================
|
||||
|
||||
// common destructor for file and dir objects
|
||||
static void js_storage_file_destructor(struct mjs* mjs, mjs_val_t obj) {
|
||||
@@ -106,23 +149,33 @@ static void js_storage_file_destructor(struct mjs* mjs, mjs_val_t obj) {
|
||||
}
|
||||
|
||||
static void js_storage_open_file(struct mjs* mjs) {
|
||||
const char* path;
|
||||
FS_AccessMode access_mode;
|
||||
FS_OpenMode open_mode;
|
||||
JS_ENUM_MAP(access_mode, {"r", FSAM_READ}, {"w", FSAM_WRITE}, {"rw", FSAM_READ_WRITE});
|
||||
JS_ENUM_MAP(
|
||||
open_mode,
|
||||
static const JsValueEnumVariant js_storage_fsam_variants[] = {
|
||||
{"r", FSAM_READ},
|
||||
{"w", FSAM_WRITE},
|
||||
{"rw", FSAM_READ_WRITE},
|
||||
};
|
||||
|
||||
static const JsValueEnumVariant js_storage_fsom_variants[] = {
|
||||
{"open_existing", FSOM_OPEN_EXISTING},
|
||||
{"open_always", FSOM_OPEN_ALWAYS},
|
||||
{"open_append", FSOM_OPEN_APPEND},
|
||||
{"create_new", FSOM_CREATE_NEW},
|
||||
{"create_always", FSOM_CREATE_ALWAYS});
|
||||
JS_FETCH_ARGS_OR_RETURN(
|
||||
mjs,
|
||||
JS_EXACTLY,
|
||||
JS_ARG_STR(&path),
|
||||
JS_ARG_ENUM(access_mode, "AccessMode"),
|
||||
JS_ARG_ENUM(open_mode, "OpenMode"));
|
||||
{"create_always", FSOM_CREATE_ALWAYS},
|
||||
};
|
||||
|
||||
static const JsValueDeclaration js_storage_open_file_arg_list[] = {
|
||||
JS_VALUE_SIMPLE(JsValueTypeString),
|
||||
JS_VALUE_ENUM(FS_AccessMode, js_storage_fsam_variants),
|
||||
JS_VALUE_ENUM(FS_OpenMode, js_storage_fsom_variants),
|
||||
};
|
||||
static const JsValueArguments js_storage_open_file_args =
|
||||
JS_VALUE_ARGS(js_storage_open_file_arg_list);
|
||||
|
||||
const char* path;
|
||||
FS_AccessMode access_mode;
|
||||
FS_OpenMode open_mode;
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(
|
||||
mjs, &js_storage_open_file_args, &path, &access_mode, &open_mode);
|
||||
|
||||
Storage* storage = JS_GET_CONTEXT(mjs);
|
||||
File* file = storage_file_alloc(storage);
|
||||
@@ -152,16 +205,18 @@ static void js_storage_open_file(struct mjs* mjs) {
|
||||
|
||||
static void js_storage_file_exists(struct mjs* mjs) {
|
||||
const char* path;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_STR(&path));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_storage_1_str_args, &path);
|
||||
Storage* storage = JS_GET_CONTEXT(mjs);
|
||||
mjs_return(mjs, mjs_mk_boolean(mjs, storage_file_exists(storage, path)));
|
||||
}
|
||||
|
||||
// ---=== dir ops ===---
|
||||
// ====================
|
||||
// Directory operations
|
||||
// ====================
|
||||
|
||||
static void js_storage_read_directory(struct mjs* mjs) {
|
||||
const char* path;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_STR(&path));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_storage_1_str_args, &path);
|
||||
|
||||
Storage* storage = JS_GET_CONTEXT(mjs);
|
||||
File* dir = storage_file_alloc(storage);
|
||||
@@ -200,30 +255,32 @@ static void js_storage_read_directory(struct mjs* mjs) {
|
||||
|
||||
static void js_storage_directory_exists(struct mjs* mjs) {
|
||||
const char* path;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_STR(&path));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_storage_1_str_args, &path);
|
||||
Storage* storage = JS_GET_CONTEXT(mjs);
|
||||
mjs_return(mjs, mjs_mk_boolean(mjs, storage_dir_exists(storage, path)));
|
||||
}
|
||||
|
||||
static void js_storage_make_directory(struct mjs* mjs) {
|
||||
const char* path;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_STR(&path));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_storage_1_str_args, &path);
|
||||
Storage* storage = JS_GET_CONTEXT(mjs);
|
||||
mjs_return(mjs, mjs_mk_boolean(mjs, storage_simply_mkdir(storage, path)));
|
||||
}
|
||||
|
||||
// ---=== common ops ===---
|
||||
// =================
|
||||
// Common operations
|
||||
// =================
|
||||
|
||||
static void js_storage_file_or_dir_exists(struct mjs* mjs) {
|
||||
const char* path;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_STR(&path));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_storage_1_str_args, &path);
|
||||
Storage* storage = JS_GET_CONTEXT(mjs);
|
||||
mjs_return(mjs, mjs_mk_boolean(mjs, storage_common_exists(storage, path)));
|
||||
}
|
||||
|
||||
static void js_storage_stat(struct mjs* mjs) {
|
||||
const char* path;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_STR(&path));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_storage_1_str_args, &path);
|
||||
Storage* storage = JS_GET_CONTEXT(mjs);
|
||||
FileInfo file_info;
|
||||
uint32_t timestamp;
|
||||
@@ -244,21 +301,21 @@ static void js_storage_stat(struct mjs* mjs) {
|
||||
|
||||
static void js_storage_remove(struct mjs* mjs) {
|
||||
const char* path;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_STR(&path));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_storage_1_str_args, &path);
|
||||
Storage* storage = JS_GET_CONTEXT(mjs);
|
||||
mjs_return(mjs, mjs_mk_boolean(mjs, storage_simply_remove(storage, path)));
|
||||
}
|
||||
|
||||
static void js_storage_rmrf(struct mjs* mjs) {
|
||||
const char* path;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_STR(&path));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_storage_1_str_args, &path);
|
||||
Storage* storage = JS_GET_CONTEXT(mjs);
|
||||
mjs_return(mjs, mjs_mk_boolean(mjs, storage_simply_remove_recursive(storage, path)));
|
||||
}
|
||||
|
||||
static void js_storage_rename(struct mjs* mjs) {
|
||||
const char *old, *new;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_STR(&old), JS_ARG_STR(&new));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_storage_2_str_args, &old, &new);
|
||||
Storage* storage = JS_GET_CONTEXT(mjs);
|
||||
FS_Error status = storage_common_rename(storage, old, new);
|
||||
mjs_return(mjs, mjs_mk_boolean(mjs, status == FSE_OK));
|
||||
@@ -266,7 +323,7 @@ static void js_storage_rename(struct mjs* mjs) {
|
||||
|
||||
static void js_storage_copy(struct mjs* mjs) {
|
||||
const char *source, *dest;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_STR(&source), JS_ARG_STR(&dest));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_storage_2_str_args, &source, &dest);
|
||||
Storage* storage = JS_GET_CONTEXT(mjs);
|
||||
FS_Error status = storage_common_copy(storage, source, dest);
|
||||
mjs_return(mjs, mjs_mk_boolean(mjs, status == FSE_OK || status == FSE_EXIST));
|
||||
@@ -274,7 +331,7 @@ static void js_storage_copy(struct mjs* mjs) {
|
||||
|
||||
static void js_storage_fs_info(struct mjs* mjs) {
|
||||
const char* fs;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_STR(&fs));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_storage_1_str_args, &fs);
|
||||
Storage* storage = JS_GET_CONTEXT(mjs);
|
||||
uint64_t total_space, free_space;
|
||||
if(storage_common_fs_info(storage, fs, &total_space, &free_space) != FSE_OK) {
|
||||
@@ -290,15 +347,19 @@ static void js_storage_fs_info(struct mjs* mjs) {
|
||||
}
|
||||
|
||||
static void js_storage_next_available_filename(struct mjs* mjs) {
|
||||
static const JsValueDeclaration js_storage_naf_arg_list[] = {
|
||||
JS_VALUE_SIMPLE(JsValueTypeString),
|
||||
JS_VALUE_SIMPLE(JsValueTypeString),
|
||||
JS_VALUE_SIMPLE(JsValueTypeString),
|
||||
JS_VALUE_SIMPLE(JsValueTypeInt32),
|
||||
};
|
||||
static const JsValueArguments js_storage_naf_args = JS_VALUE_ARGS(js_storage_naf_arg_list);
|
||||
|
||||
const char *dir_path, *file_name, *file_ext;
|
||||
int32_t max_len;
|
||||
JS_FETCH_ARGS_OR_RETURN(
|
||||
mjs,
|
||||
JS_EXACTLY,
|
||||
JS_ARG_STR(&dir_path),
|
||||
JS_ARG_STR(&file_name),
|
||||
JS_ARG_STR(&file_ext),
|
||||
JS_ARG_INT32(&max_len));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(
|
||||
mjs, &js_storage_naf_args, &dir_path, &file_name, &file_ext, &max_len);
|
||||
|
||||
Storage* storage = JS_GET_CONTEXT(mjs);
|
||||
FuriString* next_name = furi_string_alloc();
|
||||
storage_get_next_filename(storage, dir_path, file_name, file_ext, next_name, max_len);
|
||||
@@ -306,23 +367,27 @@ static void js_storage_next_available_filename(struct mjs* mjs) {
|
||||
furi_string_free(next_name);
|
||||
}
|
||||
|
||||
// ---=== path ops ===---
|
||||
// ===============
|
||||
// Path operations
|
||||
// ===============
|
||||
|
||||
static void js_storage_are_paths_equal(struct mjs* mjs) {
|
||||
const char *path1, *path2;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_STR(&path1), JS_ARG_STR(&path2));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_storage_2_str_args, &path1, &path2);
|
||||
Storage* storage = JS_GET_CONTEXT(mjs);
|
||||
mjs_return(mjs, mjs_mk_boolean(mjs, storage_common_equivalent_path(storage, path1, path2)));
|
||||
}
|
||||
|
||||
static void js_storage_is_subpath_of(struct mjs* mjs) {
|
||||
const char *parent, *child;
|
||||
JS_FETCH_ARGS_OR_RETURN(mjs, JS_EXACTLY, JS_ARG_STR(&parent), JS_ARG_STR(&child));
|
||||
JS_VALUE_PARSE_ARGS_OR_RETURN(mjs, &js_storage_2_str_args, &parent, &child);
|
||||
Storage* storage = JS_GET_CONTEXT(mjs);
|
||||
mjs_return(mjs, mjs_mk_boolean(mjs, storage_common_is_subdir(storage, parent, child)));
|
||||
}
|
||||
|
||||
// ---=== module ctor & dtor ===---
|
||||
// ==================
|
||||
// Module ctor & dtor
|
||||
// ==================
|
||||
|
||||
static void* js_storage_create(struct mjs* mjs, mjs_val_t* object, JsModules* modules) {
|
||||
UNUSED(modules);
|
||||
@@ -363,7 +428,9 @@ static void js_storage_destroy(void* data) {
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
}
|
||||
|
||||
// ---=== boilerplate ===---
|
||||
// ===========
|
||||
// Boilerplate
|
||||
// ===========
|
||||
|
||||
static const JsModuleDescriptor js_storage_desc = {
|
||||
"storage",
|
||||
|
||||
Reference in New Issue
Block a user