mirror of https://github.com/arendst/Tasmota.git
Berry C mapping moved to a separate ``berry_mapping`` library
This commit is contained in:
parent
394ae49613
commit
26a7fad65b
|
@ -893,6 +893,7 @@ All notable changes to this project will be documented in this file.
|
|||
|
||||
### Changed
|
||||
- Triple-mode TLS via configuration in a single firmware (TLS AWS IoT, Letsencrypt and No-TLS)
|
||||
- Berry C mapping moved to a separate ``berry_mapping`` library
|
||||
|
||||
### Fixed
|
||||
- ESP32 PWM range
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#ifdef USE_LVGL
|
||||
|
||||
#include "lvgl.h"
|
||||
#include "be_lvgl.h"
|
||||
#include "be_mapping.h"
|
||||
|
||||
/********************************************************************
|
||||
* Generated code, don't edit
|
||||
|
|
|
@ -249,7 +249,7 @@ be_local_closure(LVGL_glob_register_obj, /* name */
|
|||
be_local_closure(LVGL_glob_gen_cb, /* name */
|
||||
be_nested_proto(
|
||||
8, /* nstack */
|
||||
5, /* argc */
|
||||
4, /* argc */
|
||||
0, /* varg */
|
||||
0, /* has upvals */
|
||||
NULL, /* no upvals */
|
||||
|
@ -281,56 +281,57 @@ be_local_closure(LVGL_glob_gen_cb, /* name */
|
|||
),
|
||||
}),
|
||||
1, /* has constants */
|
||||
( &(const bvalue[ 8]) { /* constants */
|
||||
/* K0 */ be_nested_str(lv_event_cb),
|
||||
/* K1 */ be_nested_str(cb_event_closure),
|
||||
/* K2 */ be_nested_str(event_cb),
|
||||
/* K3 */ be_nested_str(tasmota),
|
||||
( &(const bvalue[ 9]) { /* constants */
|
||||
/* K0 */ be_nested_str(cb),
|
||||
/* K1 */ be_nested_str(lv_event_cb),
|
||||
/* K2 */ be_nested_str(cb_event_closure),
|
||||
/* K3 */ be_nested_str(event_cb),
|
||||
/* K4 */ be_nested_str(gen_cb),
|
||||
/* K5 */ be_nested_str(register_obj),
|
||||
/* K6 */ be_nested_str(null_cb),
|
||||
/* K7 */ be_nested_str(cb_do_nothing),
|
||||
/* K6 */ be_nested_str(_p),
|
||||
/* K7 */ be_nested_str(null_cb),
|
||||
/* K8 */ be_nested_str(cb_do_nothing),
|
||||
}),
|
||||
&be_const_str_gen_cb,
|
||||
&be_const_str_solidified,
|
||||
( &(const binstruction[41]) { /* code */
|
||||
0x1C140300, // 0000 EQ R5 R1 K0
|
||||
0x78160018, // 0001 JMPF R5 #001B
|
||||
0x88140101, // 0002 GETMBR R5 R0 K1
|
||||
0x4C180000, // 0003 LDNIL R6
|
||||
0x1C140A06, // 0004 EQ R5 R5 R6
|
||||
0x78160002, // 0005 JMPF R5 #0009
|
||||
0x60140013, // 0006 GETGBL R5 G19
|
||||
0x7C140000, // 0007 CALL R5 0
|
||||
0x90020205, // 0008 SETMBR R0 K1 R5
|
||||
0x88140102, // 0009 GETMBR R5 R0 K2
|
||||
0x4C180000, // 000A LDNIL R6
|
||||
0x1C140A06, // 000B EQ R5 R5 R6
|
||||
0x78160004, // 000C JMPF R5 #0012
|
||||
0xB8160600, // 000D GETNGBL R5 K3
|
||||
0x8C140B04, // 000E GETMET R5 R5 K4
|
||||
0xA4120000, // 0000 IMPORT R4 K0
|
||||
0x1C140701, // 0001 EQ R5 R3 K1
|
||||
0x78160018, // 0002 JMPF R5 #001C
|
||||
0x88140102, // 0003 GETMBR R5 R0 K2
|
||||
0x4C180000, // 0004 LDNIL R6
|
||||
0x1C140A06, // 0005 EQ R5 R5 R6
|
||||
0x78160002, // 0006 JMPF R5 #000A
|
||||
0x60140013, // 0007 GETGBL R5 G19
|
||||
0x7C140000, // 0008 CALL R5 0
|
||||
0x90020405, // 0009 SETMBR R0 K2 R5
|
||||
0x88140103, // 000A GETMBR R5 R0 K3
|
||||
0x4C180000, // 000B LDNIL R6
|
||||
0x1C140A06, // 000C EQ R5 R5 R6
|
||||
0x78160003, // 000D JMPF R5 #0012
|
||||
0x8C140904, // 000E GETMET R5 R4 K4
|
||||
0x841C0000, // 000F CLOSURE R7 P0
|
||||
0x7C140400, // 0010 CALL R5 2
|
||||
0x90020405, // 0011 SETMBR R0 K2 R5
|
||||
0x90020605, // 0011 SETMBR R0 K3 R5
|
||||
0x8C140105, // 0012 GETMET R5 R0 K5
|
||||
0x5C1C0600, // 0013 MOVE R7 R3
|
||||
0x5C1C0400, // 0013 MOVE R7 R2
|
||||
0x7C140400, // 0014 CALL R5 2
|
||||
0x88140101, // 0015 GETMBR R5 R0 K1
|
||||
0x98140802, // 0016 SETIDX R5 R4 R2
|
||||
0x88140102, // 0017 GETMBR R5 R0 K2
|
||||
0xA0000000, // 0018 CLOSE R0
|
||||
0x80040A00, // 0019 RET 1 R5
|
||||
0x7002000B, // 001A JMP #0027
|
||||
0x88140106, // 001B GETMBR R5 R0 K6
|
||||
0x4C180000, // 001C LDNIL R6
|
||||
0x1C140A06, // 001D EQ R5 R5 R6
|
||||
0x78160004, // 001E JMPF R5 #0024
|
||||
0xB8160600, // 001F GETNGBL R5 K3
|
||||
0x8C140B04, // 0020 GETMET R5 R5 K4
|
||||
0x881C0107, // 0021 GETMBR R7 R0 K7
|
||||
0x88140506, // 0015 GETMBR R5 R2 K6
|
||||
0x88180102, // 0016 GETMBR R6 R0 K2
|
||||
0x98180A01, // 0017 SETIDX R6 R5 R1
|
||||
0x88140103, // 0018 GETMBR R5 R0 K3
|
||||
0xA0000000, // 0019 CLOSE R0
|
||||
0x80040A00, // 001A RET 1 R5
|
||||
0x7002000A, // 001B JMP #0027
|
||||
0x88140107, // 001C GETMBR R5 R0 K7
|
||||
0x4C180000, // 001D LDNIL R6
|
||||
0x1C140A06, // 001E EQ R5 R5 R6
|
||||
0x78160003, // 001F JMPF R5 #0024
|
||||
0x8C140904, // 0020 GETMET R5 R4 K4
|
||||
0x881C0108, // 0021 GETMBR R7 R0 K8
|
||||
0x7C140400, // 0022 CALL R5 2
|
||||
0x90020C05, // 0023 SETMBR R0 K6 R5
|
||||
0x88140106, // 0024 GETMBR R5 R0 K6
|
||||
0x90020E05, // 0023 SETMBR R0 K7 R5
|
||||
0x88140107, // 0024 GETMBR R5 R0 K7
|
||||
0xA0000000, // 0025 CLOSE R0
|
||||
0x80040A00, // 0026 RET 1 R5
|
||||
0xA0000000, // 0027 CLOSE R0
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#ifdef USE_LVGL
|
||||
|
||||
#include "lvgl.h"
|
||||
#include "be_lvgl.h"
|
||||
#include "be_mapping.h"
|
||||
#include "lv_theme_openhasp.h"
|
||||
|
||||
extern int lv0_member(bvm *vm); // resolve virtual members
|
||||
|
@ -34,7 +34,7 @@ static int lv_get_ver_res(void) {
|
|||
}
|
||||
|
||||
/* `lv` methods */
|
||||
const lvbe_call_c_t lv_func[] = {
|
||||
const be_ntv_func_def_t lv_func[] = {
|
||||
|
||||
{ "clamp_height", (void*) &lv_clamp_height, "i", "iiii" },
|
||||
{ "clamp_width", (void*) &lv_clamp_width, "i", "iiii" },
|
||||
|
@ -111,12 +111,7 @@ const size_t lv_func_size = sizeof(lv_func) / sizeof(lv_func[0]);
|
|||
|
||||
|
||||
|
||||
typedef struct be_constint_t {
|
||||
const char * name;
|
||||
int32_t value;
|
||||
} be_constint_t;
|
||||
|
||||
const be_constint_t lv0_constants[] = {
|
||||
const be_const_member_t lv0_constants[] = {
|
||||
|
||||
{ "ALIGN_BOTTOM_LEFT", LV_ALIGN_BOTTOM_LEFT },
|
||||
{ "ALIGN_BOTTOM_MID", LV_ALIGN_BOTTOM_MID },
|
||||
|
|
|
@ -44,20 +44,21 @@ class LVGL_glob
|
|||
f(obj, event)
|
||||
end
|
||||
|
||||
def gen_cb(name, f, obj, ptr)
|
||||
#print('>> gen_cb', name, obj, ptr)
|
||||
def gen_cb(f, obj, name)
|
||||
import cb
|
||||
# print('>> gen_cb', f, name, obj)
|
||||
# record the object, whatever the callback
|
||||
|
||||
if name == "lv_event_cb"
|
||||
if self.cb_event_closure == nil self.cb_event_closure = {} end
|
||||
if self.event_cb == nil self.event_cb = tasmota.gen_cb(/ event_ptr -> self.lvgl_event_dispatch(event_ptr)) end # encapsulate 'self' in closure
|
||||
if self.event_cb == nil self.event_cb = cb.gen_cb(/ event_ptr -> self.lvgl_event_dispatch(event_ptr)) end # encapsulate 'self' in closure
|
||||
|
||||
self.register_obj(obj)
|
||||
self.cb_event_closure[ptr] = f
|
||||
self.cb_event_closure[obj._p] = f
|
||||
return self.event_cb
|
||||
# elif name == "<other_cb>"
|
||||
else
|
||||
if self.null_cb == nil self.null_cb = tasmota.gen_cb(self.cb_do_nothing) end
|
||||
if self.null_cb == nil self.null_cb = cb.gen_cb(self.cb_do_nothing) end
|
||||
return self.null_cb
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
/********************************************************************
|
||||
* Tasmota LVGL Headers
|
||||
*******************************************************************/
|
||||
#ifndef __BE_LVGL_H__
|
||||
#define __BE_LVGL_H__
|
||||
|
||||
#include "be_constobj.h"
|
||||
|
||||
#ifdef USE_LVGL
|
||||
|
||||
#include "lvgl.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
// table of functions per class
|
||||
typedef struct lvbe_call_c_t {
|
||||
const char * name;
|
||||
void * func;
|
||||
const char * return_type;
|
||||
const char * arg_type;
|
||||
} lvbe_call_c_t;
|
||||
|
||||
// list of classes and function tables
|
||||
typedef struct lvbe_call_c_classes_t {
|
||||
const char * name;
|
||||
const bclass * cl;
|
||||
const lvbe_call_c_t * func_table;
|
||||
size_t size;
|
||||
} lvbe_call_c_classes_t;
|
||||
extern const lvbe_call_c_classes_t lv_classes[];
|
||||
extern const size_t lv_classes_size;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // USE_LVGL
|
||||
|
||||
#endif // __BE_LVGL_H__
|
|
@ -0,0 +1,406 @@
|
|||
/*********************************************************************************************\
|
||||
* Class wrappers for native objects
|
||||
*
|
||||
* These class are simple wrappers (containers) for a pointer of an external object.
|
||||
* The pointer is stored interanlly by the class.
|
||||
*
|
||||
* The constructor of this class must accept the first argument to be `comptr`,
|
||||
* in such case, the constructor must store the pointer.
|
||||
* The class is not supposed to free the object at `deinit` time.
|
||||
\*********************************************************************************************/
|
||||
|
||||
#include "be_mapping.h"
|
||||
#include "be_exec.h"
|
||||
#include <string.h>
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Create an object of `class_name` given an external poinrt `ptr`.
|
||||
*
|
||||
* Instanciates the class and calls `init()` with `ptr` wrapped in `comptr` as single arg.
|
||||
* Both arguments but nost bu NULL.
|
||||
*
|
||||
* On return, the created instance is top of stack.
|
||||
\*********************************************************************************************/
|
||||
void be_create_class_wrapper(bvm *vm, const char * class_name, void * ptr) {
|
||||
if (ptr == NULL) {
|
||||
be_throw(vm, BE_MALLOC_FAIL);
|
||||
}
|
||||
|
||||
be_getglobal(vm, class_name); // stack = class
|
||||
be_call(vm, 0); // instanciate, stack = instance
|
||||
be_getmember(vm, -1, "init"); // stack = instance, init_func
|
||||
be_pushvalue(vm, -2); // stack = instance, init_func, instance
|
||||
be_pushcomptr(vm, ptr); // stack = instance, init_func, instance, ptr
|
||||
be_call(vm, 2); // stack = instance, ret, instance, ptr
|
||||
be_pop(vm, 3); // stack = instance
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Find an object by global or composite name.
|
||||
*
|
||||
* I.e. `lv.lv_object` will check for a global called `lv` and a member `lv_object`
|
||||
*
|
||||
* Only supports one level of depth, meaning a class within a module.
|
||||
* Does not check the type of the object found.
|
||||
*
|
||||
* Arguments:
|
||||
* `name`: can be NULL, in such case considers the member as not found
|
||||
*
|
||||
* Case 1: (no dot in name) `lv_wifi_bars` will look for a global variable `lv_wifi_bars`
|
||||
* Case 2: (dot in name) `lvgl.lv_obj` will get global `lvgl` and look for `lv_obj` within this module
|
||||
*
|
||||
* Returns the number of elements pushed on the stack: 1 for module, 2 for instance method, 0 if not found
|
||||
\*********************************************************************************************/
|
||||
int be_find_global_or_module_member(bvm *vm, const char * name) {
|
||||
char *saveptr;
|
||||
|
||||
if (name == NULL) {
|
||||
be_pushnil(vm);
|
||||
return 0;
|
||||
}
|
||||
char name_buf[strlen(name)+1];
|
||||
strcpy(name_buf, name);
|
||||
|
||||
char * prefix = strtok_r(name_buf, ".", &saveptr);
|
||||
char * suffix = strtok_r(NULL, ".", &saveptr);
|
||||
if (suffix) {
|
||||
if (be_getglobal(vm, prefix)) {
|
||||
if (be_getmember(vm, -1, suffix)) {
|
||||
if (be_isinstance(vm, -2)) { // instance, so we need to push method + instance
|
||||
be_pushvalue(vm, -2);
|
||||
be_remove(vm, -3);
|
||||
return 2;
|
||||
} else { // not instane, so keep only the top object
|
||||
be_remove(vm, -2);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
be_pop(vm, 2);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
be_pop(vm, 1); // remove nil
|
||||
return 0;
|
||||
} else { // no suffix, get the global object
|
||||
if (be_getglobal(vm, prefix)) {
|
||||
return 1;
|
||||
}
|
||||
be_pop(vm, 1);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Automatically parse Berry stack and call the C function accordingly
|
||||
*
|
||||
* This function takes the n incoming arguments and pushes them as arguments
|
||||
* on the stack for the C function:
|
||||
* - be_int -> int32_t
|
||||
* - be_bool -> int32_t with value 0/1
|
||||
* - be_string -> const char *
|
||||
* - be_instance -> gets the member "_p" and pushes as void*
|
||||
*
|
||||
* This works because C silently ignores any unwanted arguments.
|
||||
* There is a strong requirements that all ints and pointers are 32 bits.
|
||||
* Float is not supported but could be added. Double cannot be supported because they are 64 bits
|
||||
*
|
||||
* Optional argument:
|
||||
* - return_type: the C function return value is int32_t and is converted to the
|
||||
* relevant Berry object depending on this char:
|
||||
* '' (default): nil, no value
|
||||
* 'i' be_int
|
||||
* 'b' be_bool
|
||||
* 's' be_str
|
||||
*
|
||||
* - arg_type: optionally check the types of input arguments, or throw an error
|
||||
* string of argument types, '+' marks optional arguments
|
||||
* '.' don't care
|
||||
* 'i' be_int
|
||||
* 'b' be_bool
|
||||
* 's' be_string
|
||||
* 'c' C callback
|
||||
* '-' ignore and don't send to C function
|
||||
* 'lv_obj' be_instance of type or subtype
|
||||
* '^lv_event_cb' callback of a named class - will call `_lvgl.gen_cb(arg_type, closure, self)` and expects a callback address in return
|
||||
*
|
||||
* Ex: "oii+s" takes 3 mandatory arguments (obj_instance, int, int) and an optional fourth one [,string]
|
||||
\*********************************************************************************************/
|
||||
// general form of lv_obj_t* function, up to 4 parameters
|
||||
// We can only send 32 bits arguments (no 64 bits nor double) and we expect pointers to be 32 bits
|
||||
|
||||
// read a single value at stack position idx, convert to int.
|
||||
// if object instance, get `_p` member and convert it recursively
|
||||
intptr_t be_convert_single_elt(bvm *vm, int idx, const char * arg_type, const char * gen_cb) {
|
||||
// berry_log_C("be_convert_single_elt(idx=%i, argtype='%s', gen_cb=%p", idx, arg_type, gen_cb);
|
||||
int ret = 0;
|
||||
char provided_type = 0;
|
||||
idx = be_absindex(vm, idx); // make sure we have an absolute index
|
||||
|
||||
// berry_log_C(">> 0 idx=%i arg_type=%s", idx, arg_type ? arg_type : "NULL");
|
||||
if (arg_type == NULL) { arg_type = "."; } // if no type provided, replace with wildchar
|
||||
size_t arg_type_len = strlen(arg_type);
|
||||
|
||||
// handle callbacks first, since a wrong parameter will always yield to a crash
|
||||
if (arg_type_len > 1 && arg_type[0] == '^') { // it is a callback
|
||||
arg_type++; // skip first character
|
||||
if (be_isclosure(vm, idx)) {
|
||||
ret = be_find_global_or_module_member(vm, gen_cb);
|
||||
if (ret) {
|
||||
be_remove(vm, -3); // stack contains method + instance
|
||||
be_pushvalue(vm, idx);
|
||||
be_pushvalue(vm, 1);
|
||||
be_pushstring(vm, arg_type);
|
||||
be_call(vm, 2 + ret);
|
||||
const void * func = be_tocomptr(vm, -(3 + ret));
|
||||
be_pop(vm, 3 + ret);
|
||||
|
||||
// berry_log_C("func=%p", func);
|
||||
return (int32_t) func;
|
||||
} else {
|
||||
be_raisef(vm, "type_error", "Can't find callback generator: %s", gen_cb);
|
||||
}
|
||||
} else {
|
||||
be_raise(vm, "type_error", "Closure expected for callback type");
|
||||
}
|
||||
}
|
||||
|
||||
// first convert the value to int32
|
||||
if (be_isint(vm, idx)) { ret = be_toint(vm, idx); provided_type = 'i'; }
|
||||
else if (be_isbool(vm, idx)) { ret = be_tobool(vm, idx); provided_type = 'b'; }
|
||||
else if (be_isstring(vm, idx)) { ret = (intptr_t) be_tostring(vm, idx); provided_type = 's'; }
|
||||
else if (be_iscomptr(vm, idx)) { ret = (intptr_t) be_tocomptr(vm, idx); provided_type = 'c'; }
|
||||
else if (be_isnil(vm, idx)) { ret = 0; provided_type = 'c'; }
|
||||
|
||||
// check if simple type was a match
|
||||
if (provided_type) {
|
||||
bbool type_ok = bfalse;
|
||||
type_ok = (arg_type[0] == '.'); // any type is accepted
|
||||
type_ok = type_ok || (arg_type[0] == provided_type); // or type is a match
|
||||
type_ok = type_ok || (ret == 0 && arg_type_len != 1); // or NULL is accepted for an instance
|
||||
|
||||
if (!type_ok) {
|
||||
be_raisef(vm, "type_error", "Unexpected argument type '%c', expected '%s'", provided_type, arg_type);
|
||||
}
|
||||
// berry_log_C("be_convert_single_elt provided type=%i", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// berry_log_C("be_convert_single_elt non simple type");
|
||||
// non-simple type
|
||||
if (be_isinstance(vm, idx)) {
|
||||
// check if the instance is a subclass of `bytes()``
|
||||
be_getbuiltin(vm, "bytes");
|
||||
if (be_isderived(vm, idx)) {
|
||||
be_pop(vm, 1);
|
||||
be_getmember(vm, idx, "_buffer");
|
||||
be_pushvalue(vm, idx);
|
||||
be_call(vm, 1);
|
||||
int32_t ret = (int32_t) be_tocomptr(vm, -2);
|
||||
be_pop(vm, 2);
|
||||
return ret;
|
||||
} else {
|
||||
be_pop(vm, 1);
|
||||
// we accept either `_p` or `.p` attribute to retrieve a pointer
|
||||
if (!be_getmember(vm, idx, "_p")) {
|
||||
be_pop(vm, 1); // remove `nil`
|
||||
be_getmember(vm, idx, ".p");
|
||||
}
|
||||
int32_t ret = be_convert_single_elt(vm, -1, NULL, NULL); // recurse
|
||||
be_pop(vm, 1);
|
||||
|
||||
if (arg_type_len > 1) {
|
||||
// Check type
|
||||
be_classof(vm, idx);
|
||||
int class_found = be_find_global_or_module_member(vm, arg_type);
|
||||
// Stack: class_of_idx, class_of_target (or nil)
|
||||
if (class_found) {
|
||||
if (!be_isderived(vm, -2)) {
|
||||
be_raisef(vm, "type_error", "Unexpected class type '%s', expected '%s'", be_classname(vm, idx), arg_type);
|
||||
}
|
||||
} else {
|
||||
be_raisef(vm, "value_error", "Unable to find class '%s' (%d)", arg_type, arg_type_len);
|
||||
}
|
||||
be_pop(vm, 2);
|
||||
} else if (arg_type[0] != '.') {
|
||||
be_raisef(vm, "value_error", "Unexpected instance type '%s', expected '%s'", be_classname(vm, idx), arg_type);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
be_raisef(vm, "value_error", "Unexpected '%s'", be_typename(vm, idx));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Calling any LVGL function with auto-mapping
|
||||
*
|
||||
\*********************************************************************************************/
|
||||
|
||||
// check input parameters, and create callbacks if needed
|
||||
// change values in place
|
||||
//
|
||||
// Format:
|
||||
// - either a lowercase character encoding for a simple type
|
||||
// - 'b': bool
|
||||
// - 'i': int (int32_t)
|
||||
// - 's': string (const char *)
|
||||
//
|
||||
// - a class name surroungded by parenthesis
|
||||
// - '(lv_button)' -> lv_button class or derived
|
||||
// - '[lv_event_cb]' -> callback type, still prefixed with '^' to mark that it is cb
|
||||
//
|
||||
void be_check_arg_type(bvm *vm, int arg_start, int argc, const char * arg_type, intptr_t p[8]) {
|
||||
bbool arg_type_check = (arg_type != NULL); // is type checking activated
|
||||
int32_t arg_idx = 0; // position in arg_type string
|
||||
char type_short_name[32];
|
||||
|
||||
uint32_t p_idx = 0; // index in p[], is incremented with each parameter except '-'
|
||||
for (uint32_t i = 0; i < argc; i++) {
|
||||
type_short_name[0] = 0; // clear string
|
||||
// extract individual type
|
||||
if (NULL != arg_type) {
|
||||
switch (arg_type[arg_idx]) {
|
||||
case '-':
|
||||
arg_idx++;
|
||||
continue; // ignore current parameter and advance
|
||||
case '.':
|
||||
case 'a'...'z':
|
||||
type_short_name[0] = arg_type[arg_idx];
|
||||
type_short_name[1] = 0;
|
||||
arg_idx++;
|
||||
break;
|
||||
case '(':
|
||||
case '^':
|
||||
{
|
||||
uint32_t prefix = 0;
|
||||
if (arg_type[arg_idx] == '^') {
|
||||
type_short_name[0] = '^';
|
||||
type_short_name[1] = 0;
|
||||
prefix = 1;
|
||||
}
|
||||
uint32_t offset = 0;
|
||||
arg_idx++;
|
||||
while (arg_type[arg_idx + offset] != ')' && arg_type[arg_idx + offset] != '^' && arg_type[arg_idx + offset] != 0 && offset+prefix+1 < sizeof(type_short_name)) {
|
||||
type_short_name[offset+prefix] = arg_type[arg_idx + offset];
|
||||
type_short_name[offset+prefix+1] = 0;
|
||||
offset++;
|
||||
}
|
||||
if (arg_type[arg_idx + offset] == 0) {
|
||||
arg_type = NULL; // no more parameters, stop iterations
|
||||
}
|
||||
arg_idx += offset + 1;
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
arg_type = NULL; // stop iterations
|
||||
break;
|
||||
}
|
||||
}
|
||||
// AddLog(LOG_LEVEL_INFO, ">> be_call_c_func arg %i, type %s", i, arg_type_check ? type_short_name : "<null>");
|
||||
p[p_idx++] = be_convert_single_elt(vm, i + arg_start, arg_type_check ? type_short_name : NULL, "_lvgl.gen_cb");
|
||||
}
|
||||
|
||||
// check if we are missing arguments
|
||||
if (arg_type != NULL && arg_type[arg_idx] != 0) {
|
||||
be_raisef(vm, "value_error", "Missing arguments, remaining type '%s'", &arg_type[arg_idx]);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Internal function
|
||||
//
|
||||
// Called for constructors, i.e. C function mapped to Berry `init()`
|
||||
//
|
||||
// Pre-conditions:
|
||||
// The instance must be at stack position `1` (default when calling `init()`)
|
||||
//
|
||||
// Arguments:
|
||||
// vm: point to Berry vm (as usual)
|
||||
// ptr: the C pointer for internal data (can be NULL), will be stored in an instance variable
|
||||
// name: name of instance variable to store the pointer as `comptr`.
|
||||
// If NULL, this function does nothing
|
||||
// the name can be prefixed with `+`, if so first char is ignored.
|
||||
// Ex: `+_p` stores in instance variable `_p`
|
||||
static void be_set_ctor_ptr(bvm *vm, void * ptr, const char *name) {
|
||||
if (name == NULL) return; // do nothing if no name of attribute
|
||||
if (name[0] == '+') { name++; } // skip prefix '^' if any
|
||||
if (strlen(name) == 0) return; // do nothing if name is empty
|
||||
|
||||
be_pushcomptr(vm, ptr);
|
||||
if (be_setmember(vm, 1, name)) {
|
||||
be_pop(vm, 1);
|
||||
} else {
|
||||
be_raisef(vm, "attribute_error", "Missing member '%s' in ctor", name);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Call a C function with auto-mapping
|
||||
*
|
||||
* Arguments:
|
||||
* vm: pointer to Berry vm (as ususal)
|
||||
* func: pointer to C function
|
||||
* return_type: how to convert the result into a Berry type
|
||||
* arg_type: string describing the optional and mandatory parameters
|
||||
*
|
||||
* Note: the C function mapping supports max 8 arguments and does not directly support
|
||||
* pointers to values (although it is possible to mimick with classes)
|
||||
\*********************************************************************************************/
|
||||
int be_call_c_func(bvm *vm, void * func, const char * return_type, const char * arg_type) {
|
||||
intptr_t p[8] = {0,0,0,0,0,0,0,0};
|
||||
int argc = be_top(vm); // Get the number of arguments
|
||||
|
||||
// the following describe the active payload for the C function (start and count)
|
||||
// this is because the `init()` constructor first arg is not passed to the C function
|
||||
int arg_start = 1; // start with standard values
|
||||
int arg_count = argc;
|
||||
|
||||
// check if we call a constructor, in this case we store the return type into the new object
|
||||
// check if we call a constructor with a comptr as first arg
|
||||
if (return_type && return_type[0] == '+') {
|
||||
if (argc > 1 && be_iscomptr(vm, 2)) {
|
||||
void * obj = be_tocomptr(vm, 2);
|
||||
be_set_ctor_ptr(vm, obj, return_type);
|
||||
be_return_nil(vm);
|
||||
} else {
|
||||
// we need to discard the first arg
|
||||
arg_start++;
|
||||
arg_count--;
|
||||
}
|
||||
}
|
||||
|
||||
fn_any_callable f = (fn_any_callable) func;
|
||||
be_check_arg_type(vm, arg_start, arg_count, arg_type, p);
|
||||
intptr_t ret = (*f)(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
|
||||
// berry_log_C("be_call_c_func '%s' -> '%s': (%i,%i,%i,%i,%i,%i) -> %i", return_type, arg_type, p[0], p[1], p[2], p[3], p[4], p[5], ret);
|
||||
|
||||
if ((return_type == NULL) || (strlen(return_type) == 0)) { be_return_nil(vm); } // does not return
|
||||
else if (return_type[0] == '+') {
|
||||
void * obj = (void*) ret;
|
||||
be_set_ctor_ptr(vm, obj, return_type);
|
||||
be_return_nil(vm);
|
||||
}
|
||||
else if (strlen(return_type) == 1) {
|
||||
switch (return_type[0]) {
|
||||
case '.': // fallback next
|
||||
case 'i': be_pushint(vm, ret); break;
|
||||
case 'b': be_pushbool(vm, ret); break;
|
||||
case 's': be_pushstring(vm, (const char*) ret); break;
|
||||
case 'c': be_pushint(vm, ret); break; // TODO missing 'c' general callback type
|
||||
default: be_raise(vm, "internal_error", "Unsupported return type"); break;
|
||||
}
|
||||
be_return(vm);
|
||||
} else { // class name
|
||||
be_find_global_or_module_member(vm, return_type);
|
||||
be_pushcomptr(vm, (void*) ret); // stack = class, ptr
|
||||
be_pushcomptr(vm, (void*) -1); // stack = class, ptr, -1
|
||||
be_call(vm, 2); // instanciate with 2 arguments, stack = instance, -1, ptr
|
||||
be_pop(vm, 2); // stack = instance
|
||||
be_return(vm);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*********************************************************************************************\
|
||||
* Add const virtual members to classes and modules from C static tables
|
||||
*
|
||||
* This allows to creates hundreds of constant members (integers, strings...)
|
||||
* stored in a C array instead of explicit berry members.
|
||||
*
|
||||
* It has the following advantages:
|
||||
* - consumes much less flash memory, especially with hundreds of members
|
||||
* - allows C preprocessor to compute the value at compile time (instead of pure numerical numbers)
|
||||
* - allows to compute pointer addresses to C structures
|
||||
*
|
||||
* Takes a pointer to be_const_member_t array and size
|
||||
* Returns true if a match was found. In such case the result is on Berry stack
|
||||
*
|
||||
* Encoding depend on prefix (which is skipped when matching names):
|
||||
* 1. `COLOR_WHITE` int value
|
||||
* 3. `$SYMBOL_OK"` string pointer
|
||||
* 4. `&seg7_font` comptr
|
||||
\*********************************************************************************************/
|
||||
|
||||
#include "be_mapping.h"
|
||||
#include "be_exec.h"
|
||||
#include <string.h>
|
||||
/*********************************************************************************************\
|
||||
* Takes a pointer to be_const_member_t array and size
|
||||
* Returns true if a match was found. In such case the result is on Berry stack
|
||||
*
|
||||
* Can be called directly by `member()` function, takes the name of the member from
|
||||
* berry stack at position 1.
|
||||
*
|
||||
* Encoding depend on prefix (which is skipped when matching names):
|
||||
* 1. `COLOR_WHITE` int value
|
||||
* 3. `$SYMBOL_OK"` string pointer
|
||||
* 4. `&seg7_font` comptr
|
||||
*
|
||||
* The array must be lexically sorted, but the sort function must ignore the prefix `$` or `&`
|
||||
\*********************************************************************************************/
|
||||
bbool be_const_member(bvm *vm, const be_const_member_t * definitions, size_t def_len) {
|
||||
int32_t argc = be_top(vm); // Get the number of arguments
|
||||
if (argc == 1 && be_isstring(vm, 1)) {
|
||||
const char * needle = be_tostring(vm, 1);
|
||||
int32_t idx;
|
||||
|
||||
idx = be_map_bin_search(needle, &definitions[0].name, sizeof(definitions[0]), def_len);
|
||||
if (idx >= 0) {
|
||||
// we did have a match
|
||||
const char * key = definitions[idx].name;
|
||||
switch (key[0]) {
|
||||
// switch depending on the first char of the key, indicating the type
|
||||
case '$': // string
|
||||
be_pushstring(vm, (const char*) definitions[idx].value);
|
||||
break;
|
||||
case '&': // native function
|
||||
be_pushntvfunction(vm, (bntvfunc) definitions[idx].value);
|
||||
break;
|
||||
default: // int
|
||||
be_pushint(vm, definitions[idx].value);
|
||||
break;
|
||||
}
|
||||
return btrue;
|
||||
}
|
||||
}
|
||||
return bfalse;
|
||||
}
|
|
@ -3,8 +3,64 @@
|
|||
#ifndef __BE_MAPPING__
|
||||
#define __BE_MAPPING__
|
||||
|
||||
// include this header to force compilation fo this module
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "berry.h"
|
||||
|
||||
// include this header to force compilation fo this module
|
||||
#define BE_MAX_CB 20 // max number of callbacks, each callback requires a distinct address
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Support for Berry int constants
|
||||
* as virtual members
|
||||
\*********************************************************************************************/
|
||||
|
||||
typedef intptr_t (*fn_any_callable)(intptr_t p0, intptr_t p1, intptr_t p2, intptr_t p3,
|
||||
intptr_t p4, intptr_t p5, intptr_t p6, intptr_t p7);
|
||||
|
||||
typedef struct be_const_member_t {
|
||||
const char * name;
|
||||
int value;
|
||||
} be_const_member_t;
|
||||
|
||||
// table of functions per class
|
||||
typedef struct be_ntv_func_def_t {
|
||||
const char * name;
|
||||
void * func;
|
||||
const char * return_type;
|
||||
const char * arg_type;
|
||||
} be_ntv_func_def_t;
|
||||
|
||||
struct bclass;
|
||||
// list of classes and function tables
|
||||
typedef struct be_ntv_class_def_t {
|
||||
const char * name;
|
||||
const struct bclass * cl;
|
||||
const be_ntv_func_def_t * func_table;
|
||||
size_t size;
|
||||
} be_ntv_class_def_t;
|
||||
|
||||
void be_raisef(bvm *vm, const char *except, const char *msg, ...);
|
||||
|
||||
extern void be_map_insert_int(bvm *vm, const char *key, bint value);
|
||||
extern void be_map_insert_bool(bvm *vm, const char *key, bbool value);
|
||||
extern void be_map_insert_real(bvm *vm, const char *key, breal value);
|
||||
extern void be_map_insert_str(bvm *vm, const char *key, const char *value);
|
||||
extern void be_map_insert_list_uint8(bvm *vm, const char *key, const uint8_t *value, size_t size);
|
||||
|
||||
extern int be_map_bin_search(const char * needle, const void * table, size_t elt_size, size_t total_elements);
|
||||
|
||||
extern void be_create_class_wrapper(bvm *vm, const char * class_name, void * ptr);
|
||||
extern int be_find_global_or_module_member(bvm *vm, const char * cl_name);
|
||||
|
||||
extern bbool be_const_member(bvm *vm, const be_const_member_t * definitions, size_t def_len);
|
||||
extern intptr_t be_convert_single_elt(bvm *vm, int idx, const char * arg_type, const char * gen_cb);
|
||||
extern void be_check_arg_type(bvm *vm, int arg_start, int argc, const char * arg_type, intptr_t p[8]);;
|
||||
extern int be_call_c_func(bvm *vm, void * func, const char * return_type, const char * arg_type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // __BE_MAPPING__
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
#include "be_mapping.h"
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Helper functions to create a map with single line calls
|
||||
\*********************************************************************************************/
|
||||
/* Insert an int to a key */
|
||||
void be_map_insert_int(bvm *vm, const char *key, bint value)
|
||||
{
|
||||
be_pushstring(vm, key);
|
||||
be_pushint(vm, value);
|
||||
be_data_insert(vm, -3);
|
||||
be_pop(vm, 2);
|
||||
}
|
||||
/* Insert an bbool to a key */
|
||||
void be_map_insert_bool(bvm *vm, const char *key, bbool value)
|
||||
{
|
||||
be_pushstring(vm, key);
|
||||
be_pushbool(vm, value);
|
||||
be_data_insert(vm, -3);
|
||||
be_pop(vm, 2);
|
||||
}
|
||||
/* Insert an real to a key */
|
||||
/* if value == NAN, ignore */
|
||||
void be_map_insert_real(bvm *vm, const char *key, breal value)
|
||||
{
|
||||
if (!isnan(value)) {
|
||||
be_pushstring(vm, key);
|
||||
be_pushreal(vm, value);
|
||||
be_data_insert(vm, -3);
|
||||
be_pop(vm, 2);
|
||||
}
|
||||
}
|
||||
/* Insert an C string to a key */
|
||||
void be_map_insert_str(bvm *vm, const char *key, const char *value)
|
||||
{
|
||||
be_pushstring(vm, key);
|
||||
be_pushstring(vm, value);
|
||||
be_data_insert(vm, -3);
|
||||
be_pop(vm, 2);
|
||||
}
|
||||
/* Insert list of bytes as individual integers to a key */
|
||||
void be_map_insert_list_uint8(bvm *vm, const char *key, const uint8_t *value, size_t size)
|
||||
{
|
||||
be_pushstring(vm, key);
|
||||
|
||||
be_newobject(vm, "list");
|
||||
for (uint32_t i=0; i < size; i++) {
|
||||
be_pushint(vm, value[i]);
|
||||
be_data_push(vm, -2);
|
||||
be_pop(vm, 1);
|
||||
}
|
||||
be_pop(vm, 1); // now list is on top
|
||||
|
||||
be_data_insert(vm, -3); // insert into map, key/value
|
||||
be_pop(vm, 2); // pop both key and value
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Binary search for dynamic attributes
|
||||
*
|
||||
* Names need to be sorted
|
||||
\*********************************************************************************************/
|
||||
// binary search within an array of sorted strings
|
||||
// the first 4 bytes are a pointer to a string
|
||||
// returns 0..total_elements-1 or -1 if not found
|
||||
//
|
||||
// This version skips the first character of the string if it's not a letter,
|
||||
// the first character is used to indicate the type of the value associated to the key
|
||||
int be_map_bin_search(const char * needle, const void * table, size_t elt_size, size_t total_elements) {
|
||||
int low = 0;
|
||||
int high = total_elements - 1;
|
||||
int mid = (low + high) / 2;
|
||||
// start a dissect
|
||||
while (low <= high) {
|
||||
const char * elt = *(const char **) ( ((uint8_t*)table) + mid * elt_size );
|
||||
char first_char = elt[0];
|
||||
if ( !(first_char >= 'a' && first_char <='z') && !(first_char >= 'A' && first_char <='Z') ) {
|
||||
elt++; // skip first char
|
||||
}
|
||||
int comp = strcmp(needle, elt);
|
||||
if (comp < 0) {
|
||||
high = mid - 1;
|
||||
} else if (comp > 0) {
|
||||
low = mid + 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
mid = (low + high) / 2;
|
||||
}
|
||||
if (low <= high) {
|
||||
return mid;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/*********************************************************************************************\
|
||||
* Extended version of be_raise()
|
||||
\*********************************************************************************************/
|
||||
|
||||
#include "be_mapping.h"
|
||||
#include "be_exec.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
// variant of be_raise with string format
|
||||
void be_raisef(bvm *vm, const char *except, const char *msg, ...) {
|
||||
// To save stack space support logging for max text length of 128 characters
|
||||
char log_data[128];
|
||||
|
||||
va_list arg;
|
||||
va_start(arg, msg);
|
||||
uint32_t len = vsnprintf(log_data, sizeof(log_data)-3, msg, arg);
|
||||
va_end(arg);
|
||||
if (len+3 > sizeof(log_data)) { strcat(log_data, "..."); } // Actual data is more
|
||||
be_raise(vm, except, log_data);
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
* Generated code, don't edit
|
||||
*******************************************************************/
|
||||
|
||||
const be_constint_t lv_gpio_constants[] = {
|
||||
const be_const_member_t lv_gpio_constants[] = {
|
||||
|
||||
{ "A4988_DIR", (int32_t) GPIO_A4988_DIR },
|
||||
{ "A4988_ENA", (int32_t) GPIO_A4988_ENA },
|
||||
|
|
|
@ -8,9 +8,10 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#include "be_ctypes.h"
|
||||
#include "be_mapping.h"
|
||||
|
||||
/* `lv_style` methods */
|
||||
const lvbe_call_c_t lv_style_func[] = {
|
||||
const be_ntv_func_def_t lv_style_func[] = {
|
||||
{ "set_align", (void*) &lv_style_set_align, "", "(lv.lv_style)i" },
|
||||
{ "set_anim_speed", (void*) &lv_style_set_anim_speed, "", "(lv.lv_style)i" },
|
||||
{ "set_anim_time", (void*) &lv_style_set_anim_time, "", "(lv.lv_style)i" },
|
||||
|
@ -103,20 +104,20 @@ const lvbe_call_c_t lv_style_func[] = {
|
|||
};
|
||||
|
||||
/* `lv_font` methods */
|
||||
const lvbe_call_c_t lv_font_func[] = {
|
||||
const be_ntv_func_def_t lv_font_func[] = {
|
||||
};
|
||||
|
||||
/* `lv_color` methods */
|
||||
const lvbe_call_c_t lv_color_func[] = {
|
||||
const be_ntv_func_def_t lv_color_func[] = {
|
||||
};
|
||||
|
||||
/* `lv_theme` methods */
|
||||
const lvbe_call_c_t lv_theme_func[] = {
|
||||
const be_ntv_func_def_t lv_theme_func[] = {
|
||||
};
|
||||
|
||||
/* `lv_img` methods */
|
||||
#ifdef BE_LV_WIDGET_IMG
|
||||
const lvbe_call_c_t lv_img_func[] = {
|
||||
const be_ntv_func_def_t lv_img_func[] = {
|
||||
{ "get_angle", (void*) &lv_img_get_angle, "i", "(lv.lv_obj)" },
|
||||
{ "get_antialias", (void*) &lv_img_get_antialias, "b", "(lv.lv_obj)" },
|
||||
{ "get_offset_x", (void*) &lv_img_get_offset_x, "i", "(lv.lv_obj)" },
|
||||
|
@ -136,7 +137,7 @@ const lvbe_call_c_t lv_img_func[] = {
|
|||
#endif // BE_LV_WIDGET_IMG
|
||||
|
||||
/* `lv_disp` methods */
|
||||
const lvbe_call_c_t lv_disp_func[] = {
|
||||
const be_ntv_func_def_t lv_disp_func[] = {
|
||||
{ "clean_dcache", (void*) &lv_disp_clean_dcache, "", "(lv.lv_disp)" },
|
||||
{ "dpx", (void*) &lv_disp_dpx, "i", "(lv.lv_disp)i" },
|
||||
{ "get_inactive_time", (void*) &lv_disp_get_inactive_time, "i", "(lv.lv_disp)" },
|
||||
|
@ -154,7 +155,7 @@ const lvbe_call_c_t lv_disp_func[] = {
|
|||
};
|
||||
|
||||
/* `lv_obj` methods */
|
||||
const lvbe_call_c_t lv_obj_func[] = {
|
||||
const be_ntv_func_def_t lv_obj_func[] = {
|
||||
{ "add_event_cb", (void*) &lv_obj_add_event_cb, "i", "(lv.lv_obj)^lv_event_cb^i." },
|
||||
{ "add_flag", (void*) &lv_obj_add_flag, "", "(lv.lv_obj)i" },
|
||||
{ "add_state", (void*) &lv_obj_add_state, "", "(lv.lv_obj)i" },
|
||||
|
@ -458,7 +459,7 @@ const lvbe_call_c_t lv_obj_func[] = {
|
|||
};
|
||||
|
||||
/* `lv_group` methods */
|
||||
const lvbe_call_c_t lv_group_func[] = {
|
||||
const be_ntv_func_def_t lv_group_func[] = {
|
||||
{ "add_obj", (void*) &lv_group_add_obj, "", "(lv.lv_group)(lv.lv_obj)" },
|
||||
{ "del", (void*) &lv_group_del, "", "(lv.lv_group)" },
|
||||
{ "focus_freeze", (void*) &lv_group_focus_freeze, "", "(lv.lv_group)b" },
|
||||
|
@ -481,7 +482,7 @@ const lvbe_call_c_t lv_group_func[] = {
|
|||
};
|
||||
|
||||
/* `lv_indev` methods */
|
||||
const lvbe_call_c_t lv_indev_func[] = {
|
||||
const be_ntv_func_def_t lv_indev_func[] = {
|
||||
{ "enable", (void*) &lv_indev_enable, "", "(lv.lv_indev)b" },
|
||||
{ "get_gesture_dir", (void*) &lv_indev_get_gesture_dir, "i", "(lv.lv_indev)" },
|
||||
{ "get_key", (void*) &lv_indev_get_key, "i", "(lv.lv_indev)" },
|
||||
|
@ -501,7 +502,7 @@ const lvbe_call_c_t lv_indev_func[] = {
|
|||
|
||||
/* `lv_chart` methods */
|
||||
#ifdef BE_LV_WIDGET_CHART
|
||||
const lvbe_call_c_t lv_chart_func[] = {
|
||||
const be_ntv_func_def_t lv_chart_func[] = {
|
||||
{ "get_cursor_point", (void*) &lv_chart_get_cursor_point, "i", "(lv.lv_obj)(lv.lv_chart_cursor)" },
|
||||
{ "get_point_count", (void*) &lv_chart_get_point_count, "i", "(lv.lv_obj)" },
|
||||
{ "get_point_pos_by_id", (void*) &lv_chart_get_point_pos_by_id, "", "(lv.lv_obj)(lv.lv_chart_series)i(lv.lv_point)" },
|
||||
|
@ -537,7 +538,7 @@ const lvbe_call_c_t lv_chart_func[] = {
|
|||
|
||||
/* `lv_colorwheel` methods */
|
||||
#ifdef BE_LV_WIDGET_COLORWHEEL
|
||||
const lvbe_call_c_t lv_colorwheel_func[] = {
|
||||
const be_ntv_func_def_t lv_colorwheel_func[] = {
|
||||
{ "get_color_mode", (void*) &lv_colorwheel_get_color_mode, "i", "(lv.lv_obj)" },
|
||||
{ "get_color_mode_fixed", (void*) &lv_colorwheel_get_color_mode_fixed, "b", "(lv.lv_obj)" },
|
||||
{ "get_hsv", (void*) &lv_colorwheel_get_hsv, "i", "(lv.lv_obj)" },
|
||||
|
@ -551,14 +552,14 @@ const lvbe_call_c_t lv_colorwheel_func[] = {
|
|||
|
||||
/* `lv_imgbtn` methods */
|
||||
#ifdef BE_LV_WIDGET_IMGBTN
|
||||
const lvbe_call_c_t lv_imgbtn_func[] = {
|
||||
const be_ntv_func_def_t lv_imgbtn_func[] = {
|
||||
{ "set_src", (void*) &lv_imgbtn_set_src, "", "(lv.lv_obj)(lv.lv_imgbtn_state)..." },
|
||||
};
|
||||
#endif // BE_LV_WIDGET_IMGBTN
|
||||
|
||||
/* `lv_led` methods */
|
||||
#ifdef BE_LV_WIDGET_LED
|
||||
const lvbe_call_c_t lv_led_func[] = {
|
||||
const be_ntv_func_def_t lv_led_func[] = {
|
||||
{ "get_brightness", (void*) &lv_led_get_brightness, "i", "(lv.lv_obj)" },
|
||||
{ "off", (void*) &lv_led_off, "", "(lv.lv_obj)" },
|
||||
{ "on", (void*) &lv_led_on, "", "(lv.lv_obj)" },
|
||||
|
@ -570,7 +571,7 @@ const lvbe_call_c_t lv_led_func[] = {
|
|||
|
||||
/* `lv_meter` methods */
|
||||
#ifdef BE_LV_WIDGET_METER
|
||||
const lvbe_call_c_t lv_meter_func[] = {
|
||||
const be_ntv_func_def_t lv_meter_func[] = {
|
||||
{ "add_arc", (void*) &lv_meter_add_arc, "lv.lv_meter_indicator", "(lv.lv_obj)(lv.lv_meter_scale)i(lv.lv_color)i" },
|
||||
{ "add_needle_img", (void*) &lv_meter_add_needle_img, "lv.lv_meter_indicator", "(lv.lv_obj)(lv.lv_meter_scale).ii" },
|
||||
{ "add_needle_line", (void*) &lv_meter_add_needle_line, "lv.lv_meter_indicator", "(lv.lv_obj)(lv.lv_meter_scale)i(lv.lv_color)i" },
|
||||
|
@ -587,7 +588,7 @@ const lvbe_call_c_t lv_meter_func[] = {
|
|||
|
||||
/* `lv_msgbox` methods */
|
||||
#ifdef BE_LV_WIDGET_MSGBOX
|
||||
const lvbe_call_c_t lv_msgbox_func[] = {
|
||||
const be_ntv_func_def_t lv_msgbox_func[] = {
|
||||
{ "close", (void*) &lv_msgbox_close, "", "(lv.lv_obj)" },
|
||||
{ "get_active_btn_text", (void*) &lv_msgbox_get_active_btn_text, "s", "(lv.lv_obj)" },
|
||||
{ "get_btns", (void*) &lv_msgbox_get_btns, "lv.lv_obj", "(lv.lv_obj)" },
|
||||
|
@ -599,7 +600,7 @@ const lvbe_call_c_t lv_msgbox_func[] = {
|
|||
|
||||
/* `lv_spinbox` methods */
|
||||
#ifdef BE_LV_WIDGET_SPINBOX
|
||||
const lvbe_call_c_t lv_spinbox_func[] = {
|
||||
const be_ntv_func_def_t lv_spinbox_func[] = {
|
||||
{ "decrement", (void*) &lv_spinbox_decrement, "", "(lv.lv_obj)" },
|
||||
{ "get_rollover", (void*) &lv_spinbox_get_rollover, "b", "(lv.lv_obj)" },
|
||||
{ "get_step", (void*) &lv_spinbox_get_step, "i", "(lv.lv_obj)" },
|
||||
|
@ -617,13 +618,13 @@ const lvbe_call_c_t lv_spinbox_func[] = {
|
|||
|
||||
/* `lv_spinner` methods */
|
||||
#ifdef BE_LV_WIDGET_SPINNER
|
||||
const lvbe_call_c_t lv_spinner_func[] = {
|
||||
const be_ntv_func_def_t lv_spinner_func[] = {
|
||||
};
|
||||
#endif // BE_LV_WIDGET_SPINNER
|
||||
|
||||
/* `lv_arc` methods */
|
||||
#ifdef BE_LV_WIDGET_ARC
|
||||
const lvbe_call_c_t lv_arc_func[] = {
|
||||
const be_ntv_func_def_t lv_arc_func[] = {
|
||||
{ "get_angle_end", (void*) &lv_arc_get_angle_end, "i", "(lv.lv_obj)" },
|
||||
{ "get_angle_start", (void*) &lv_arc_get_angle_start, "i", "(lv.lv_obj)" },
|
||||
{ "get_bg_angle_end", (void*) &lv_arc_get_bg_angle_end, "i", "(lv.lv_obj)" },
|
||||
|
@ -648,7 +649,7 @@ const lvbe_call_c_t lv_arc_func[] = {
|
|||
|
||||
/* `lv_bar` methods */
|
||||
#ifdef BE_LV_WIDGET_BAR
|
||||
const lvbe_call_c_t lv_bar_func[] = {
|
||||
const be_ntv_func_def_t lv_bar_func[] = {
|
||||
{ "get_max_value", (void*) &lv_bar_get_max_value, "i", "(lv.lv_obj)" },
|
||||
{ "get_min_value", (void*) &lv_bar_get_min_value, "i", "(lv.lv_obj)" },
|
||||
{ "get_mode", (void*) &lv_bar_get_mode, "i", "(lv.lv_obj)" },
|
||||
|
@ -663,13 +664,13 @@ const lvbe_call_c_t lv_bar_func[] = {
|
|||
|
||||
/* `lv_btn` methods */
|
||||
#ifdef BE_LV_WIDGET_BTN
|
||||
const lvbe_call_c_t lv_btn_func[] = {
|
||||
const be_ntv_func_def_t lv_btn_func[] = {
|
||||
};
|
||||
#endif // BE_LV_WIDGET_BTN
|
||||
|
||||
/* `lv_btnmatrix` methods */
|
||||
#ifdef BE_LV_WIDGET_BTNMATRIX
|
||||
const lvbe_call_c_t lv_btnmatrix_func[] = {
|
||||
const be_ntv_func_def_t lv_btnmatrix_func[] = {
|
||||
{ "clear_btn_ctrl", (void*) &lv_btnmatrix_clear_btn_ctrl, "", "(lv.lv_obj)i(lv.lv_btnmatrix_ctrl)" },
|
||||
{ "clear_btn_ctrl_all", (void*) &lv_btnmatrix_clear_btn_ctrl_all, "", "(lv.lv_obj)(lv.lv_btnmatrix_ctrl)" },
|
||||
{ "get_btn_text", (void*) &lv_btnmatrix_get_btn_text, "s", "(lv.lv_obj)i" },
|
||||
|
@ -688,7 +689,7 @@ const lvbe_call_c_t lv_btnmatrix_func[] = {
|
|||
|
||||
/* `lv_canvas` methods */
|
||||
#ifdef BE_LV_WIDGET_CANVAS
|
||||
const lvbe_call_c_t lv_canvas_func[] = {
|
||||
const be_ntv_func_def_t lv_canvas_func[] = {
|
||||
{ "blur_hor", (void*) &lv_canvas_blur_hor, "", "(lv.lv_obj)(lv.lv_area)i" },
|
||||
{ "blur_ver", (void*) &lv_canvas_blur_ver, "", "(lv.lv_obj)(lv.lv_area)i" },
|
||||
{ "copy_buf", (void*) &lv_canvas_copy_buf, "", "(lv.lv_obj).iiii" },
|
||||
|
@ -709,7 +710,7 @@ const lvbe_call_c_t lv_canvas_func[] = {
|
|||
|
||||
/* `lv_checkbox` methods */
|
||||
#ifdef BE_LV_WIDGET_CHECKBOX
|
||||
const lvbe_call_c_t lv_checkbox_func[] = {
|
||||
const be_ntv_func_def_t lv_checkbox_func[] = {
|
||||
{ "get_text", (void*) &lv_checkbox_get_text, "s", "(lv.lv_obj)" },
|
||||
{ "set_text", (void*) &lv_checkbox_set_text, "", "(lv.lv_obj)s" },
|
||||
{ "set_text_static", (void*) &lv_checkbox_set_text_static, "", "(lv.lv_obj)s" },
|
||||
|
@ -718,7 +719,7 @@ const lvbe_call_c_t lv_checkbox_func[] = {
|
|||
|
||||
/* `lv_dropdown` methods */
|
||||
#ifdef BE_LV_WIDGET_DROPDOWN
|
||||
const lvbe_call_c_t lv_dropdown_func[] = {
|
||||
const be_ntv_func_def_t lv_dropdown_func[] = {
|
||||
{ "add_option", (void*) &lv_dropdown_add_option, "", "(lv.lv_obj)si" },
|
||||
{ "clear_options", (void*) &lv_dropdown_clear_options, "", "(lv.lv_obj)" },
|
||||
{ "close", (void*) &lv_dropdown_close, "", "(lv.lv_obj)" },
|
||||
|
@ -744,7 +745,7 @@ const lvbe_call_c_t lv_dropdown_func[] = {
|
|||
|
||||
/* `lv_label` methods */
|
||||
#ifdef BE_LV_WIDGET_LABEL
|
||||
const lvbe_call_c_t lv_label_func[] = {
|
||||
const be_ntv_func_def_t lv_label_func[] = {
|
||||
{ "cut_text", (void*) &lv_label_cut_text, "", "(lv.lv_obj)ii" },
|
||||
{ "get_letter_on", (void*) &lv_label_get_letter_on, "i", "(lv.lv_obj)(lv.lv_point)" },
|
||||
{ "get_letter_pos", (void*) &lv_label_get_letter_pos, "", "(lv.lv_obj)i(lv.lv_point)" },
|
||||
|
@ -767,7 +768,7 @@ const lvbe_call_c_t lv_label_func[] = {
|
|||
|
||||
/* `lv_line` methods */
|
||||
#ifdef BE_LV_WIDGET_LINE
|
||||
const lvbe_call_c_t lv_line_func[] = {
|
||||
const be_ntv_func_def_t lv_line_func[] = {
|
||||
{ "get_y_invert", (void*) &lv_line_get_y_invert, "b", "(lv.lv_obj)" },
|
||||
{ "set_points", (void*) &lv_line_set_points, "", "(lv.lv_obj)ii" },
|
||||
{ "set_y_invert", (void*) &lv_line_set_y_invert, "", "(lv.lv_obj)b" },
|
||||
|
@ -776,7 +777,7 @@ const lvbe_call_c_t lv_line_func[] = {
|
|||
|
||||
/* `lv_roller` methods */
|
||||
#ifdef BE_LV_WIDGET_ROLLER
|
||||
const lvbe_call_c_t lv_roller_func[] = {
|
||||
const be_ntv_func_def_t lv_roller_func[] = {
|
||||
{ "get_option_cnt", (void*) &lv_roller_get_option_cnt, "i", "(lv.lv_obj)" },
|
||||
{ "get_options", (void*) &lv_roller_get_options, "s", "(lv.lv_obj)" },
|
||||
{ "get_selected", (void*) &lv_roller_get_selected, "i", "(lv.lv_obj)" },
|
||||
|
@ -789,7 +790,7 @@ const lvbe_call_c_t lv_roller_func[] = {
|
|||
|
||||
/* `lv_slider` methods */
|
||||
#ifdef BE_LV_WIDGET_SLIDER
|
||||
const lvbe_call_c_t lv_slider_func[] = {
|
||||
const be_ntv_func_def_t lv_slider_func[] = {
|
||||
{ "get_left_value", (void*) &lv_slider_get_left_value, "i", "(lv.lv_obj)" },
|
||||
{ "get_max_value", (void*) &lv_slider_get_max_value, "i", "(lv.lv_obj)" },
|
||||
{ "get_min_value", (void*) &lv_slider_get_min_value, "i", "(lv.lv_obj)" },
|
||||
|
@ -805,13 +806,13 @@ const lvbe_call_c_t lv_slider_func[] = {
|
|||
|
||||
/* `lv_switch` methods */
|
||||
#ifdef BE_LV_WIDGET_SWITCH
|
||||
const lvbe_call_c_t lv_switch_func[] = {
|
||||
const be_ntv_func_def_t lv_switch_func[] = {
|
||||
};
|
||||
#endif // BE_LV_WIDGET_SWITCH
|
||||
|
||||
/* `lv_table` methods */
|
||||
#ifdef BE_LV_WIDGET_TABLE
|
||||
const lvbe_call_c_t lv_table_func[] = {
|
||||
const be_ntv_func_def_t lv_table_func[] = {
|
||||
{ "add_cell_ctrl", (void*) &lv_table_add_cell_ctrl, "", "(lv.lv_obj)ii(lv.lv_table_cell_ctrl)" },
|
||||
{ "clear_cell_ctrl", (void*) &lv_table_clear_cell_ctrl, "", "(lv.lv_obj)ii(lv.lv_table_cell_ctrl)" },
|
||||
{ "get_cell_value", (void*) &lv_table_get_cell_value, "s", "(lv.lv_obj)ii" },
|
||||
|
@ -830,7 +831,7 @@ const lvbe_call_c_t lv_table_func[] = {
|
|||
|
||||
/* `lv_textarea` methods */
|
||||
#ifdef BE_LV_WIDGET_TEXTAREA
|
||||
const lvbe_call_c_t lv_textarea_func[] = {
|
||||
const be_ntv_func_def_t lv_textarea_func[] = {
|
||||
{ "add_char", (void*) &lv_textarea_add_char, "", "(lv.lv_obj)i" },
|
||||
{ "add_text", (void*) &lv_textarea_add_text, "", "(lv.lv_obj)s" },
|
||||
{ "clear_selection", (void*) &lv_textarea_clear_selection, "", "(lv.lv_obj)" },
|
||||
|
@ -901,7 +902,7 @@ extern const bclass be_class_lv_theme;
|
|||
|
||||
|
||||
// map of clases
|
||||
const lvbe_call_c_classes_t lv_classes[] = {
|
||||
const be_ntv_class_def_t lv_classes[] = {
|
||||
#ifdef BE_LV_WIDGET_ARC
|
||||
{ "lv_arc", &be_class_lv_arc, lv_arc_func, sizeof(lv_arc_func) / sizeof(lv_arc_func[0]) },
|
||||
#endif // BE_LV_WIDGET_ARC
|
||||
|
@ -988,106 +989,106 @@ const size_t lv_classes_size = sizeof(lv_classes) / sizeof(lv_classes[0]);
|
|||
/* `lv_theme` methods */
|
||||
/* `lv_img` methods */
|
||||
#ifdef BE_LV_WIDGET_IMG
|
||||
int be_ntv_lv_img_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_img_create, "+", "(lv.lv_obj)"); }
|
||||
int be_ntv_lv_img_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_img_create, "+_p", "(lv.lv_obj)"); }
|
||||
#endif // BE_LV_WIDGET_IMG
|
||||
/* `lv_disp` methods */
|
||||
/* `lv_obj` methods */
|
||||
int be_ntv_lv_obj_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_obj_create, "+", "(lv.lv_obj)"); }
|
||||
int be_ntv_lv_obj_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_obj_create, "+_p", "(lv.lv_obj)"); }
|
||||
/* `lv_group` methods */
|
||||
int be_ntv_lv_group_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_group_create, "+", ""); }
|
||||
int be_ntv_lv_group_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_group_create, "+_p", ""); }
|
||||
/* `lv_indev` methods */
|
||||
/* `lv_chart` methods */
|
||||
#ifdef BE_LV_WIDGET_CHART
|
||||
int be_ntv_lv_chart_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_chart_create, "+", "(lv.lv_obj)"); }
|
||||
int be_ntv_lv_chart_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_chart_create, "+_p", "(lv.lv_obj)"); }
|
||||
#endif // BE_LV_WIDGET_CHART
|
||||
/* `lv_colorwheel` methods */
|
||||
#ifdef BE_LV_WIDGET_COLORWHEEL
|
||||
int be_ntv_lv_colorwheel_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_colorwheel_create, "+", "(lv.lv_obj)b"); }
|
||||
int be_ntv_lv_colorwheel_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_colorwheel_create, "+_p", "(lv.lv_obj)b"); }
|
||||
#endif // BE_LV_WIDGET_COLORWHEEL
|
||||
/* `lv_imgbtn` methods */
|
||||
#ifdef BE_LV_WIDGET_IMGBTN
|
||||
int be_ntv_lv_imgbtn_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_imgbtn_create, "+", "(lv.lv_obj)"); }
|
||||
int be_ntv_lv_imgbtn_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_imgbtn_create, "+_p", "(lv.lv_obj)"); }
|
||||
#endif // BE_LV_WIDGET_IMGBTN
|
||||
/* `lv_led` methods */
|
||||
#ifdef BE_LV_WIDGET_LED
|
||||
int be_ntv_lv_led_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_led_create, "+", "(lv.lv_obj)"); }
|
||||
int be_ntv_lv_led_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_led_create, "+_p", "(lv.lv_obj)"); }
|
||||
#endif // BE_LV_WIDGET_LED
|
||||
/* `lv_meter` methods */
|
||||
#ifdef BE_LV_WIDGET_METER
|
||||
int be_ntv_lv_meter_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_meter_create, "+", "(lv.lv_obj)"); }
|
||||
int be_ntv_lv_meter_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_meter_create, "+_p", "(lv.lv_obj)"); }
|
||||
#endif // BE_LV_WIDGET_METER
|
||||
/* `lv_msgbox` methods */
|
||||
#ifdef BE_LV_WIDGET_MSGBOX
|
||||
int be_ntv_lv_msgbox_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_msgbox_create, "+", "(lv.lv_obj)sssb"); }
|
||||
int be_ntv_lv_msgbox_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_msgbox_create, "+_p", "(lv.lv_obj)sssb"); }
|
||||
#endif // BE_LV_WIDGET_MSGBOX
|
||||
/* `lv_spinbox` methods */
|
||||
#ifdef BE_LV_WIDGET_SPINBOX
|
||||
int be_ntv_lv_spinbox_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_spinbox_create, "+", "(lv.lv_obj)"); }
|
||||
int be_ntv_lv_spinbox_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_spinbox_create, "+_p", "(lv.lv_obj)"); }
|
||||
#endif // BE_LV_WIDGET_SPINBOX
|
||||
/* `lv_spinner` methods */
|
||||
#ifdef BE_LV_WIDGET_SPINNER
|
||||
int be_ntv_lv_spinner_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_spinner_create, "+", "(lv.lv_obj)ii"); }
|
||||
int be_ntv_lv_spinner_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_spinner_create, "+_p", "(lv.lv_obj)ii"); }
|
||||
#endif // BE_LV_WIDGET_SPINNER
|
||||
/* `lv_arc` methods */
|
||||
#ifdef BE_LV_WIDGET_ARC
|
||||
int be_ntv_lv_arc_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_arc_create, "+", "(lv.lv_obj)"); }
|
||||
int be_ntv_lv_arc_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_arc_create, "+_p", "(lv.lv_obj)"); }
|
||||
#endif // BE_LV_WIDGET_ARC
|
||||
/* `lv_bar` methods */
|
||||
#ifdef BE_LV_WIDGET_BAR
|
||||
int be_ntv_lv_bar_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_bar_create, "+", "(lv.lv_obj)"); }
|
||||
int be_ntv_lv_bar_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_bar_create, "+_p", "(lv.lv_obj)"); }
|
||||
#endif // BE_LV_WIDGET_BAR
|
||||
/* `lv_btn` methods */
|
||||
#ifdef BE_LV_WIDGET_BTN
|
||||
int be_ntv_lv_btn_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_btn_create, "+", "(lv.lv_obj)"); }
|
||||
int be_ntv_lv_btn_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_btn_create, "+_p", "(lv.lv_obj)"); }
|
||||
#endif // BE_LV_WIDGET_BTN
|
||||
/* `lv_btnmatrix` methods */
|
||||
#ifdef BE_LV_WIDGET_BTNMATRIX
|
||||
int be_ntv_lv_btnmatrix_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_btnmatrix_create, "+", "(lv.lv_obj)"); }
|
||||
int be_ntv_lv_btnmatrix_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_btnmatrix_create, "+_p", "(lv.lv_obj)"); }
|
||||
#endif // BE_LV_WIDGET_BTNMATRIX
|
||||
/* `lv_canvas` methods */
|
||||
#ifdef BE_LV_WIDGET_CANVAS
|
||||
int be_ntv_lv_canvas_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_canvas_create, "+", "(lv.lv_obj)"); }
|
||||
int be_ntv_lv_canvas_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_canvas_create, "+_p", "(lv.lv_obj)"); }
|
||||
#endif // BE_LV_WIDGET_CANVAS
|
||||
/* `lv_checkbox` methods */
|
||||
#ifdef BE_LV_WIDGET_CHECKBOX
|
||||
int be_ntv_lv_checkbox_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_checkbox_create, "+", "(lv.lv_obj)"); }
|
||||
int be_ntv_lv_checkbox_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_checkbox_create, "+_p", "(lv.lv_obj)"); }
|
||||
#endif // BE_LV_WIDGET_CHECKBOX
|
||||
/* `lv_dropdown` methods */
|
||||
#ifdef BE_LV_WIDGET_DROPDOWN
|
||||
int be_ntv_lv_dropdown_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_dropdown_create, "+", "(lv.lv_obj)"); }
|
||||
int be_ntv_lv_dropdown_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_dropdown_create, "+_p", "(lv.lv_obj)"); }
|
||||
#endif // BE_LV_WIDGET_DROPDOWN
|
||||
/* `lv_label` methods */
|
||||
#ifdef BE_LV_WIDGET_LABEL
|
||||
int be_ntv_lv_label_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_label_create, "+", "(lv.lv_obj)"); }
|
||||
int be_ntv_lv_label_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_label_create, "+_p", "(lv.lv_obj)"); }
|
||||
#endif // BE_LV_WIDGET_LABEL
|
||||
/* `lv_line` methods */
|
||||
#ifdef BE_LV_WIDGET_LINE
|
||||
int be_ntv_lv_line_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_line_create, "+", "(lv.lv_obj)"); }
|
||||
int be_ntv_lv_line_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_line_create, "+_p", "(lv.lv_obj)"); }
|
||||
#endif // BE_LV_WIDGET_LINE
|
||||
/* `lv_roller` methods */
|
||||
#ifdef BE_LV_WIDGET_ROLLER
|
||||
int be_ntv_lv_roller_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_roller_create, "+", "(lv.lv_obj)"); }
|
||||
int be_ntv_lv_roller_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_roller_create, "+_p", "(lv.lv_obj)"); }
|
||||
#endif // BE_LV_WIDGET_ROLLER
|
||||
/* `lv_slider` methods */
|
||||
#ifdef BE_LV_WIDGET_SLIDER
|
||||
int be_ntv_lv_slider_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_slider_create, "+", "(lv.lv_obj)"); }
|
||||
int be_ntv_lv_slider_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_slider_create, "+_p", "(lv.lv_obj)"); }
|
||||
#endif // BE_LV_WIDGET_SLIDER
|
||||
/* `lv_switch` methods */
|
||||
#ifdef BE_LV_WIDGET_SWITCH
|
||||
int be_ntv_lv_switch_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_switch_create, "+", "(lv.lv_obj)"); }
|
||||
int be_ntv_lv_switch_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_switch_create, "+_p", "(lv.lv_obj)"); }
|
||||
#endif // BE_LV_WIDGET_SWITCH
|
||||
/* `lv_table` methods */
|
||||
#ifdef BE_LV_WIDGET_TABLE
|
||||
int be_ntv_lv_table_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_table_create, "+", "(lv.lv_obj)"); }
|
||||
int be_ntv_lv_table_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_table_create, "+_p", "(lv.lv_obj)"); }
|
||||
#endif // BE_LV_WIDGET_TABLE
|
||||
/* `lv_textarea` methods */
|
||||
#ifdef BE_LV_WIDGET_TEXTAREA
|
||||
int be_ntv_lv_textarea_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_textarea_create, "+", "(lv.lv_obj)"); }
|
||||
int be_ntv_lv_textarea_init(bvm *vm) { return be_call_c_func(vm, (void*) &lv_textarea_create, "+_p", "(lv.lv_obj)"); }
|
||||
#endif // BE_LV_WIDGET_TEXTAREA
|
||||
|
||||
// create font either empty or from parameter on stack
|
||||
int lvbe_font_create(bvm *vm) { return be_call_c_func(vm, NULL, "+lv_font", ""); }
|
||||
int lvbe_theme_create(bvm *vm) { return be_call_c_func(vm, NULL, "+lv_theme", ""); }
|
||||
int lvbe_font_create(bvm *vm) { return be_call_c_func(vm, NULL, "+_p", ""); }
|
||||
int lvbe_theme_create(bvm *vm) { return be_call_c_func(vm, NULL, "+_p", ""); }
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -26,19 +26,6 @@
|
|||
const char kTypeError[] PROGMEM = "type_error";
|
||||
const char kInternalError[] PROGMEM = "intenal_error";
|
||||
|
||||
extern "C" {
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Support for Berry int constants
|
||||
* as virtual members
|
||||
\*********************************************************************************************/
|
||||
typedef struct be_constint_t {
|
||||
const char * name;
|
||||
int32_t value;
|
||||
} be_constint_t;
|
||||
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* LVGL top level virtual members
|
||||
*
|
||||
|
@ -76,65 +63,6 @@ extern "C" {
|
|||
return v;
|
||||
}
|
||||
|
||||
// variant of be_raise with string format
|
||||
[[ noreturn ]] void be_raisef(bvm *vm, const char *except, const char *msg, ...) {
|
||||
// To save stack space support logging for max text length of 128 characters
|
||||
char log_data[128];
|
||||
|
||||
va_list arg;
|
||||
va_start(arg, msg);
|
||||
uint32_t len = ext_vsnprintf_P(log_data, sizeof(log_data)-3, msg, arg);
|
||||
va_end(arg);
|
||||
if (len+3 > sizeof(log_data)) { strcat(log_data, "..."); } // Actual data is more
|
||||
be_raise(vm, except, log_data);
|
||||
}
|
||||
|
||||
static void map_insert_int(bvm *vm, const char *key, int value)
|
||||
{
|
||||
be_pushstring(vm, key);
|
||||
be_pushint(vm, value);
|
||||
be_data_insert(vm, -3);
|
||||
be_pop(vm, 2);
|
||||
}
|
||||
static void map_insert_bool(bvm *vm, const char *key, bool value)
|
||||
{
|
||||
be_pushstring(vm, key);
|
||||
be_pushbool(vm, value);
|
||||
be_data_insert(vm, -3);
|
||||
be_pop(vm, 2);
|
||||
}
|
||||
// if value == NAN, ignore
|
||||
static void map_insert_float(bvm *vm, const char *key, float value)
|
||||
{
|
||||
if (!isnan(value)) {
|
||||
be_pushstring(vm, key);
|
||||
be_pushreal(vm, value);
|
||||
be_data_insert(vm, -3);
|
||||
be_pop(vm, 2);
|
||||
}
|
||||
}
|
||||
static void map_insert_str(bvm *vm, const char *key, const char *value)
|
||||
{
|
||||
be_pushstring(vm, key);
|
||||
be_pushstring(vm, value);
|
||||
be_data_insert(vm, -3);
|
||||
be_pop(vm, 2);
|
||||
}
|
||||
static void map_insert_list_uint8(bvm *vm, const char *key, const uint8_t *value, size_t size)
|
||||
{
|
||||
be_pushstring(vm, key);
|
||||
|
||||
be_newobject(vm, "list");
|
||||
for (uint32_t i=0; i < size; i++) {
|
||||
be_pushint(vm, value[i]);
|
||||
be_data_push(vm, -2);
|
||||
be_pop(vm, 1);
|
||||
}
|
||||
be_pop(vm, 1); // now list is on top
|
||||
|
||||
be_data_insert(vm, -3); // insert into map, key/value
|
||||
be_pop(vm, 2); // pop both key and value
|
||||
}
|
||||
int32_t member_find(bvm *vm, const char *key, int32_t default_value) {
|
||||
int32_t ret = default_value;
|
||||
if (be_getmember(vm, -1, key)) {
|
||||
|
@ -171,283 +99,6 @@ extern "C" {
|
|||
be_call(vm, 2); // call wirn 2 parameters (implicit instance and key)
|
||||
be_pop(vm, 2); // pop 2 arguments and return value
|
||||
}
|
||||
|
||||
// create an object from the pointer and a class name
|
||||
// on return, instance is pushed on the stack
|
||||
void lv_create_object(bvm *vm, const char * class_name, void * ptr);
|
||||
void lv_create_object(bvm *vm, const char * class_name, void * ptr) {
|
||||
if (ptr == nullptr) {
|
||||
be_throw(vm, BE_MALLOC_FAIL);
|
||||
}
|
||||
|
||||
be_getglobal(vm, class_name); // stack = class
|
||||
be_call(vm, 0); // instanciate, stack = instance
|
||||
be_getmember(vm, -1, "init"); // stack = instance, init_func
|
||||
be_pushvalue(vm, -2); // stack = instance, init_func, instance
|
||||
be_pushcomptr(vm, ptr); // stack = instance, init_func, instance, ptr
|
||||
be_call(vm, 2); // stack = instance, ret, instance, ptr
|
||||
be_pop(vm, 3); // stack = instance
|
||||
}
|
||||
|
||||
extern void berry_log_C(const char * berry_buf, ...);
|
||||
// Create a class given a global name or a name within a module
|
||||
// Case 1: (no dot in name) `lv_wifi_bars` will look for a global variable `lv_wifi_bars`
|
||||
// Case 2: (dot in name) `lvgl.lv_obj` will import `lvgl` and look for `lv_obj` within this module
|
||||
// returns true if successful and result is top of stack, or false if not found and `nil` is at top of stack
|
||||
bbool be_find_class(bvm *vm, const char * cl_name);
|
||||
bbool be_find_class(bvm *vm, const char * cl_name) {
|
||||
char *saveptr;
|
||||
bbool ret = false;
|
||||
|
||||
if (cl_name == NULL) {
|
||||
be_pushnil(vm);
|
||||
return ret;
|
||||
}
|
||||
// berry_log_C(">> be_find_class %s", cl_name);
|
||||
char cl_name_buf[strlen(cl_name)+1];
|
||||
strcpy(cl_name_buf, cl_name);
|
||||
|
||||
char * prefix = strtok_r(cl_name_buf, ".", &saveptr);
|
||||
char * suffix = strtok_r(NULL, ".", &saveptr);
|
||||
if (suffix) {
|
||||
// berry_log_C(">> be_find_class %s - %s", prefix, suffix);
|
||||
be_getmodule(vm, prefix);
|
||||
ret = be_getmember(vm, -1, suffix);
|
||||
// berry_log_C(">> be_find_class ret=%i", ret);
|
||||
be_remove(vm, -2);
|
||||
} else {
|
||||
ret = be_getglobal(vm, prefix);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Binary search for dynamic attributes
|
||||
*
|
||||
* Names need to be sorted
|
||||
\*********************************************************************************************/
|
||||
// binary search within an array of sorted strings
|
||||
// the first 4 bytes are a pointer to a string
|
||||
// returns 0..total_elements-1 or -1 if not found
|
||||
//
|
||||
// This version skips the first character of the string if it's not a letter,
|
||||
// the first character is used to indicate the type of the value associated to the key
|
||||
extern "C" {
|
||||
int32_t bin_search(const char * needle, const void * table, size_t elt_size, size_t total_elements);
|
||||
int32_t bin_search(const char * needle, const void * table, size_t elt_size, size_t total_elements) {
|
||||
int32_t low = 0;
|
||||
int32_t high = total_elements - 1;
|
||||
int32_t mid = (low + high) / 2;
|
||||
// start a dissect
|
||||
while (low <= high) {
|
||||
const char * elt = *(const char **) ( ((uint8_t*)table) + mid * elt_size );
|
||||
char first_char = elt[0];
|
||||
if ( !(first_char >= 'a' && first_char <='z') && !(first_char >= 'A' && first_char <='Z') ) {
|
||||
elt++; // skip first char
|
||||
}
|
||||
int32_t comp = strcmp(needle, elt);
|
||||
if (comp < 0) {
|
||||
high = mid - 1;
|
||||
} else if (comp > 0) {
|
||||
low = mid + 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
mid = (low + high) / 2;
|
||||
}
|
||||
if (low <= high) {
|
||||
return mid;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Generalized callbacks
|
||||
*
|
||||
* Warning, the following expect all parameters to be 32 bits wide
|
||||
\*********************************************************************************************/
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Automatically parse Berry stack and call the C function accordingly
|
||||
*
|
||||
* This function takes the n incoming arguments and pushes them as arguments
|
||||
* on the stack for the C function:
|
||||
* - be_int -> int32_t
|
||||
* - be_bool -> int32_t with value 0/1
|
||||
* - be_string -> const char *
|
||||
* - be_instance -> gets the member "_p" and pushes as void*
|
||||
*
|
||||
* This works because C silently ignores any unwanted arguments.
|
||||
* There is a strong requirements that all ints and pointers are 32 bits.
|
||||
* Float is not supported but could be added. Double cannot be supported because they are 64 bits
|
||||
*
|
||||
* Optional argument:
|
||||
* - return_type: the C function return value is int32_t and is converted to the
|
||||
* relevant Berry object depending on this char:
|
||||
* '' (default): nil, no value
|
||||
* 'i' be_int
|
||||
* 'b' be_bool
|
||||
* 's' be_str
|
||||
*
|
||||
* - arg_type: optionally check the types of input arguments, or throw an error
|
||||
* string of argument types, '+' marks optional arguments
|
||||
* '.' don't care
|
||||
* 'i' be_int
|
||||
* 'b' be_bool
|
||||
* 's' be_string
|
||||
* 'c' C callback
|
||||
* 'lv_obj' be_instance of type or subtype
|
||||
* '^lv_event_cb' callback of a named class - will call `_lvgl.gen_cb(arg_type, closure, self, lv native pointer)` and expects a callback address in return
|
||||
*
|
||||
* Ex: "oii+s" takes 3 mandatory arguments (obj_instance, int, int) and an optional fourth one [,string]
|
||||
\*********************************************************************************************/
|
||||
// general form of lv_obj_t* function, up to 4 parameters
|
||||
// We can only send 32 bits arguments (no 64 bits nor double) and we expect pointers to be 32 bits
|
||||
|
||||
#define LVBE_LVGL_GLOB "_lvgl"
|
||||
#define LVBE_LVGL_CB_GEN "gen_cb"
|
||||
|
||||
// read a single value at stack position idx, convert to int.
|
||||
// if object instance, get `_p` member and convert it recursively
|
||||
int32_t be_convert_single_elt(bvm *vm, int32_t idx, const char * arg_type = nullptr, void * lv_obj_cb = nullptr) {
|
||||
int32_t ret = 0;
|
||||
char provided_type = 0;
|
||||
idx = be_absindex(vm, idx); // make sure we have an absolute index
|
||||
|
||||
// berry_log_C(">> 0 idx=%i arg_type=%s", idx, arg_type ? arg_type : "NULL");
|
||||
if (arg_type == nullptr) { arg_type = "."; } // if no type provided, replace with wildchar
|
||||
size_t arg_type_len = strlen(arg_type);
|
||||
|
||||
// handle callbacks first, since a wrong parameter will always yield to a crash
|
||||
if (arg_type_len > 1 && arg_type[0] == '^') { // it is a callback
|
||||
arg_type++; // skip first character
|
||||
if (be_isclosure(vm, idx)) {
|
||||
be_getglobal(vm, LVBE_LVGL_GLOB);
|
||||
be_getmethod(vm, -1, LVBE_LVGL_CB_GEN);
|
||||
be_pushvalue(vm, -2);
|
||||
be_remove(vm, -3); // stack contains method + instance
|
||||
be_pushstring(vm, arg_type);
|
||||
be_pushvalue(vm, idx);
|
||||
be_pushvalue(vm, 1);
|
||||
be_pushcomptr(vm, lv_obj_cb);
|
||||
be_call(vm, 5);
|
||||
const void * func = be_tocomptr(vm, -6);
|
||||
be_pop(vm, 6);
|
||||
|
||||
// berry_log_C("func=%p", func);
|
||||
return (int32_t) func;
|
||||
} else {
|
||||
be_raise(vm, kTypeError, "Closure expected for callback type");
|
||||
}
|
||||
}
|
||||
|
||||
// first convert the value to int32
|
||||
if (be_isint(vm, idx)) { ret = be_toint(vm, idx); provided_type = 'i'; }
|
||||
else if (be_isbool(vm, idx)) { ret = be_tobool(vm, idx); provided_type = 'b'; }
|
||||
else if (be_isstring(vm, idx)) { ret = (int32_t) be_tostring(vm, idx); provided_type = 's'; }
|
||||
else if (be_iscomptr(vm, idx)) { ret = (int32_t) be_tocomptr(vm, idx); provided_type = 'c'; }
|
||||
|
||||
// check if simple type was a match
|
||||
if (provided_type) {
|
||||
bool type_ok = false;
|
||||
type_ok = (arg_type[0] == '.'); // any type is accepted
|
||||
type_ok = type_ok || (arg_type[0] == provided_type); // or type is a match
|
||||
type_ok = type_ok || (ret == 0 && arg_type_len != 1); // or NULL is accepted for an instance
|
||||
|
||||
if (!type_ok) {
|
||||
berry_log_C("Unexpected argument type '%c', expected '%s'", provided_type, arg_type);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// non-simple type
|
||||
if (be_isinstance(vm, idx)) {
|
||||
// check if the instance is a subclass of `bytes()``
|
||||
be_getbuiltin(vm, "bytes"); // add "list" class
|
||||
if (be_isderived(vm, idx)) {
|
||||
be_pop(vm, 1);
|
||||
be_getmember(vm, idx, "_buffer");
|
||||
be_pushvalue(vm, idx);
|
||||
be_call(vm, 1);
|
||||
int32_t ret = (int32_t) be_tocomptr(vm, -2);
|
||||
be_pop(vm, 2);
|
||||
return ret;
|
||||
} else {
|
||||
be_pop(vm, 1);
|
||||
be_getmember(vm, idx, "_p");
|
||||
int32_t ret = be_convert_single_elt(vm, -1, nullptr); // recurse
|
||||
be_pop(vm, 1);
|
||||
|
||||
if (arg_type_len > 1) {
|
||||
// Check type
|
||||
be_classof(vm, idx);
|
||||
bool class_found = be_find_class(vm, arg_type);
|
||||
// Stack: class_of_idx, class_of_target (or nil)
|
||||
if (class_found) {
|
||||
if (!be_isderived(vm, -2)) {
|
||||
berry_log_C("Unexpected class type '%s', expected '%s'", be_classname(vm, idx), arg_type);
|
||||
}
|
||||
} else {
|
||||
berry_log_C("Unable to find class '%s' (%d)", arg_type, arg_type_len);
|
||||
}
|
||||
be_pop(vm, 2);
|
||||
} else if (arg_type[0] != '.') {
|
||||
berry_log_C("Unexpected instance type '%s', expected '%s'", be_classname(vm, idx), arg_type);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
be_raise(vm, kTypeError, nullptr);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Generalized virtual members for modules
|
||||
*
|
||||
* Takes a pointer to be_constint_t array and size
|
||||
* Returns true if a match was found. In such case the result is on Berry stack
|
||||
*
|
||||
* Encoding depend on prefix (which is skipped when matching names):
|
||||
* 1. `COLOR_WHITE` int value
|
||||
* 3. `$SYMBOL_OK"` string pointer
|
||||
* 4. `&seg7_font` comptr
|
||||
\*********************************************************************************************/
|
||||
bool be_module_member(bvm *vm, const be_constint_t * definitions, size_t def_len);
|
||||
bool be_module_member(bvm *vm, const be_constint_t * definitions, size_t def_len) {
|
||||
int32_t argc = be_top(vm); // Get the number of arguments
|
||||
if (argc == 1 && be_isstring(vm, 1)) {
|
||||
const char * needle = be_tostring(vm, 1);
|
||||
int32_t idx;
|
||||
|
||||
idx = bin_search(needle, &definitions[0].name, sizeof(definitions[0]), def_len);
|
||||
if (idx >= 0) {
|
||||
// we did have a match
|
||||
const char * key = definitions[idx].name;
|
||||
switch (key[0]) {
|
||||
// switch depending on the first char of the key, indicating the type
|
||||
case '$': // string
|
||||
be_pushstring(vm, (const char*) definitions[idx].value);
|
||||
break;
|
||||
case '&': // native function
|
||||
be_pushntvfunction(vm, (bntvfunc) definitions[idx].value);
|
||||
break;
|
||||
default: // int
|
||||
be_pushint(vm, definitions[idx].value);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
|
@ -459,7 +110,6 @@ void BrTimeoutStart(void) {
|
|||
if (0 == berry.timeout) {
|
||||
berry.timeout = 1; // rare case when value accidentally computes to zero
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void BrTimeoutYield(void) {
|
||||
|
|
|
@ -39,7 +39,7 @@ extern "C" {
|
|||
// virtual member
|
||||
int gp_member(bvm *vm);
|
||||
int gp_member(bvm *vm) {
|
||||
if (be_module_member(vm, lv_gpio_constants, lv_gpio_constants_size)) {
|
||||
if (be_const_member(vm, lv_gpio_constants, lv_gpio_constants_size)) {
|
||||
be_return(vm);
|
||||
} else {
|
||||
be_return_nil(vm);
|
||||
|
|
|
@ -50,11 +50,11 @@ extern "C" {
|
|||
light_controller.calcLevels(channels);
|
||||
uint8_t bri = light_state.getBri();
|
||||
|
||||
// map_insert_int(vm, "_devices_present", TasmotaGlobal.devices_present);
|
||||
// map_insert_int(vm, "_light_device", Light.device);
|
||||
// map_insert_int(vm, "_light_subtype", Light.subtype);
|
||||
// map_insert_int(vm, "_light_multi", Light.pwm_multi_channels);
|
||||
// map_insert_int(vm, "_light_linked", light_controller.isCTRGBLinked());
|
||||
// be_map_insert_int(vm, "_devices_present", TasmotaGlobal.devices_present);
|
||||
// be_map_insert_int(vm, "_light_device", Light.device);
|
||||
// be_map_insert_int(vm, "_light_subtype", Light.subtype);
|
||||
// be_map_insert_int(vm, "_light_multi", Light.pwm_multi_channels);
|
||||
// be_map_insert_int(vm, "_light_linked", light_controller.isCTRGBLinked());
|
||||
|
||||
if (!Light.pwm_multi_channels) {
|
||||
uint32_t subtype = Light.subtype; // virtual sub-type, for SO37 128
|
||||
|
@ -64,7 +64,7 @@ extern "C" {
|
|||
if (light_controller.isCTRGBLinked() && (light_num == 0)) {
|
||||
data_present = true; // valid combination
|
||||
if (subtype >= LST_RGBW) {
|
||||
map_insert_str(vm, "colormode", (light_state.getColorMode() & LCM_RGB ? "rgb" : "ct"));
|
||||
be_map_insert_str(vm, "colormode", (light_state.getColorMode() & LCM_RGB ? "rgb" : "ct"));
|
||||
}
|
||||
}
|
||||
if (!light_controller.isCTRGBLinked()) {
|
||||
|
@ -83,33 +83,33 @@ extern "C" {
|
|||
|
||||
if (data_present) {
|
||||
// see ResponseLightState()
|
||||
map_insert_bool(vm, "power", bitRead(TasmotaGlobal.power, light_num + Light.device - 1));
|
||||
map_insert_int(vm, "bri", bri);
|
||||
be_map_insert_bool(vm, "power", bitRead(TasmotaGlobal.power, light_num + Light.device - 1));
|
||||
be_map_insert_int(vm, "bri", bri);
|
||||
|
||||
if (subtype >= LST_RGB) {
|
||||
uint16_t hue;
|
||||
uint8_t sat, bri;
|
||||
light_state.getHSB(&hue, &sat, &bri);
|
||||
map_insert_int(vm, "hue", hue);
|
||||
map_insert_int(vm, "sat", sat);
|
||||
be_map_insert_int(vm, "hue", hue);
|
||||
be_map_insert_int(vm, "sat", sat);
|
||||
}
|
||||
if ((LST_COLDWARM == subtype) || (LST_RGBW <= subtype)) {
|
||||
map_insert_int(vm, "ct", light_state.getCT());
|
||||
be_map_insert_int(vm, "ct", light_state.getCT());
|
||||
}
|
||||
if (subtype >= LST_RGB) {
|
||||
snprintf(s_rgb, sizeof(s_rgb), PSTR("%02X%02X%02X"), channels[0], channels[1], channels[2]);
|
||||
map_insert_str(vm, "rgb", s_rgb);
|
||||
be_map_insert_str(vm, "rgb", s_rgb);
|
||||
}
|
||||
if (subtype > LST_NONE) {
|
||||
map_insert_list_uint8(vm, "channels", &channels[chanidx], subtype);
|
||||
be_map_insert_list_uint8(vm, "channels", &channels[chanidx], subtype);
|
||||
}
|
||||
}
|
||||
} else { // Light.pwm_multi_channels
|
||||
if ((light_num >= 0) && (light_num < LST_MAX)) {
|
||||
data_present = true;
|
||||
map_insert_bool(vm, "power", Light.power & (1 << light_num));
|
||||
map_insert_int(vm, "bri", Light.current_color[light_num]);
|
||||
map_insert_list_uint8(vm, "channels", &channels[light_num], 1);
|
||||
be_map_insert_bool(vm, "power", Light.power & (1 << light_num));
|
||||
be_map_insert_int(vm, "bri", Light.current_color[light_num]);
|
||||
be_map_insert_list_uint8(vm, "channels", &channels[light_num], 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
#include <berry.h>
|
||||
#include "lvgl.h"
|
||||
#include "be_lvgl.h"
|
||||
#include "be_mapping.h"
|
||||
#include "be_ctypes.h"
|
||||
#include "Adafruit_LvGL_Glue.h"
|
||||
|
||||
|
@ -35,6 +35,8 @@
|
|||
// Berry easy logging
|
||||
extern "C" {
|
||||
extern void berry_log_C(const char * berry_buf, ...);
|
||||
extern const be_ntv_class_def_t lv_classes[];
|
||||
extern const size_t lv_classes_size;
|
||||
}
|
||||
|
||||
extern Adafruit_LvGL_Glue * glue;
|
||||
|
@ -99,80 +101,6 @@ LVBE_globals lvbe;
|
|||
extern void start_lvgl(const char * uconfig);
|
||||
extern void lv_ex_get_started_1(void);
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Calling any LVGL function with auto-mapping
|
||||
*
|
||||
\*********************************************************************************************/
|
||||
|
||||
// check input parameters, and create callbacks if needed
|
||||
// change values in place
|
||||
//
|
||||
// Format:
|
||||
// - either a lowercase character encoding for a simple type
|
||||
// - 'b': bool
|
||||
// - 'i': int (int32_t)
|
||||
// - 's': string (const char *)
|
||||
//
|
||||
// - a class name surroungded by parenthesis
|
||||
// - '(lv_button)' -> lv_button class or derived
|
||||
// - '[lv_event_cb]' -> callback type, still prefixed with '^' to mark that it is cb
|
||||
//
|
||||
void be_check_arg_type(bvm *vm, int32_t arg_start, int32_t argc, const char * arg_type, int32_t p[8]);
|
||||
void be_check_arg_type(bvm *vm, int32_t arg_start, int32_t argc, const char * arg_type, int32_t p[8]) {
|
||||
bool arg_type_check = (arg_type != nullptr); // is type checking activated
|
||||
int32_t arg_idx = 0; // position in arg_type string
|
||||
char type_short_name[32];
|
||||
|
||||
for (uint32_t i = 0; i < argc; i++) {
|
||||
type_short_name[0] = 0; // clear string
|
||||
// extract individual type
|
||||
if (nullptr != arg_type) {
|
||||
switch (arg_type[arg_idx]) {
|
||||
case '.':
|
||||
case 'a'...'z':
|
||||
type_short_name[0] = arg_type[arg_idx];
|
||||
type_short_name[1] = 0;
|
||||
arg_idx++;
|
||||
break;
|
||||
case '(':
|
||||
case '^':
|
||||
{
|
||||
uint32_t prefix = 0;
|
||||
if (arg_type[arg_idx] == '^') {
|
||||
type_short_name[0] = '^';
|
||||
type_short_name[1] = 0;
|
||||
prefix = 1;
|
||||
}
|
||||
uint32_t offset = 0;
|
||||
arg_idx++;
|
||||
while (arg_type[arg_idx + offset] != ')' && arg_type[arg_idx + offset] != '^' && arg_type[arg_idx + offset] != 0 && offset+prefix+1 < sizeof(type_short_name)) {
|
||||
type_short_name[offset+prefix] = arg_type[arg_idx + offset];
|
||||
type_short_name[offset+prefix+1] = 0;
|
||||
offset++;
|
||||
}
|
||||
if (arg_type[arg_idx + offset] == 0) {
|
||||
arg_type = nullptr; // no more parameters, stop iterations
|
||||
}
|
||||
arg_idx += offset + 1;
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
arg_type = nullptr; // stop iterations
|
||||
break;
|
||||
}
|
||||
}
|
||||
// AddLog(LOG_LEVEL_INFO, ">> be_call_c_func arg %i, type %s", i, arg_type_check ? type_short_name : "<null>");
|
||||
p[i] = be_convert_single_elt(vm, i + arg_start, arg_type_check ? type_short_name : nullptr, (void*) p[0]);
|
||||
}
|
||||
|
||||
// check if we are missing arguments
|
||||
if (arg_type != nullptr && arg_type[arg_idx] != 0) {
|
||||
berry_log_C("Missing arguments, remaining type '%s'", &arg_type[arg_idx]);
|
||||
}
|
||||
}
|
||||
|
||||
typedef int32_t (*fn_any_callable)(int32_t p0, int32_t p1, int32_t p2, int32_t p3,
|
||||
int32_t p4, int32_t p5, int32_t p6, int32_t p7);
|
||||
extern "C" {
|
||||
|
||||
void lv_init_set_member(bvm *vm, int index, void * ptr);
|
||||
|
@ -205,15 +133,15 @@ extern "C" {
|
|||
// berry_log_C("lvx_member looking for method '%s' of class '%s'", method_name, class_name);
|
||||
|
||||
// look for class descriptor
|
||||
int32_t class_idx = bin_search(class_name, &lv_classes[0].name, sizeof(lv_classes[0]), lv_classes_size);
|
||||
int32_t class_idx = be_map_bin_search(class_name, &lv_classes[0].name, sizeof(lv_classes[0]), lv_classes_size);
|
||||
if (class_idx >= 0) {
|
||||
const lvbe_call_c_t * methods_calls = lv_classes[class_idx].func_table;
|
||||
const be_ntv_func_def_t * methods_calls = lv_classes[class_idx].func_table;
|
||||
size_t methods_size = lv_classes[class_idx].size;
|
||||
|
||||
int32_t method_idx = bin_search(method_name, methods_calls, sizeof(lvbe_call_c_t), methods_size);
|
||||
int32_t method_idx = be_map_bin_search(method_name, methods_calls, sizeof(be_ntv_func_def_t), methods_size);
|
||||
if (method_idx >= 0) {
|
||||
// method found
|
||||
const lvbe_call_c_t * method = &methods_calls[method_idx];
|
||||
const be_ntv_func_def_t * method = &methods_calls[method_idx];
|
||||
// berry_log_C("lvx_member method found func=%p return_type=%s arg_type=%s", method->func, method->return_type, method->arg_type);
|
||||
// push native closure
|
||||
be_pushntvclosure(vm, &lvx_call_c, 3); // 3 upvals
|
||||
|
@ -245,63 +173,6 @@ extern "C" {
|
|||
}
|
||||
be_raise(vm, kTypeError, nullptr);
|
||||
}
|
||||
|
||||
int be_call_c_func(bvm *vm, void * func, const char * return_type, const char * arg_type) {
|
||||
// AddLog(LOG_LEVEL_INFO, ">> be_call_c_func, func=%p, return_type=%s, arg_type=%s", func, return_type ? return_type : "", arg_type ? arg_type : "");
|
||||
int32_t p[8] = {0,0,0,0,0,0,0,0};
|
||||
int32_t argc = be_top(vm); // Get the number of arguments
|
||||
|
||||
// the following describe the active payload for the C function (start and count)
|
||||
// this is because the `init()` constructor first arg is not passed to the C function
|
||||
int32_t arg_start = 1; // start with standard values
|
||||
int32_t arg_count = argc;
|
||||
|
||||
// check if we call a constructor, in this case we store the return type into the new object
|
||||
// check if we call a constructor with a comptr as first arg
|
||||
if (return_type && return_type[0] == '+') {
|
||||
if (argc > 1 && be_iscomptr(vm, 2)) {
|
||||
lv_obj_t * obj = (lv_obj_t*) be_tocomptr(vm, 2);
|
||||
lv_init_set_member(vm, 1, obj);
|
||||
be_return_nil(vm);
|
||||
} else {
|
||||
// we need to discard the first arg
|
||||
arg_start++;
|
||||
arg_count--;
|
||||
}
|
||||
}
|
||||
|
||||
fn_any_callable f = (fn_any_callable) func;
|
||||
// AddLog(LOG_LEVEL_INFO, ">> before be_check_arg_type argc=%i - %i", arg_count, arg_start);
|
||||
be_check_arg_type(vm, arg_start, arg_count, arg_type, p);
|
||||
// AddLog(LOG_LEVEL_INFO, ">> be_call_c_func(%p) - %p,%p,%p,%p,%p - %s", f, p[0], p[1], p[2], p[3], p[4], return_type ? return_type : "NULL");
|
||||
int32_t ret = (*f)(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
|
||||
// AddLog(LOG_LEVEL_INFO, ">> be_call_c_func, ret = %p", ret);
|
||||
if ((return_type == nullptr) || (strlen(return_type) == 0)) { be_return_nil(vm); } // does not return
|
||||
else if (return_type[0] == '+') {
|
||||
lv_obj_t * obj = (lv_obj_t*) ret;
|
||||
lv_init_set_member(vm, 1, obj);
|
||||
be_return_nil(vm);
|
||||
}
|
||||
else if (strlen(return_type) == 1) {
|
||||
switch (return_type[0]) {
|
||||
case '.': // fallback next
|
||||
case 'i': be_pushint(vm, ret); break;
|
||||
case 'b': be_pushbool(vm, ret); break;
|
||||
case 's': be_pushstring(vm, (const char*) ret); break;
|
||||
case 'c': be_pushint(vm, ret); break; // TODO missing 'c' general callback type
|
||||
default: be_raise(vm, "internal_error", "Unsupported return type"); break;
|
||||
}
|
||||
be_return(vm);
|
||||
} else { // class name
|
||||
// AddLog(LOG_LEVEL_INFO, ">> be_call_c_func, create_obj ret=%i return_type=%s", ret, return_type);
|
||||
be_find_class(vm, return_type);
|
||||
be_pushcomptr(vm, (void*) ret); // stack = class, ptr
|
||||
be_pushcomptr(vm, (void*) -1); // stack = class, ptr, -1
|
||||
be_call(vm, 2); // instanciate with 2 arguments, stack = instance, -1, ptr
|
||||
be_pop(vm, 2); // stack = instance
|
||||
be_return(vm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
|
@ -396,7 +267,7 @@ extern "C" {
|
|||
typedef lv_obj_t* (*fn_lvobj__void)(void); // f() -> newly created lv_obj()
|
||||
int lv0_lvobj__void_call(bvm *vm, fn_lvobj__void func) {
|
||||
lv_obj_t * obj = (*func)();
|
||||
be_find_class(vm, "lv.lv_obj");
|
||||
be_find_global_or_module_member(vm, "lv.lv_obj");
|
||||
be_pushcomptr(vm, (void*) -1); // stack = class, -1
|
||||
be_pushcomptr(vm, (void*) obj); // stack = class, -1, ptr
|
||||
be_call(vm, 2); // instanciate, stack = instance (don't call init() )
|
||||
|
@ -413,7 +284,7 @@ extern "C" {
|
|||
if (argc == 1 && be_isstring(vm, 1)) {
|
||||
lv_font_t * font = lv_font_load(be_tostring(vm, 1));
|
||||
if (font != nullptr) {
|
||||
be_find_class(vm, "lv.lv_font");
|
||||
be_find_global_or_module_member(vm, "lv.lv_font");
|
||||
be_pushcomptr(vm, font);
|
||||
be_call(vm, 1);
|
||||
be_pop(vm, 1);
|
||||
|
@ -441,7 +312,7 @@ extern "C" {
|
|||
lv_font_t * font = info.font;
|
||||
|
||||
if (font != nullptr) {
|
||||
be_find_class(vm, "lv.lv_font");
|
||||
be_find_global_or_module_member(vm, "lv.lv_font");
|
||||
be_pushcomptr(vm, font);
|
||||
be_call(vm, 1);
|
||||
be_pop(vm, 1);
|
||||
|
@ -637,7 +508,7 @@ extern "C" {
|
|||
be_raisef(vm, "value_error", "unknown font size '%s-%i'", name, size);
|
||||
}
|
||||
|
||||
be_find_class(vm, "lv.lv_font");
|
||||
be_find_global_or_module_member(vm, "lv.lv_font");
|
||||
be_pushcomptr(vm, (void*)font_entry->font);
|
||||
be_call(vm, 1);
|
||||
be_pop(vm, 1);
|
||||
|
@ -674,10 +545,10 @@ extern "C" {
|
|||
* Responds to virtual constants
|
||||
\*********************************************************************************************/
|
||||
|
||||
extern const lvbe_call_c_t lv_func[];
|
||||
extern const be_ntv_func_def_t lv_func[];
|
||||
extern const size_t lv_func_size;
|
||||
|
||||
extern const be_constint_t lv0_constants[];
|
||||
extern const be_const_member_t lv0_constants[];
|
||||
extern const size_t lv0_constants_size;
|
||||
|
||||
extern const be_ctypes_class_by_name_t be_ctypes_lvgl_classes[];
|
||||
|
@ -686,7 +557,7 @@ extern "C" {
|
|||
int lv0_member(bvm *vm);
|
||||
int lv0_member(bvm *vm) {
|
||||
// first try the standard way
|
||||
if (be_module_member(vm, lv0_constants, lv0_constants_size)) {
|
||||
if (be_const_member(vm, lv0_constants, lv0_constants_size)) {
|
||||
be_return(vm);
|
||||
}
|
||||
// try alternative members
|
||||
|
@ -698,9 +569,9 @@ extern "C" {
|
|||
// search for a class with this name
|
||||
char cl_prefixed[32];
|
||||
snprintf(cl_prefixed, sizeof(cl_prefixed), "lv_%s", needle); // we try both actual name and prefixed with `lv_` so both `lv.obj` and `lv.lv_obj` work
|
||||
idx = bin_search(cl_prefixed, &lv_classes[0].name, sizeof(lv_classes[0]), lv_classes_size);
|
||||
idx = be_map_bin_search(cl_prefixed, &lv_classes[0].name, sizeof(lv_classes[0]), lv_classes_size);
|
||||
if (idx < 0) {
|
||||
idx = bin_search(needle, &lv_classes[0].name, sizeof(lv_classes[0]), lv_classes_size);
|
||||
idx = be_map_bin_search(needle, &lv_classes[0].name, sizeof(lv_classes[0]), lv_classes_size);
|
||||
}
|
||||
if (idx >= 0) {
|
||||
// we did have a match
|
||||
|
@ -708,9 +579,9 @@ extern "C" {
|
|||
be_return(vm);
|
||||
}
|
||||
// same search for ctypes
|
||||
idx = bin_search(cl_prefixed, &be_ctypes_lvgl_classes[0].name, sizeof(be_ctypes_lvgl_classes[0]), be_ctypes_lvgl_classes_size);
|
||||
idx = be_map_bin_search(cl_prefixed, &be_ctypes_lvgl_classes[0].name, sizeof(be_ctypes_lvgl_classes[0]), be_ctypes_lvgl_classes_size);
|
||||
if (idx < 0) {
|
||||
idx = bin_search(needle, &be_ctypes_lvgl_classes[0].name, sizeof(be_ctypes_lvgl_classes[0]), be_ctypes_lvgl_classes_size);
|
||||
idx = be_map_bin_search(needle, &be_ctypes_lvgl_classes[0].name, sizeof(be_ctypes_lvgl_classes[0]), be_ctypes_lvgl_classes_size);
|
||||
}
|
||||
if (idx >= 0) {
|
||||
// we did have a match
|
||||
|
@ -719,9 +590,9 @@ extern "C" {
|
|||
}
|
||||
|
||||
// search for a method with this name
|
||||
idx = bin_search(needle, &lv_func[0].name, sizeof(lv_func[0]), lv_func_size);
|
||||
idx = be_map_bin_search(needle, &lv_func[0].name, sizeof(lv_func[0]), lv_func_size);
|
||||
if (idx >= 0) {
|
||||
const lvbe_call_c_t * method = &lv_func[idx];
|
||||
const be_ntv_func_def_t * method = &lv_func[idx];
|
||||
// push native closure
|
||||
be_pushntvclosure(vm, &lvx_call_c, 3); // 3 upvals
|
||||
|
||||
|
@ -803,7 +674,7 @@ extern "C" {
|
|||
lv_indev_t * indev = lv_indev_drv_register(&lvbe.indev_drv);
|
||||
lvbe.indev_list.addHead(indev); // keep track of indevs
|
||||
|
||||
be_find_class(vm, "lv.lv_indev");
|
||||
be_find_global_or_module_member(vm, "lv.lv_indev");
|
||||
be_pushint(vm, (int32_t) indev);
|
||||
be_call(vm, 1);
|
||||
be_pop(vm, 1);
|
||||
|
@ -859,7 +730,7 @@ extern "C" {
|
|||
void * obj = nullptr;
|
||||
int argc = be_top(vm);
|
||||
if (argc > 1) {
|
||||
obj = (void*) be_convert_single_elt(vm, 2);
|
||||
obj = (void*) be_convert_single_elt(vm, 2, NULL, NULL);
|
||||
}
|
||||
lv_init_set_member(vm, 1, obj);
|
||||
be_return_nil(vm);
|
||||
|
@ -885,7 +756,7 @@ extern "C" {
|
|||
lv_style_t * style = nullptr;
|
||||
|
||||
if (argc > 1) {
|
||||
style = (lv_style_t*) be_convert_single_elt(vm, 2);
|
||||
style = (lv_style_t*) be_convert_single_elt(vm, 2, NULL, NULL);
|
||||
}
|
||||
if (style == nullptr) {
|
||||
style = (lv_style_t*) be_malloc(vm, sizeof(lv_style_t));
|
||||
|
|
|
@ -181,10 +181,10 @@ extern "C" {
|
|||
int32_t top = be_top(vm); // Get the number of arguments
|
||||
if (top == 1) { // no argument (instance only)
|
||||
be_newobject(vm, "map");
|
||||
map_insert_int(vm, "utc", Rtc.utc_time);
|
||||
map_insert_int(vm, "local", Rtc.local_time);
|
||||
map_insert_int(vm, "restart", Rtc.restart_time);
|
||||
map_insert_int(vm, "timezone", Rtc.time_timezone);
|
||||
be_map_insert_int(vm, "utc", Rtc.utc_time);
|
||||
be_map_insert_int(vm, "local", Rtc.local_time);
|
||||
be_map_insert_int(vm, "restart", Rtc.restart_time);
|
||||
be_map_insert_int(vm, "timezone", Rtc.time_timezone);
|
||||
be_pop(vm, 1);
|
||||
be_return(vm);
|
||||
}
|
||||
|
@ -198,14 +198,14 @@ extern "C" {
|
|||
int32_t top = be_top(vm); // Get the number of arguments
|
||||
if (top == 1) { // no argument (instance only)
|
||||
be_newobject(vm, "map");
|
||||
map_insert_int(vm, "flash", ESP.getFlashChipSize() / 1024);
|
||||
map_insert_int(vm, "program", ESP_getSketchSize() / 1024);
|
||||
map_insert_int(vm, "program_free", ESP.getFreeSketchSpace() / 1024);
|
||||
map_insert_int(vm, "heap_free", ESP_getFreeHeap() / 1024);
|
||||
map_insert_int(vm, "frag", ESP_getHeapFragmentation());
|
||||
be_map_insert_int(vm, "flash", ESP.getFlashChipSize() / 1024);
|
||||
be_map_insert_int(vm, "program", ESP_getSketchSize() / 1024);
|
||||
be_map_insert_int(vm, "program_free", ESP.getFreeSketchSpace() / 1024);
|
||||
be_map_insert_int(vm, "heap_free", ESP_getFreeHeap() / 1024);
|
||||
be_map_insert_int(vm, "frag", ESP_getHeapFragmentation());
|
||||
if (UsePSRAM()) {
|
||||
map_insert_int(vm, "psram", ESP.getPsramSize() / 1024);
|
||||
map_insert_int(vm, "psram_free", ESP.getFreePsram() / 1024);
|
||||
be_map_insert_int(vm, "psram", ESP.getPsramSize() / 1024);
|
||||
be_map_insert_int(vm, "psram_free", ESP.getFreePsram() / 1024);
|
||||
}
|
||||
be_pop(vm, 1);
|
||||
be_return(vm);
|
||||
|
@ -222,17 +222,17 @@ extern "C" {
|
|||
be_newobject(vm, "map");
|
||||
if (Settings->flag4.network_wifi) {
|
||||
int32_t rssi = WiFi.RSSI();
|
||||
map_insert_int(vm, "rssi", rssi);
|
||||
map_insert_int(vm, "quality", WifiGetRssiAsQuality(rssi));
|
||||
be_map_insert_int(vm, "rssi", rssi);
|
||||
be_map_insert_int(vm, "quality", WifiGetRssiAsQuality(rssi));
|
||||
#if LWIP_IPV6
|
||||
String ipv6_addr = WifiGetIPv6();
|
||||
if (ipv6_addr != "") {
|
||||
map_insert_str(vm, "ip6", ipv6_addr.c_str());
|
||||
be_map_insert_str(vm, "ip6", ipv6_addr.c_str());
|
||||
}
|
||||
#endif
|
||||
if (static_cast<uint32_t>(WiFi.localIP()) != 0) {
|
||||
map_insert_str(vm, "mac", WiFi.macAddress().c_str());
|
||||
map_insert_str(vm, "ip", WiFi.localIP().toString().c_str());
|
||||
be_map_insert_str(vm, "mac", WiFi.macAddress().c_str());
|
||||
be_map_insert_str(vm, "ip", WiFi.localIP().toString().c_str());
|
||||
}
|
||||
}
|
||||
be_pop(vm, 1);
|
||||
|
@ -250,8 +250,8 @@ extern "C" {
|
|||
be_newobject(vm, "map");
|
||||
#ifdef USE_ETHERNET
|
||||
if (static_cast<uint32_t>(EthernetLocalIP()) != 0) {
|
||||
map_insert_str(vm, "mac", EthernetMacAddress().c_str());
|
||||
map_insert_str(vm, "ip", EthernetLocalIP().toString().c_str());
|
||||
be_map_insert_str(vm, "mac", EthernetMacAddress().c_str());
|
||||
be_map_insert_str(vm, "ip", EthernetLocalIP().toString().c_str());
|
||||
}
|
||||
#endif
|
||||
be_pop(vm, 1);
|
||||
|
@ -262,14 +262,14 @@ extern "C" {
|
|||
|
||||
static void l_push_time(bvm *vm, struct tm *t, const char *unparsed) {
|
||||
be_newobject(vm, "map");
|
||||
map_insert_int(vm, "year", t->tm_year + 1900);
|
||||
map_insert_int(vm, "month", t->tm_mon + 1);
|
||||
map_insert_int(vm, "day", t->tm_mday);
|
||||
map_insert_int(vm, "hour", t->tm_hour);
|
||||
map_insert_int(vm, "min", t->tm_min);
|
||||
map_insert_int(vm, "sec", t->tm_sec);
|
||||
map_insert_int(vm, "weekday", t->tm_wday);
|
||||
if (unparsed) map_insert_str(vm, "unparsed", unparsed);
|
||||
be_map_insert_int(vm, "year", t->tm_year + 1900);
|
||||
be_map_insert_int(vm, "month", t->tm_mon + 1);
|
||||
be_map_insert_int(vm, "day", t->tm_mday);
|
||||
be_map_insert_int(vm, "hour", t->tm_hour);
|
||||
be_map_insert_int(vm, "min", t->tm_min);
|
||||
be_map_insert_int(vm, "sec", t->tm_sec);
|
||||
be_map_insert_int(vm, "weekday", t->tm_wday);
|
||||
if (unparsed) be_map_insert_str(vm, "unparsed", unparsed);
|
||||
be_pop(vm, 1);
|
||||
}
|
||||
|
||||
|
@ -332,27 +332,14 @@ extern "C" {
|
|||
// ESP object
|
||||
int32_t l_yield(bvm *vm);
|
||||
int32_t l_yield(bvm *vm) {
|
||||
BrTimeoutYield(); // reset timeout
|
||||
be_return_nil(vm);
|
||||
return be_call_c_func(vm, (void*) &BrTimeoutYield, NULL, "-");
|
||||
}
|
||||
|
||||
// Berry: tasmota.scale_uint(int * 5) -> int
|
||||
//
|
||||
int32_t l_scaleuint(struct bvm *vm);
|
||||
int32_t l_scaleuint(struct bvm *vm) {
|
||||
int32_t top = be_top(vm); // Get the number of arguments
|
||||
if (top == 6 && be_isint(vm, 2) && be_isint(vm, 3) && be_isint(vm, 4) && be_isint(vm, 5) && be_isint(vm, 6)) { // only 1 argument of type string accepted
|
||||
int32_t v = be_toint(vm, 2);
|
||||
int32_t from1 = be_toint(vm, 3);
|
||||
int32_t from2 = be_toint(vm, 4);
|
||||
int32_t to1 = be_toint(vm, 5);
|
||||
int32_t to2 = be_toint(vm, 6);
|
||||
|
||||
int32_t ret = changeUIntScale(v, from1, from2, to1, to2);
|
||||
be_pushint(vm, ret);
|
||||
be_return(vm);
|
||||
}
|
||||
be_raise(vm, kTypeError, nullptr);
|
||||
return be_call_c_func(vm, (void*) &changeUIntScale, "i", "-iiiii");
|
||||
}
|
||||
|
||||
int32_t l_respCmnd(bvm *vm);
|
||||
|
@ -379,20 +366,17 @@ extern "C" {
|
|||
|
||||
int32_t l_respCmndDone(bvm *vm);
|
||||
int32_t l_respCmndDone(bvm *vm) {
|
||||
ResponseCmndDone();
|
||||
be_return_nil(vm);
|
||||
return be_call_c_func(vm, (void*) &ResponseCmndDone, NULL, "-");
|
||||
}
|
||||
|
||||
int32_t l_respCmndError(bvm *vm);
|
||||
int32_t l_respCmndError(bvm *vm) {
|
||||
ResponseCmndError();
|
||||
be_return_nil(vm);
|
||||
return be_call_c_func(vm, (void*) &ResponseCmndError, NULL, "-");
|
||||
}
|
||||
|
||||
int32_t l_respCmndFailed(bvm *vm);
|
||||
int32_t l_respCmndFailed(bvm *vm) {
|
||||
ResponseCmndFailed();
|
||||
be_return_nil(vm);
|
||||
return be_call_c_func(vm, (void*) &ResponseCmndFailed, NULL, "-");
|
||||
}
|
||||
|
||||
// update XdrvMailbox.command with actual command
|
||||
|
|
|
@ -57,7 +57,7 @@ String wc_UrlEncode(const String& text) {
|
|||
/*********************************************************************************************\
|
||||
* Int constants
|
||||
*********************************************************************************************/
|
||||
// const be_constint_t webserver_constants[] = {
|
||||
// const be_const_member_t webserver_constants[] = {
|
||||
// { "BUTTON_CONFIGURATION", BUTTON_CONFIGURATION },
|
||||
// { "BUTTON_INFORMATION", BUTTON_INFORMATION },
|
||||
// { "BUTTON_MAIN", BUTTON_MAIN },
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
/*********************************************************************************************\
|
||||
* Int constants
|
||||
*********************************************************************************************/
|
||||
const be_constint_t webserver_constants[] = {
|
||||
const be_const_member_t webserver_constants[] = {
|
||||
{ "BUTTON_CONFIGURATION", BUTTON_CONFIGURATION },
|
||||
{ "BUTTON_INFORMATION", BUTTON_INFORMATION },
|
||||
{ "BUTTON_MAIN", BUTTON_MAIN },
|
||||
|
@ -51,7 +51,7 @@ extern "C" {
|
|||
if (argc == 1 && be_isstring(vm, 1)) {
|
||||
const char * needle = be_tostring(vm, 1);
|
||||
|
||||
int32_t constant_idx = bin_search(needle, &webserver_constants[0].name, sizeof(webserver_constants[0]), ARRAY_SIZE(webserver_constants));
|
||||
int32_t constant_idx = be_map_bin_search(needle, &webserver_constants[0].name, sizeof(webserver_constants[0]), ARRAY_SIZE(webserver_constants));
|
||||
|
||||
if (constant_idx >= 0) {
|
||||
// we did have a match, low == high
|
||||
|
|
|
@ -320,13 +320,14 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#include "be_ctypes.h"
|
||||
#include "be_mapping.h"
|
||||
""")
|
||||
|
||||
for subtype, flv in lv.items():
|
||||
print(f"/* `lv_{subtype}` methods */")
|
||||
if subtype in lv_widgets:
|
||||
print(f"#ifdef BE_LV_WIDGET_{subtype.upper()}")
|
||||
print(f"const lvbe_call_c_t lv_{subtype}_func[] = {{")
|
||||
print(f"const be_ntv_func_def_t lv_{subtype}_func[] = {{")
|
||||
|
||||
func_out = {} # used to sort output
|
||||
for f in flv:
|
||||
|
@ -361,7 +362,7 @@ print()
|
|||
# print the global map of classes
|
||||
print(f"""
|
||||
// map of clases
|
||||
const lvbe_call_c_classes_t lv_classes[] = {{""")
|
||||
const be_ntv_class_def_t lv_classes[] = {{""")
|
||||
|
||||
for subtype in sorted(lv):
|
||||
# for subtype, flv in lv.items():
|
||||
|
@ -391,7 +392,7 @@ for subtype, flv in lv.items():
|
|||
if len(c_ret_type) > 1: c_ret_type = "lv." + c_ret_type
|
||||
|
||||
if c_func_name.endswith("_create"):
|
||||
c_ret_type = "+" # constructor, init method does not return any value
|
||||
c_ret_type = "+_p" # constructor, init method does not return any value
|
||||
if subtype in lv_widgets:
|
||||
print(f"#ifdef BE_LV_WIDGET_{subtype.upper()}")
|
||||
print(f" int be_ntv_lv_{subtype}_init(bvm *vm) {{ return be_call_c_func(vm, (void*) &{orig_func_name}, \"{c_ret_type}\", { c_argc if c_argc else 'nullptr'}); }}")
|
||||
|
@ -401,8 +402,8 @@ for subtype, flv in lv.items():
|
|||
|
||||
print("""
|
||||
// create font either empty or from parameter on stack
|
||||
int lvbe_font_create(bvm *vm) { return be_call_c_func(vm, NULL, "+lv_font", ""); }
|
||||
int lvbe_theme_create(bvm *vm) { return be_call_c_func(vm, NULL, "+lv_theme", ""); }
|
||||
int lvbe_font_create(bvm *vm) { return be_call_c_func(vm, NULL, "+_p", ""); }
|
||||
int lvbe_theme_create(bvm *vm) { return be_call_c_func(vm, NULL, "+_p", ""); }
|
||||
""")
|
||||
|
||||
print()
|
||||
|
@ -660,7 +661,7 @@ print("""/********************************************************************
|
|||
#ifdef USE_LVGL
|
||||
|
||||
#include "lvgl.h"
|
||||
#include "be_lvgl.h"
|
||||
#include "be_mapping.h"
|
||||
#include "lv_theme_openhasp.h"
|
||||
|
||||
extern int lv0_member(bvm *vm); // resolve virtual members
|
||||
|
@ -685,7 +686,7 @@ static int lv_get_ver_res(void) {
|
|||
}
|
||||
|
||||
/* `lv` methods */
|
||||
const lvbe_call_c_t lv_func[] = {
|
||||
const be_ntv_func_def_t lv_func[] = {
|
||||
""")
|
||||
|
||||
func_out = {} # used to sort output
|
||||
|
@ -728,12 +729,7 @@ const size_t lv_func_size = sizeof(lv_func) / sizeof(lv_func[0]);
|
|||
|
||||
print("""
|
||||
|
||||
typedef struct be_constint_t {
|
||||
const char * name;
|
||||
int32_t value;
|
||||
} be_constint_t;
|
||||
|
||||
const be_constint_t lv0_constants[] = {
|
||||
const be_const_member_t lv0_constants[] = {
|
||||
""")
|
||||
|
||||
lv_module2 = {}
|
||||
|
|
|
@ -56,7 +56,7 @@ print(" * Generated code, don't edit")
|
|||
print(" *******************************************************************/")
|
||||
|
||||
print("""
|
||||
const be_constint_t lv_gpio_constants[] = {
|
||||
const be_const_member_t lv_gpio_constants[] = {
|
||||
""")
|
||||
|
||||
lv_module2 = {}
|
||||
|
|
Loading…
Reference in New Issue