Skip to content

Commit

Permalink
js modules updates 2
Browse files Browse the repository at this point in the history
by Willy-JL
  • Loading branch information
xMasterX committed Mar 23, 2024
1 parent 385c3c1 commit aaa7c81
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 19 deletions.
16 changes: 11 additions & 5 deletions applications/system/js_app/examples/apps/Scripts/textbox.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
let textbox = require("textbox");

// Set config before setting text
// You should set config before adding text
// Focus (start / end), Font (text / hex)
textbox.setConfig("end", "text");

let text = "Example dynamic updating textbox\n";
textbox.setText(text);
// Can make sure it's empty before showing, in case of reusing in same script
// (Closing textbox already empties the text, but maybe you added more in a loop for example)
textbox.emptyText();

// Add default text
textbox.addText("Example dynamic updating textbox\n");

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

let i = 0;
while (textbox.isOpen() && i < 20) {
print("console", i++);
text += "textbox " + to_string(i) + "\n";
textbox.setText(text);

// Add text to textbox buffer
textbox.addText("textbox " + to_string(i) + "\n");

delay(500);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@ while (1) {
let data_view = Uint8Array(rx_data);
print("0x" + to_hex_string(data_view[0]));
}
}
}

// There's also serial.end(), so you can serial.setup() again in same script
// You can also use serial.readAny(timeout), will avoid starving your loop with single byte reads
1 change: 1 addition & 0 deletions applications/system/js_app/modules/js_badusb.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ static void js_badusb_quit_free(JsBadusbInst* badusb) {
if(badusb->usb_if_prev) {
furi_hal_hid_kb_release_all();
furi_check(furi_hal_usb_set_config(badusb->usb_if_prev, NULL));
badusb->usb_if_prev = NULL;
}
if(badusb->hid_cfg) {
free(badusb->hid_cfg);
Expand Down
98 changes: 89 additions & 9 deletions applications/system/js_app/modules/js_serial.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <core/common_defines.h>
#include <expansion/expansion.h>
#include <furi_hal.h>
#include "../js_modules.h"
#include <m-array.h>
Expand Down Expand Up @@ -88,14 +89,49 @@ static void js_serial_setup(struct mjs* mjs) {
return;
}

serial->rx_stream = furi_stream_buffer_alloc(RX_BUF_LEN, 1);
expansion_disable(furi_record_open(RECORD_EXPANSION));
furi_record_close(RECORD_EXPANSION);

serial->serial_handle = furi_hal_serial_control_acquire(serial_id);
if(serial->serial_handle) {
serial->rx_stream = furi_stream_buffer_alloc(RX_BUF_LEN, 1);
furi_hal_serial_init(serial->serial_handle, baudrate);
furi_hal_serial_async_rx_start(
serial->serial_handle, js_serial_on_async_rx, serial, false);
serial->setup_done = true;
} else {
expansion_enable(furi_record_open(RECORD_EXPANSION));
furi_record_close(RECORD_EXPANSION);
}
}

static void js_serial_deinit(JsSerialInst* js_serial) {
if(js_serial->setup_done) {
furi_hal_serial_async_rx_stop(js_serial->serial_handle);
furi_hal_serial_deinit(js_serial->serial_handle);
furi_hal_serial_control_release(js_serial->serial_handle);
js_serial->serial_handle = NULL;
furi_stream_buffer_free(js_serial->rx_stream);

expansion_enable(furi_record_open(RECORD_EXPANSION));
furi_record_close(RECORD_EXPANSION);

js_serial->setup_done = false;
}
}

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);
furi_assert(serial);

if(!serial->setup_done) {
mjs_prepend_errorf(mjs, MJS_INTERNAL_ERROR, "Serial is not configured");
mjs_return(mjs, MJS_UNDEFINED);
return;
}

js_serial_deinit(serial);
}

static void js_serial_write(struct mjs* mjs) {
Expand Down Expand Up @@ -345,6 +381,55 @@ static void js_serial_read_bytes(struct mjs* mjs) {
free(read_buf);
}

static char* js_serial_receive_any(JsSerialInst* serial, size_t* len, uint32_t timeout) {
uint32_t flags = ThreadEventCustomDataRx;
if(furi_stream_buffer_is_empty(serial->rx_stream)) {
flags = js_flags_wait(serial->mjs, ThreadEventCustomDataRx, timeout);
}
if(flags & ThreadEventCustomDataRx) { // New data received
*len = furi_stream_buffer_bytes_available(serial->rx_stream);
if(!*len) return NULL;
char* buf = malloc(*len);
furi_stream_buffer_receive(serial->rx_stream, buf, *len, 0);
return buf;
}
return NULL;
}

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);
furi_assert(serial);
if(!serial->setup_done) {
mjs_prepend_errorf(mjs, MJS_INTERNAL_ERROR, "Serial is not configured");
mjs_return(mjs, MJS_UNDEFINED);
return;
}

uint32_t timeout = FuriWaitForever;

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

size_t bytes_read = 0;
char* read_buf = js_serial_receive_any(serial, &bytes_read, timeout);

mjs_val_t return_obj = MJS_UNDEFINED;
if(bytes_read > 0 && read_buf) {
return_obj = mjs_mk_string(mjs, read_buf, bytes_read, true);
}
mjs_return(mjs, return_obj);
free(read_buf);
}

static bool
js_serial_expect_parse_string(struct mjs* mjs, mjs_val_t arg, PatternArray_t patterns) {
size_t str_len = 0;
Expand Down Expand Up @@ -578,10 +663,12 @@ static void* js_serial_create(struct mjs* mjs, mjs_val_t* object) {
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));
*object = serial_obj;

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

static void js_serial_destroy(void* inst) {
JsSerialInst* js_serial = inst;
if(js_serial->setup_done) {
furi_hal_serial_async_rx_stop(js_serial->serial_handle);
furi_hal_serial_deinit(js_serial->serial_handle);
furi_hal_serial_control_release(js_serial->serial_handle);
js_serial->serial_handle = NULL;
}

furi_stream_buffer_free(js_serial->rx_stream);
js_serial_deinit(js_serial);
free(js_serial);
}

Expand Down
32 changes: 28 additions & 4 deletions applications/system/js_app/modules/js_textbox.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ typedef struct {
TextBox* text_box;
ViewDispatcher* view_dispatcher;
FuriThread* thread;
FuriString* text;
} JsTextboxInst;

static JsTextboxInst* get_this_ctx(struct mjs* mjs) {
Expand Down Expand Up @@ -74,18 +75,37 @@ static void js_textbox_set_config(struct mjs* mjs) {
mjs_return(mjs, MJS_UNDEFINED);
}

static void js_textbox_set_text(struct mjs* mjs) {
static void js_textbox_add_text(struct mjs* mjs) {
JsTextboxInst* textbox = get_this_ctx(mjs);
if(!check_arg_count(mjs, 1)) return;

mjs_val_t text_arg = mjs_arg(mjs, 0);
const char* text = mjs_get_string(mjs, &text_arg, NULL);
size_t text_len = 0;
const char* text = mjs_get_string(mjs, &text_arg, &text_len);
if(!text) {
ret_bad_args(mjs, "Text must be a string");
return;
}

text_box_set_text(textbox->text_box, text);
size_t new_len = furi_string_size(textbox->text) + text_len;
if(new_len >= 4096) {
furi_string_right(textbox->text, new_len / 2);
}

furi_string_cat(textbox->text, text);

text_box_set_text(textbox->text_box, furi_string_get_cstr(textbox->text));

mjs_return(mjs, MJS_UNDEFINED);
}

static void js_textbox_empty_text(struct mjs* mjs) {
JsTextboxInst* textbox = get_this_ctx(mjs);
if(!check_arg_count(mjs, 0)) return;

furi_string_reset(textbox->text);

text_box_set_text(textbox->text_box, furi_string_get_cstr(textbox->text));

mjs_return(mjs, MJS_UNDEFINED);
}
Expand All @@ -109,6 +129,7 @@ static void textbox_deinit(void* context) {
furi_record_close(RECORD_GUI);

text_box_reset(textbox->text_box);
furi_string_reset(textbox->text);
}

static void textbox_callback(void* context, uint32_t arg) {
Expand Down Expand Up @@ -166,11 +187,13 @@ static void* js_textbox_create(struct mjs* mjs, mjs_val_t* object) {
mjs_val_t textbox_obj = mjs_mk_object(mjs);
mjs_set(mjs, textbox_obj, INST_PROP_NAME, ~0, mjs_mk_foreign(mjs, textbox));
mjs_set(mjs, textbox_obj, "setConfig", ~0, MJS_MK_FN(js_textbox_set_config));
mjs_set(mjs, textbox_obj, "setText", ~0, MJS_MK_FN(js_textbox_set_text));
mjs_set(mjs, textbox_obj, "addText", ~0, MJS_MK_FN(js_textbox_add_text));
mjs_set(mjs, textbox_obj, "emptyText", ~0, MJS_MK_FN(js_textbox_empty_text));
mjs_set(mjs, textbox_obj, "isOpen", ~0, MJS_MK_FN(js_textbox_is_open));
mjs_set(mjs, textbox_obj, "show", ~0, MJS_MK_FN(js_textbox_show));
mjs_set(mjs, textbox_obj, "close", ~0, MJS_MK_FN(js_textbox_close));
textbox->text_box = text_box_alloc();
textbox->text = furi_string_alloc();
*object = textbox_obj;
return textbox;
}
Expand All @@ -182,6 +205,7 @@ static void js_textbox_destroy(void* inst) {
textbox_deinit(textbox);
}
text_box_free(textbox->text_box);
furi_string_free(textbox->text);
free(textbox);
}

Expand Down

0 comments on commit aaa7c81

Please sign in to comment.