[FL-3963] Move JS modules to new arg parser (#4139)

* js: value destructuring and tests

* js: temporary fix to see size impact

* js_val: reduce code size 1

* i may be stupid.

* test: js_value args

* Revert "js: temporary fix to see size impact"

This reverts commit f51d726dbafc4300d3552020de1c3b8f9ecd3ac1.

* pvs: silence warnings

* style: formatting

* pvs: silence warnings?

* pvs: silence warnings??

* js_value: redesign declaration types for less code

* js: temporary fix to see size impact

* style: formatting

* pvs: fix helpful warnings

* js_value: reduce .rodata size

* pvs: fix helpful warning

* js_value: reduce code size 1

* fix build error

* style: format

* Revert "js: temporary fix to see size impact"

This reverts commit d6a46f01794132e882e03fd273dec24386a4f8ba.

* style: format

* js: move to new arg parser

* style: format

---------

Co-authored-by: hedger <hedger@users.noreply.github.com>
This commit is contained in:
Anna Antonenko
2025-04-05 03:17:30 +04:00
committed by GitHub
parent 7192c9e68b
commit dac1457f0a
13 changed files with 525 additions and 620 deletions

View File

@@ -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 = {

View File

@@ -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);

View File

@@ -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;
}