Skip to content

Commit aaa7c81

Browse files
committed
js modules updates 2
by Willy-JL
1 parent 385c3c1 commit aaa7c81

File tree

5 files changed

+133
-19
lines changed

5 files changed

+133
-19
lines changed

applications/system/js_app/examples/apps/Scripts/textbox.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
11
let textbox = require("textbox");
22

3-
// Set config before setting text
3+
// You should set config before adding text
44
// Focus (start / end), Font (text / hex)
55
textbox.setConfig("end", "text");
66

7-
let text = "Example dynamic updating textbox\n";
8-
textbox.setText(text);
7+
// Can make sure it's empty before showing, in case of reusing in same script
8+
// (Closing textbox already empties the text, but maybe you added more in a loop for example)
9+
textbox.emptyText();
10+
11+
// Add default text
12+
textbox.addText("Example dynamic updating textbox\n");
913

1014
// Non-blocking, can keep updating text after, can close in JS or in GUI
1115
textbox.show();
1216

1317
let i = 0;
1418
while (textbox.isOpen() && i < 20) {
1519
print("console", i++);
16-
text += "textbox " + to_string(i) + "\n";
17-
textbox.setText(text);
20+
21+
// Add text to textbox buffer
22+
textbox.addText("textbox " + to_string(i) + "\n");
23+
1824
delay(500);
1925
}
2026

applications/system/js_app/examples/apps/Scripts/uart_echo.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,7 @@ while (1) {
88
let data_view = Uint8Array(rx_data);
99
print("0x" + to_hex_string(data_view[0]));
1010
}
11-
}
11+
}
12+
13+
// There's also serial.end(), so you can serial.setup() again in same script
14+
// You can also use serial.readAny(timeout), will avoid starving your loop with single byte reads

applications/system/js_app/modules/js_badusb.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ static void js_badusb_quit_free(JsBadusbInst* badusb) {
8181
if(badusb->usb_if_prev) {
8282
furi_hal_hid_kb_release_all();
8383
furi_check(furi_hal_usb_set_config(badusb->usb_if_prev, NULL));
84+
badusb->usb_if_prev = NULL;
8485
}
8586
if(badusb->hid_cfg) {
8687
free(badusb->hid_cfg);

applications/system/js_app/modules/js_serial.c

Lines changed: 89 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <core/common_defines.h>
2+
#include <expansion/expansion.h>
23
#include <furi_hal.h>
34
#include "../js_modules.h"
45
#include <m-array.h>
@@ -88,14 +89,49 @@ static void js_serial_setup(struct mjs* mjs) {
8889
return;
8990
}
9091

91-
serial->rx_stream = furi_stream_buffer_alloc(RX_BUF_LEN, 1);
92+
expansion_disable(furi_record_open(RECORD_EXPANSION));
93+
furi_record_close(RECORD_EXPANSION);
94+
9295
serial->serial_handle = furi_hal_serial_control_acquire(serial_id);
9396
if(serial->serial_handle) {
97+
serial->rx_stream = furi_stream_buffer_alloc(RX_BUF_LEN, 1);
9498
furi_hal_serial_init(serial->serial_handle, baudrate);
9599
furi_hal_serial_async_rx_start(
96100
serial->serial_handle, js_serial_on_async_rx, serial, false);
97101
serial->setup_done = true;
102+
} else {
103+
expansion_enable(furi_record_open(RECORD_EXPANSION));
104+
furi_record_close(RECORD_EXPANSION);
105+
}
106+
}
107+
108+
static void js_serial_deinit(JsSerialInst* js_serial) {
109+
if(js_serial->setup_done) {
110+
furi_hal_serial_async_rx_stop(js_serial->serial_handle);
111+
furi_hal_serial_deinit(js_serial->serial_handle);
112+
furi_hal_serial_control_release(js_serial->serial_handle);
113+
js_serial->serial_handle = NULL;
114+
furi_stream_buffer_free(js_serial->rx_stream);
115+
116+
expansion_enable(furi_record_open(RECORD_EXPANSION));
117+
furi_record_close(RECORD_EXPANSION);
118+
119+
js_serial->setup_done = false;
120+
}
121+
}
122+
123+
static void js_serial_end(struct mjs* mjs) {
124+
mjs_val_t obj_inst = mjs_get(mjs, mjs_get_this(mjs), INST_PROP_NAME, ~0);
125+
JsSerialInst* serial = mjs_get_ptr(mjs, obj_inst);
126+
furi_assert(serial);
127+
128+
if(!serial->setup_done) {
129+
mjs_prepend_errorf(mjs, MJS_INTERNAL_ERROR, "Serial is not configured");
130+
mjs_return(mjs, MJS_UNDEFINED);
131+
return;
98132
}
133+
134+
js_serial_deinit(serial);
99135
}
100136

101137
static void js_serial_write(struct mjs* mjs) {
@@ -345,6 +381,55 @@ static void js_serial_read_bytes(struct mjs* mjs) {
345381
free(read_buf);
346382
}
347383

384+
static char* js_serial_receive_any(JsSerialInst* serial, size_t* len, uint32_t timeout) {
385+
uint32_t flags = ThreadEventCustomDataRx;
386+
if(furi_stream_buffer_is_empty(serial->rx_stream)) {
387+
flags = js_flags_wait(serial->mjs, ThreadEventCustomDataRx, timeout);
388+
}
389+
if(flags & ThreadEventCustomDataRx) { // New data received
390+
*len = furi_stream_buffer_bytes_available(serial->rx_stream);
391+
if(!*len) return NULL;
392+
char* buf = malloc(*len);
393+
furi_stream_buffer_receive(serial->rx_stream, buf, *len, 0);
394+
return buf;
395+
}
396+
return NULL;
397+
}
398+
399+
static void js_serial_read_any(struct mjs* mjs) {
400+
mjs_val_t obj_inst = mjs_get(mjs, mjs_get_this(mjs), INST_PROP_NAME, ~0);
401+
JsSerialInst* serial = mjs_get_ptr(mjs, obj_inst);
402+
furi_assert(serial);
403+
if(!serial->setup_done) {
404+
mjs_prepend_errorf(mjs, MJS_INTERNAL_ERROR, "Serial is not configured");
405+
mjs_return(mjs, MJS_UNDEFINED);
406+
return;
407+
}
408+
409+
uint32_t timeout = FuriWaitForever;
410+
411+
do {
412+
size_t num_args = mjs_nargs(mjs);
413+
if(num_args == 1) {
414+
mjs_val_t timeout_arg = mjs_arg(mjs, 0);
415+
if(!mjs_is_number(timeout_arg)) {
416+
break;
417+
}
418+
timeout = mjs_get_int32(mjs, timeout_arg);
419+
}
420+
} while(0);
421+
422+
size_t bytes_read = 0;
423+
char* read_buf = js_serial_receive_any(serial, &bytes_read, timeout);
424+
425+
mjs_val_t return_obj = MJS_UNDEFINED;
426+
if(bytes_read > 0 && read_buf) {
427+
return_obj = mjs_mk_string(mjs, read_buf, bytes_read, true);
428+
}
429+
mjs_return(mjs, return_obj);
430+
free(read_buf);
431+
}
432+
348433
static bool
349434
js_serial_expect_parse_string(struct mjs* mjs, mjs_val_t arg, PatternArray_t patterns) {
350435
size_t str_len = 0;
@@ -578,10 +663,12 @@ static void* js_serial_create(struct mjs* mjs, mjs_val_t* object) {
578663
mjs_val_t serial_obj = mjs_mk_object(mjs);
579664
mjs_set(mjs, serial_obj, INST_PROP_NAME, ~0, mjs_mk_foreign(mjs, js_serial));
580665
mjs_set(mjs, serial_obj, "setup", ~0, MJS_MK_FN(js_serial_setup));
666+
mjs_set(mjs, serial_obj, "end", ~0, MJS_MK_FN(js_serial_end));
581667
mjs_set(mjs, serial_obj, "write", ~0, MJS_MK_FN(js_serial_write));
582668
mjs_set(mjs, serial_obj, "read", ~0, MJS_MK_FN(js_serial_read));
583669
mjs_set(mjs, serial_obj, "readln", ~0, MJS_MK_FN(js_serial_readln));
584670
mjs_set(mjs, serial_obj, "readBytes", ~0, MJS_MK_FN(js_serial_read_bytes));
671+
mjs_set(mjs, serial_obj, "readAny", ~0, MJS_MK_FN(js_serial_read_any));
585672
mjs_set(mjs, serial_obj, "expect", ~0, MJS_MK_FN(js_serial_expect));
586673
*object = serial_obj;
587674

@@ -590,14 +677,7 @@ static void* js_serial_create(struct mjs* mjs, mjs_val_t* object) {
590677

591678
static void js_serial_destroy(void* inst) {
592679
JsSerialInst* js_serial = inst;
593-
if(js_serial->setup_done) {
594-
furi_hal_serial_async_rx_stop(js_serial->serial_handle);
595-
furi_hal_serial_deinit(js_serial->serial_handle);
596-
furi_hal_serial_control_release(js_serial->serial_handle);
597-
js_serial->serial_handle = NULL;
598-
}
599-
600-
furi_stream_buffer_free(js_serial->rx_stream);
680+
js_serial_deinit(js_serial);
601681
free(js_serial);
602682
}
603683

applications/system/js_app/modules/js_textbox.c

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ typedef struct {
77
TextBox* text_box;
88
ViewDispatcher* view_dispatcher;
99
FuriThread* thread;
10+
FuriString* text;
1011
} JsTextboxInst;
1112

1213
static JsTextboxInst* get_this_ctx(struct mjs* mjs) {
@@ -74,18 +75,37 @@ static void js_textbox_set_config(struct mjs* mjs) {
7475
mjs_return(mjs, MJS_UNDEFINED);
7576
}
7677

77-
static void js_textbox_set_text(struct mjs* mjs) {
78+
static void js_textbox_add_text(struct mjs* mjs) {
7879
JsTextboxInst* textbox = get_this_ctx(mjs);
7980
if(!check_arg_count(mjs, 1)) return;
8081

8182
mjs_val_t text_arg = mjs_arg(mjs, 0);
82-
const char* text = mjs_get_string(mjs, &text_arg, NULL);
83+
size_t text_len = 0;
84+
const char* text = mjs_get_string(mjs, &text_arg, &text_len);
8385
if(!text) {
8486
ret_bad_args(mjs, "Text must be a string");
8587
return;
8688
}
8789

88-
text_box_set_text(textbox->text_box, text);
90+
size_t new_len = furi_string_size(textbox->text) + text_len;
91+
if(new_len >= 4096) {
92+
furi_string_right(textbox->text, new_len / 2);
93+
}
94+
95+
furi_string_cat(textbox->text, text);
96+
97+
text_box_set_text(textbox->text_box, furi_string_get_cstr(textbox->text));
98+
99+
mjs_return(mjs, MJS_UNDEFINED);
100+
}
101+
102+
static void js_textbox_empty_text(struct mjs* mjs) {
103+
JsTextboxInst* textbox = get_this_ctx(mjs);
104+
if(!check_arg_count(mjs, 0)) return;
105+
106+
furi_string_reset(textbox->text);
107+
108+
text_box_set_text(textbox->text_box, furi_string_get_cstr(textbox->text));
89109

90110
mjs_return(mjs, MJS_UNDEFINED);
91111
}
@@ -109,6 +129,7 @@ static void textbox_deinit(void* context) {
109129
furi_record_close(RECORD_GUI);
110130

111131
text_box_reset(textbox->text_box);
132+
furi_string_reset(textbox->text);
112133
}
113134

114135
static void textbox_callback(void* context, uint32_t arg) {
@@ -166,11 +187,13 @@ static void* js_textbox_create(struct mjs* mjs, mjs_val_t* object) {
166187
mjs_val_t textbox_obj = mjs_mk_object(mjs);
167188
mjs_set(mjs, textbox_obj, INST_PROP_NAME, ~0, mjs_mk_foreign(mjs, textbox));
168189
mjs_set(mjs, textbox_obj, "setConfig", ~0, MJS_MK_FN(js_textbox_set_config));
169-
mjs_set(mjs, textbox_obj, "setText", ~0, MJS_MK_FN(js_textbox_set_text));
190+
mjs_set(mjs, textbox_obj, "addText", ~0, MJS_MK_FN(js_textbox_add_text));
191+
mjs_set(mjs, textbox_obj, "emptyText", ~0, MJS_MK_FN(js_textbox_empty_text));
170192
mjs_set(mjs, textbox_obj, "isOpen", ~0, MJS_MK_FN(js_textbox_is_open));
171193
mjs_set(mjs, textbox_obj, "show", ~0, MJS_MK_FN(js_textbox_show));
172194
mjs_set(mjs, textbox_obj, "close", ~0, MJS_MK_FN(js_textbox_close));
173195
textbox->text_box = text_box_alloc();
196+
textbox->text = furi_string_alloc();
174197
*object = textbox_obj;
175198
return textbox;
176199
}
@@ -182,6 +205,7 @@ static void js_textbox_destroy(void* inst) {
182205
textbox_deinit(textbox);
183206
}
184207
text_box_free(textbox->text_box);
208+
furi_string_free(textbox->text);
185209
free(textbox);
186210
}
187211

0 commit comments

Comments
 (0)