YUI 提供了多引擎支持的 JavaScript API,包括 mquickjs、QuickJS 和 Mario 三种 JavaScript 引擎的绑定。
YUI 对象是所有 YUI 原生 API 的命名空间。
| 方法 | 参数 | 返回值 | 描述 | 支持引擎 |
|---|---|---|---|---|
YUI.log(...) |
...args |
undefined|number |
打印日志到控制台 | 全部 |
YUI.setText(layerId, text) |
layerId: string, text: string |
undefined|number |
设置图层文本内容 | 全部 |
YUI.getText(layerId) |
layerId: string |
string|null |
获取图层文本内容 | 全部 |
YUI.setBgColor(layerId, color) |
layerId: string, color: string |
undefined|number |
设置图层背景色 (#RRGGBB) | 全部 |
YUI.hide(layerId) |
layerId: string |
undefined|number |
隐藏图层 | 全部 |
YUI.show(layerId) |
layerId: string |
undefined|number |
显示图层 | 全部 |
YUI.renderFromJson(layerId, json) |
layerId: string, json: string |
number |
从JSON渲染图层树 | 全部 |
YUI.update(jsonString) |
jsonString: string|object |
number |
JSON增量更新 | 全部 |
YUI.themeLoad(path) |
path: string |
object|number |
加载主题文件 | 全部 |
YUI.themeSetCurrent(name) |
name: string |
boolean|number |
设置当前主题 | 全部 |
YUI.themeUnload(name) |
name: string |
boolean|number |
卸载主题 | 全部 |
YUI.themeApplyToTree() |
- | boolean|number |
应用主题到图层树 | 全部 |
YUI.inspect.enable() |
- | boolean|number |
启用全局 inspect 调试模式 | 全部 |
YUI.inspect.disable() |
- | boolean|number |
禁用全局 inspect 调试模式 | 全部 |
YUI.inspect.setLayer(layerId, enabled) |
layerId: string, enabled: boolean |
boolean|number |
为特定图层设置 inspect 模式 | 全部 |
YUI.inspect.setShowBounds(show) |
show: boolean |
boolean|number |
设置是否显示边界框 | 全部 |
YUI.inspect.setShowInfo(show) |
show: boolean |
boolean|number |
设置是否显示详细信息 | 全部 |
注意: 返回值类型取决于引擎,mquickjs 返回 undefined,QuickJS 返回 undefined,Mario 返回 number(0=成功,-1=失败)
Socket API 在 mquickjs 和 QuickJS 引擎中可用。
| 方法 | 参数 | 返回值 | 描述 |
|---|---|---|---|
Socket.socket(type) |
type: number |
number |
创建socket |
Socket.close(fd) |
fd: number |
number |
关闭socket |
Socket.shutdown(fd) |
fd: number |
number |
关闭socket连接 |
Socket.connect(fd, host, port, timeout) |
fd: number, host: string, port: number, timeout: number |
number |
连接到服务器 |
Socket.bind(fd, host, port) |
fd: number, host: string, port: number |
number |
绑定socket |
Socket.listen(fd, backlog) |
fd: number, backlog: number |
number |
监听连接 |
Socket.accept(fd) |
fd: number |
number |
接受连接 |
Socket.getsockname(fd) |
fd: number |
{ip: string, port: number}|number |
获取本地地址 |
Socket.getpeername(fd) |
fd: number |
{ip: string, port: number}|number |
获取对端地址 |
Socket.socketpair(domain, type, protocol) |
domain: number, type: number, protocol: number |
number[]|number |
创建socket对 |
Socket.setsockopt(fd, level, option_name, option_value, option_len) |
fd: number, level: number, option_name: number, option_value: any, option_len: number |
number |
设置socket选项 |
Socket.getsockopt(fd, level, option_name, option_len) |
fd: number, level: number, option_name: number, option_len: number |
any|number |
获取socket选项 |
Socket.send(fd, data, flags) |
fd: number, data: string, flags: number |
number |
发送数据 |
Socket.recv(fd, len, flags) |
fd: number, len: number, flags: number |
string|number |
接收数据 |
Socket.sendto(fd, data, flags, host, port) |
fd: number, data: string, flags: number, host: string, port: number |
number |
发送数据到指定地址 |
Socket.recvfrom(fd, len, flags) |
fd: number, len: number, flags: number |
{data: string, ip: string, port: number}|number |
从任意地址接收数据 |
Socket.inet_addr(ip) |
ip: string |
number |
IP地址转换 |
Socket.ntohl(value) |
value: number |
number |
网络字节序转换 |
Socket.make_sockaddr_in(ip, port) |
ip: string, port: number |
{ptr: number, size: number} |
创建sockaddr结构 |
YUI Native 函数定义
// 核心YUI函数
static JSValue js_yui_log(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
static JSValue js_set_text(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
static JSValue js_get_text(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
static JSValue js_set_bg_color(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
static JSValue js_hide(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
static JSValue js_show(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
static JSValue js_render_from_json(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
static JSValue js_yui_call(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
static JSValue js_yui_update(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
// 主题管理函数
static JSValue js_yui_themeLoad(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
static JSValue js_yui_themeSetCurrent(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
static JSValue js_yui_themeUnload(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
static JSValue js_yui_themeApplyToTree(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)
// Socket API (lib/jsmodule/js_socket.c)
static JSValue js_socket_create(JSContext* ctx, JSValue* this_val, int argc, JSValue* argv)
static JSValue js_socket_close(JSContext* ctx, JSValue* this_val, int argc, JSValue* argv)
static JSValue js_socket_shutdown(JSContext* ctx, JSValue* this_val, int argc, JSValue* argv)
static JSValue js_socket_connect(JSContext* ctx, JSValue* this_val, int argc, JSValue* argv)
static JSValue js_socket_bind(JSContext* ctx, JSValue* this_val, int argc, JSValue* argv)
static JSValue js_socket_listen(JSContext* ctx, JSValue* this_val, int argc, JSValue* argv)
static JSValue js_socket_accept(JSContext* ctx, JSValue* this_val, int argc, JSValue* argv)
static JSValue js_socket_getsockname(JSContext* ctx, JSValue* this_val, int argc, JSValue* argv)
static JSValue js_socket_getpeername(JSContext* ctx, JSValue* this_val, int argc, JSValue* argv)
static JSValue js_socket_socketpair(JSContext* ctx, JSValue* this_val, int argc, JSValue* argv)
static JSValue js_socket_setsockopt(JSContext* ctx, JSValue* this_val, int argc, JSValue* argv)
static JSValue js_socket_getsockopt(JSContext* ctx, JSValue* this_val, int argc, JSValue* argv)
static JSValue js_socket_send(JSContext* ctx, JSValue* this_val, int argc, JSValue* argv)
static JSValue js_socket_recv(JSContext* ctx, JSValue* this_val, int argc, JSValue* argv)
static JSValue js_socket_sendto(JSContext* ctx, JSValue* this_val, int argc, JSValue* argv)
static JSValue js_socket_recvfrom(JSContext* ctx, JSValue* this_val, int argc, JSValue* argv)
static JSValue js_socket_inet_addr(JSContext* ctx, JSValue* this_val, int argc, JSValue* argv)
static JSValue js_socket_ntohl(JSContext* ctx, JSValue* this_val, int argc, JSValue* argv)
static JSValue js_socket_make_sockaddr_in(JSContext* ctx, JSValue* this_val, int argc, JSValue* argv)注册到JavaScript的方式
static const JSPropDef js_yui[] = {
JS_CFUNC_DEF("log", 1, js_yui_log ),
JS_CFUNC_DEF("setText", 1, js_set_text ),
JS_CFUNC_DEF("getText", 1, js_get_text ),
JS_CFUNC_DEF("setBgColor", 1, js_set_bg_color ),
JS_CFUNC_DEF("hide", 1, js_hide ),
JS_CFUNC_DEF("show", 1, js_show ),
JS_CFUNC_DEF("renderFromJson", 2, js_render_from_json ),
JS_CFUNC_DEF("call", 2, js_yui_call ),
JS_CFUNC_DEF("update", 1, js_yui_update ),
JS_CFUNC_DEF("themeLoad", 1, js_yui_themeLoad ),
JS_CFUNC_DEF("themeSetCurrent", 1, js_yui_themeSetCurrent ),
JS_CFUNC_DEF("themeUnload", 1, js_yui_themeUnload ),
JS_CFUNC_DEF("themeApplyToTree", 0, js_yui_themeApplyToTree ),
JS_PROP_END,
};函数签名
static JSValue js_func(JSContext *ctx, JSValue *this_val, int argc, JSValue *argv)特点
- 使用
JS_CFUNC_DEF宏注册函数 - 参数:
JSValue *argv数组 - 字符串转换:
JS_ToCString(ctx, value, &buf) - 不支持
JS_FreeCString() - 返回
JSValue类型 - 使用
JSCStringBuf结构体处理字符串
暴露的JavaScript API
YUI.log(...)
YUI.setText(layerId, text)
YUI.getText(layerId)
YUI.setBgColor(layerId, color)
YUI.hide(layerId)
YUI.show(layerId)
YUI.renderFromJson(layerId, json)
YUI.call(func, param)
YUI.update(jsonString)
YUI.themeLoad(path)
YUI.themeSetCurrent(name)
YUI.themeUnload(name)
YUI.themeApplyToTree()
// Inspect API (Inspect对象)
YUI.inspect.enable()
YUI.inspect.disable()
YUI.inspect.setLayer(layerId, enabled)
YUI.inspect.setShowBounds(show)
YUI.inspect.setShowInfo(show)
// Socket API (Socket对象)
Socket.socket(type)
Socket.close(fd)
Socket.shutdown(fd)
Socket.connect(fd, host, port, timeout)
Socket.bind(fd, host, port)
Socket.listen(fd, backlog)
Socket.accept(fd)
Socket.getsockname(fd)
Socket.getpeername(fd)
Socket.socketpair(domain, type, protocol)
Socket.setsockopt(fd, level, option_name, option_value, option_len)
Socket.getsockopt(fd, level, option_name, option_len)
Socket.send(fd, data, flags)
Socket.recv(fd, len, flags)
Socket.sendto(fd, data, flags, host, port)
Socket.recvfrom(fd, len, flags)
Socket.inet_addr(ip)
Socket.ntohl(value)
Socket.make_sockaddr_in(ip, port)YUI Native 函数定义
// 核心YUI函数
static JSValue js_set_text(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
static JSValue js_get_text(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
static JSValue js_set_bg_color(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
static JSValue js_hide(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
static JSValue js_show(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
static JSValue js_log(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
static JSValue js_render_from_json(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
static JSValue js_update(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
// 主题管理函数
static JSValue js_theme_load(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
static JSValue js_theme_set_current(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
static JSValue js_theme_unload(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
static JSValue js_theme_apply_to_tree(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
// Socket API (lib/jsmodule-quickjs/js_socket.c)
static JSValue js_socket(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
static JSValue js_socket_close(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
static JSValue js_socket_shutdown(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
static JSValue js_socket_connect(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
static JSValue js_socket_bind(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
static JSValue js_socket_listen(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
static JSValue js_socket_accept(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
static JSValue js_socket_getsockname(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
static JSValue js_socket_getpeername(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
static JSValue js_socket_socketpair(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
static JSValue js_socket_setsockopt(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
static JSValue js_socket_getsockopt(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
static JSValue js_socket_send(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
static JSValue js_socket_recv(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
static JSValue js_socket_sendto(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
static JSValue js_socket_recvfrom(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
static JSValue js_socket_inet_addr(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
static JSValue js_socket_ntohl(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
static JSValue js_socket_make_sockaddr_in(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)注册到JavaScript的方式
// 创建 YUI 对象
JSValue yui_obj = JS_NewObject(g_js_ctx);
// 注册方法到 YUI 对象
JS_SetPropertyStr(g_js_ctx, yui_obj, "setText",
JS_NewCFunction(g_js_ctx, js_set_text, "setText", 2));
JS_SetPropertyStr(g_js_ctx, yui_obj, "getText",
JS_NewCFunction(g_js_ctx, js_get_text, "getText", 1));
JS_SetPropertyStr(g_js_ctx, yui_obj, "setBgColor",
JS_NewCFunction(g_js_ctx, js_set_bg_color, "setBgColor", 2));
JS_SetPropertyStr(g_js_ctx, yui_obj, "hide",
JS_NewCFunction(g_js_ctx, js_hide, "hide", 1));
JS_SetPropertyStr(g_js_ctx, yui_obj, "show",
JS_NewCFunction(g_js_ctx, js_show, "show", 1));
JS_SetPropertyStr(g_js_ctx, yui_obj, "renderFromJson",
JS_NewCFunction(g_js_ctx, js_render_from_json, "renderFromJson", 2));
JS_SetPropertyStr(g_js_ctx, yui_obj, "update",
JS_NewCFunction(g_js_ctx, js_update, "update", 1));
JS_SetPropertyStr(g_js_ctx, yui_obj, "log",
JS_NewCFunction(g_js_ctx, js_log, "log", 1));
JS_SetPropertyStr(g_js_ctx, yui_obj, "themeLoad",
JS_NewCFunction(g_js_ctx, js_theme_load, "themeLoad", 1));
JS_SetPropertyStr(g_js_ctx, yui_obj, "themeSetCurrent",
JS_NewCFunction(g_js_ctx, js_theme_set_current, "themeSetCurrent", 1));
JS_SetPropertyStr(g_js_ctx, yui_obj, "themeUnload",
JS_NewCFunction(g_js_ctx, js_theme_unload, "themeUnload", 1));
JS_SetPropertyStr(g_js_ctx, yui_obj, "themeApplyToTree",
JS_NewCFunction(g_js_ctx, js_theme_apply_to_tree, "themeApplyToTree", 0));
// 将 YUI 对象添加到全局
JS_SetPropertyStr(g_js_ctx, global_obj, "YUI", yui_obj);
// 也注册为全局函数(兼容性)
JS_SetPropertyStr(g_js_ctx, global_obj, "setText",
JS_NewCFunction(g_js_ctx, js_set_text, "setText", 2));
JS_SetPropertyStr(g_js_ctx, global_obj, "getText",
JS_NewCFunction(g_js_ctx, js_get_text, "getText", 1));
JS_SetPropertyStr(g_js_ctx, global_obj, "setBgColor",
JS_NewCFunction(g_js_ctx, js_set_bg_color, "setBgColor", 2));
JS_SetPropertyStr(g_js_ctx, global_obj, "hide",
JS_NewCFunction(g_js_ctx, js_hide, "hide", 1));
JS_SetPropertyStr(g_js_ctx, global_obj, "show",
JS_NewCFunction(g_js_ctx, js_show, "show", 1));函数签名
static JSValue js_func(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)特点
- 使用
JS_NewCFunction()创建函数对象 - 使用
JS_SetPropertyStr()注册到对象 - 参数:
JSValueConst *argv数组 - 字符串转换:
JS_ToCStringLen(ctx, &len, value) - 需要
JS_FreeCString(ctx, str)释放字符串 - 返回
JSValue类型 - 支持常量参数(
JSValueConst)
暴露的JavaScript API
YUI.log(...)
YUI.setText(layerId, text)
YUI.getText(layerId)
YUI.setBgColor(layerId, color)
YUI.hide(layerId)
YUI.show(layerId)
YUI.renderFromJson(layerId, json)
YUI.update(jsonString)
YUI.themeLoad(path)
YUI.themeSetCurrent(name)
YUI.themeUnload(name)
YUI.themeApplyToTree()
// 兼容性全局函数
setText(layerId, text)
getText(layerId)
setBgColor(layerId, color)
hide(layerId)
show(layerId)
// Socket API (Socket对象)
Socket.socket(type)
Socket.close(fd)
Socket.shutdown(fd)
Socket.connect(fd, host, port, timeout)
Socket.bind(fd, host, port)
Socket.listen(fd, backlog)
Socket.accept(fd)
Socket.getsockname(fd)
Socket.getpeername(fd)
Socket.socketpair(domain, type, protocol)
Socket.setsockopt(fd, level, option_name, option_value, option_len)
Socket.getsockopt(fd, level, option_name, option_len)
Socket.send(fd, data, flags)
Socket.recv(fd, len, flags)
Socket.sendto(fd, data, flags, host, port)
Socket.recvfrom(fd, len, flags)
Socket.inet_addr(ip)
Socket.ntohl(value)
Socket.make_sockaddr_in(ip, port)YUI Native 函数定义(共12个)
// 核心YUI函数(8个)
static var_t* mario_set_text(vm_t* vm, var_t* env, void* data) // 设置文本
static var_t* mario_get_text(vm_t* vm, var_t* env, void* data) // 获取文本
static var_t* mario_set_bg_color(vm_t* vm, var_t* env, void* data) // 设置背景色
static var_t* mario_hide(vm_t* vm, var_t* env, void* data) // 隐藏图层
static var_t* mario_show(vm_t* vm, var_t* env, void* data) // 显示图层
static var_t* mario_render_from_json(vm_t* vm, var_t* env, void* data)// JSON渲染
static var_t* mario_update(vm_t* vm, var_t* env, void* data) // 增量更新
static var_t* mario_log(vm_t* vm, var_t* env, void* data) // 日志输出
// 主题管理函数(4个)
static var_t* mario_theme_load(vm_t* vm, var_t* env, void* data) // 加载主题
static var_t* mario_theme_set_current(vm_t* vm, var_t* env, void* data) // 设置当前主题
static var_t* mario_theme_unload(vm_t* vm, var_t* env, void* data) // 卸载主题
static var_t* mario_theme_apply_to_tree(vm_t* vm, var_t* env, void* data) // 应用主题到树注册到JavaScript的方式
// 注册 YUI 类的方法(12个)
vm_reg_native(g_vm, yui_cls, "setText(layerId, text)", mario_set_text, NULL);
vm_reg_native(g_vm, yui_cls, "getText(layerId)", mario_get_text, NULL);
vm_reg_native(g_vm, yui_cls, "setBgColor(layerId, color)", mario_set_bg_color, NULL);
vm_reg_native(g_vm, yui_cls, "hide(layerId)", mario_hide, NULL);
vm_reg_native(g_vm, yui_cls, "show(layerId)", mario_show, NULL);
vm_reg_native(g_vm, yui_cls, "renderFromJson(layerId, json)", mario_render_from_json, NULL);
vm_reg_native(g_vm, yui_cls, "update(jsonString)", mario_update, NULL);
vm_reg_native(g_vm, yui_cls, "log(...)", mario_log, NULL);
vm_reg_native(g_vm, yui_cls, "themeLoad(path)", mario_theme_load, NULL);
vm_reg_native(g_vm, yui_cls, "themeSetCurrent(name)", mario_theme_set_current, NULL);
vm_reg_native(g_vm, yui_cls, "themeUnload(name)", mario_theme_unload, NULL);
vm_reg_native(g_vm, yui_cls, "themeApplyToTree()", mario_theme_apply_to_tree, NULL);
// 也注册为全局函数(5个,仅基础操作)
vm_reg_static(g_vm, NULL, "setText(layerId, text)", mario_set_text, NULL);
vm_reg_static(g_vm, NULL, "getText(layerId)", mario_get_text, NULL);
vm_reg_static(g_vm, NULL, "setBgColor(layerId, color)", mario_set_bg_color, NULL);
vm_reg_static(g_vm, NULL, "hide(layerId)", mario_hide, NULL);
vm_reg_static(g_vm, NULL, "show(layerId)", mario_show, NULL);函数签名
static var_t* mario_func(vm_t* vm, var_t* env, void* data)特点
- 使用
vm_reg_native()注册函数到 YUI 类 - 使用
vm_reg_static()注册为全局函数(仅5个基础操作) - 函数声明包含参数类型(用于文档和提示)
- 使用
get_func_arg_str(env, index)获取字符串参数 - 不支持复杂对象操作
- 返回
var_t*类型 - 使用
var_new_int(),var_new_str(),var_new_null()创建返回值 - 引擎限制:ES3-like,不支持现代JS特性
暴露的JavaScript API(实际可用)
// YUI 对象方法(12个)
YUI.log(...)
YUI.setText(layerId, text)
YUI.getText(layerId)
YUI.setBgColor(layerId, color)
YUI.hide(layerId)
YUI.show(layerId)
YUI.renderFromJson(layerId, json)
YUI.update(jsonString)
YUI.themeLoad(path)
YUI.themeSetCurrent(name)
YUI.themeUnload(name)
YUI.themeApplyToTree()
// 全局函数(5个,仅基础操作)
setText(layerId, text)
getText(layerId)
setBgColor(layerId, color)
hide(layerId)
show(layerId)
// Socket API: 在 lib/mario/builtin/socket/native_socket.c 中提供(23个函数)
// 使用方式: Socket.socket(type), Socket.connect(fd, host, port, timeout) 等Native函数实现示例
mquickjs版本:
static JSValue js_yui_themeLoad(JSContext *ctx, JSValue *this_val,
int argc, JSValue *argv) {
const char *theme_path = NULL;
JSCStringBuf buf;
if (argc < 1) {
return JS_ThrowTypeError(ctx, "themeLoad requires 1 argument");
}
theme_path = JS_ToCString(ctx, argv[0], &buf);
ThemeManager* manager = theme_manager_get_instance();
Theme* theme = theme_manager_load_theme(theme_path);
if (theme) {
JSValue result = JS_NewObject(ctx);
JS_SetPropertyStr(ctx, result, "success", JS_NewBool(1));
JS_SetPropertyStr(ctx, result, "name",
JS_NewString(ctx, theme->name));
return result;
}
// ...
}QuickJS版本:
static JSValue js_theme_load(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv) {
if (argc < 1) {
return JS_ThrowTypeError(ctx, "themeLoad requires 1 argument");
}
size_t len;
const char* theme_path = JS_ToCStringLen(ctx, &len, argv[0]);
ThemeManager* manager = theme_manager_get_instance();
Theme* theme = theme_manager_load_theme(theme_path);
JS_FreeCString(ctx, theme_path); // 必须释放
if (theme) {
JSValue result = JS_NewObject(ctx);
JS_SetPropertyStr(ctx, result, "success", JS_NewBool(ctx, 1));
JS_SetPropertyStr(ctx, result, "name",
JS_NewString(ctx, theme->name));
return result;
}
// ...
}Mario版本:
static var_t* mario_theme_load(vm_t* vm, var_t* env, void* data) {
var_t* args = get_func_args(env);
uint32_t argc = get_func_args_num(env);
if (argc < 1) {
return var_new_int(vm, -1); // 返回错误码
}
const char* theme_path = get_func_arg_str(env, 0);
ThemeManager* manager = theme_manager_get_instance();
Theme* theme = theme_manager_load_theme(theme_path);
if (theme) {
printf("JS(Mario): Loaded theme: %s\n", theme->name);
return var_new_int(vm, 0); // 成功返回0
} else {
return var_new_int(vm, -1); // 失败返回-1
}
}mquickjs 引擎提供了完整的 JavaScript 标准库:
全局函数
print(...args)- 打印输出gc()- 垃圾回收load(filename)- 加载并执行JS文件setTimeout(func, delay)- 设置定时器clearTimeout(id)- 清除定时器parseInt(str, radix)- 字符串转整数parseFloat(str)- 字符串转浮点数eval(code)- 执行代码isNaN(value)- 检查是否为NaNisFinite(value)- 检查是否为有限数
Object 对象
Object.defineProperty(obj, prop, descriptor)Object.getPrototypeOf(obj)Object.setPrototypeOf(obj, proto)Object.create(proto)Object.keys(obj)obj.hasOwnProperty(prop)obj.toString()
Function 对象
func.call(thisArg, ...args)func.apply(thisArg, argsArray)func.bind(thisArg, ...args)func.toString()func.length(属性)
Number 对象
Number.parseInt(str, radix)Number.parseFloat(str)Number.MAX_VALUENumber.MIN_VALUEnum.toExponential(fractionDigits)num.toFixed(digits)num.toPrecision(precision)num.toString(radix)
String 对象
str.length(属性)str.charAt(index)str.charCodeAt(index)str.codePointAt(pos)str.slice(start, end)str.substring(start, end)str.concat(...strings)str.indexOf(search)str.lastIndexOf(search)str.match(regexp)str.replace(search, replacement)str.replaceAll(search, replacement)str.search(regexp)str.split(separator, limit)str.toLowerCase()str.toUpperCase()str.trim()str.trimStart()str.trimEnd()str.toString()str.repeat(count)
Array 对象
Array.isArray(value)arr.length(属性)arr.concat(...arrays)arr.push(...items)arr.pop()arr.join(separator)arr.toString()arr.reverse()arr.shift()arr.slice(start, end)arr.splice(start, deleteCount, ...items)arr.unshift(...items)arr.forEach(callback)arr.map(callback)arr.filter(callback)arr.every(callback)arr.some(callback)arr.reduce(callback, initialValue)arr.reduceRight(callback, initialValue)arr.sort(compareFunc)
Math 对象
Math.abs(x),Math.acos(x),Math.asin(x),Math.atan(x)Math.atan2(y, x),Math.ceil(x),Math.cos(x),Math.exp(x)Math.floor(x),Math.log(x),Math.max(...values),Math.min(...values)Math.pow(x, y),Math.random(),Math.round(x),Math.sin(x)Math.sqrt(x),Math.tan(x),Math.imul(a, b),Math.clz32(x)
JSON 对象
JSON.parse(text, reviver)JSON.stringify(value, replacer, space)
Date 对象
Date.now()- 返回当前时间戳
console 对象
console.log(...args)- 控制台输出
performance 对象
performance.now()- 返回高精度时间戳
以下函数在 QuickJS 引擎中也可作为全局函数直接调用:
setText(layerId, text)getText(layerId)setBgColor(layerId, color)hide(layerId)show(layerId)
// 获取主题管理器单例
ThemeManager* theme_manager_get_instance(void);
// 销毁主题管理器
void theme_manager_destroy(void);
// 加载主题文件
Theme* theme_manager_load_theme(const char* theme_path);
// 设置当前主题
int theme_manager_set_current(const char* theme_name);
// 获取当前主题
Theme* theme_manager_get_current(void);
// 获取主题(按名称)
Theme* theme_manager_get_theme(const char* theme_name);
// 卸载主题
void theme_manager_unload_theme(const char* theme_name);
// 应用主题到单个图层
void theme_manager_apply_to_layer(Layer* layer, const char* id, const char* type);
// 应用主题到图层树
void theme_manager_apply_to_tree(Layer* root);// 创建主题对象
Theme* theme_create(const char* name, const char* version);
// 销毁主题对象
void theme_destroy(Theme* theme);
// 从JSON文件加载主题
Theme* theme_load_from_file(const char* json_path);
// 从JSON对象加载主题
Theme* theme_load_from_json(cJSON* json);
// 添加规则到主题
void theme_add_rule(Theme* theme, ThemeRule* rule);
// 从JSON创建规则
ThemeRule* theme_rule_create_from_json(cJSON* json);
// 销毁规则
void theme_rule_destroy(ThemeRule* rule);
// 应用主题样式到图层
void theme_apply_to_layer(Theme* theme, Layer* layer, const char* id, const char* type);
// 合并样式
void theme_merge_style(ThemeRule* rule, Layer* layer);
// 解析选择器类型
ThemeSelectorType theme_parse_selector_type(const char* selector);// 查找图层
Layer* find_layer_by_id(Layer* root, const char* id);
// 从JSON字符串解析图层
Layer* parse_layer_from_string(const char* json_str, Layer* parent);
// 销毁图层
void destroy_layer(Layer* layer);
// 布局图层
void layout_layer(Layer* layer);
// 加载所有字体
void load_all_fonts(Layer* layer);
// 设置图层文本
void layer_set_text(Layer* layer, const char* text);
// 获取图层文本
const char* layer_get_text(const Layer* layer);
// 设置图层事件
void layer_set_event(Layer* layer, EventType event_type, EventHandler handler);// JSON增量更新
int yui_update(Layer* root, const char* update_json);
// 解析颜色字符串
int parse_color(const char* color_str, Color* color);// 从JSON设置单个属性
int layer_set_property_from_json(Layer* layer, const char* key, cJSON* value, int is_creating);
// 从JSON对象批量设置属性
int layer_set_properties_from_json(Layer* layer, cJSON* json, int is_creating);
// 从JSON数组创建子图层
int layer_set_children_from_json(Layer* layer, cJSON* children_array);// 渲染图层树
void render_layer(Layer* layer);
// 渲染所有图层
void render_all_layers(Layer* root);// 计算图层布局
void calculate_layout(Layer* layer);// 更新动画
void animate_update(Layer* root, uint32_t delta_time);
// 添加动画
Animation* animate_add(Layer* layer, AnimationType type, float from, float to, uint32_t duration);| 特性 | mquickjs | QuickJS | Mario |
|---|---|---|---|
| 注册方式 | JS_CFUNC_DEF 宏数组 |
JS_NewCFunction + JS_SetPropertyStr |
vm_reg_native |
| 函数签名 | JSValue func(JSContext*, JSValue*, int, JSValue*) |
JSValue func(JSContext*, JSValueConst, int, JSValueConst*) |
var_t* func(vm_t*, var_t*, void*) |
| 参数类型 | JSValue* |
JSValueConst* |
var_t* env |
| 字符串转换 | JS_ToCString(ctx, val, &buf) |
JS_ToCStringLen(ctx, &len, val) |
get_func_arg_str(env, idx) |
| 字符串释放 | ❌ 不需要 | ✅ 需要 JS_FreeCString |
❌ 不需要 |
| 返回值 | JSValue |
JSValue |
var_t* |
| 对象操作 | ✅ 完整支持 | ✅ 完整支持 | ❌ 仅简单类型 |
| 引擎特性 | 轻量级 | 完整ES2020 | ES3-like |
| API | mquickjs | QuickJS | Mario |
|---|---|---|---|
| YUI Core | ✅ | ✅ | ✅ |
| Socket API | ✅ | ✅ | ✅ |
| 标准库 | ✅ 完整 | ✅ 完整 | ❌ 基础 |
| Theme Mgmt | ✅ | ✅ | ✅ |
| JSON | ✅ | ✅ | |
| Array | ✅ | ✅ | |
| Promise | ❌ | ✅ | ❌ |
| ES6+ | ❌ | ✅ | ❌ |
// 加载主题
var result = YUI.themeLoad('app/themes/dark.json');
if (result && result.success) {
console.log('Loaded theme: ' + result.name);
// 设置为当前主题
if (YUI.themeSetCurrent(result.name)) {
console.log('Theme activated');
// 应用到UI
if (YUI.themeApplyToTree()) {
console.log('Theme applied to UI');
}
}
}
// 卸载主题
YUI.themeUnload('old-theme');// 启用全局 inspect 模式
YUI.inspect.enable();
// 为特定图层启用 inspect
YUI.inspect.setLayer('button1', true);
// 设置显示选项
YUI.inspect.setShowBounds(true); // 显示边界框
YUI.inspect.setShowInfo(true); // 显示详细信息
// 禁用 inspect 模式
YUI.inspect.disable();// 设置文本
YUI.setText('button1', 'Click Me');
// 获取文本
var text = YUI.getText('label1');
// 设置背景色
YUI.setBgColor('panel1', '#FF0000');
// 显示/隐藏
YUI.hide('loading');
YUI.show('content');
// 从JSON渲染
var json = '{"type": "Label", "text": "Hello", "style": {"width": 100}}';
YUI.renderFromJson('container', json);
// JSON增量更新
var update = {
"target": "button1",
"style": {"bgColor": "#00FF00", "text": "Updated"}
};
YUI.update(JSON.stringify(update));// 创建TCP socket
var fd = Socket.socket(Socket.TCP);
// 连接到服务器
if (Socket.connect(fd, '127.0.0.1', 8080, 5000) === 0) {
console.log('Connected');
// 发送数据
Socket.send(fd, 'Hello Server', 0);
// 接收数据
var data = Socket.recv(fd, 1024, 0);
console.log('Received: ' + data);
// 关闭socket
Socket.close(fd);
}ya -c yui-stdlib-host && ya -b yui-stdlib-hostmake playgroundmake main # 主程序
make mqjs # mquickjs 版本
make run # 运行主程序
make clean # 清理构建文件- 引擎兼容性:所有核心 API 和 Socket API 在三个引擎中都可用,Mario 引擎的 Socket API 更加强大(23个函数)
- 内存管理:QuickJS 需要手动释放字符串,mquickjs 和 Mario 不需要
- 错误处理:不同引擎的错误返回值类型不同,mquickjs/Mario 返回整数代码,QuickJS 返回布尔值
- 异步支持:目前只支持同步 API,异步操作需要使用定时器模拟
- 使用
YUI.log()或console.log()输出调试信息 - 检查返回值判断操作是否成功
- 使用
JSON.stringify()将对象转为字符串输出 - 在 C 代码中添加
printf调试原生函数调用 - 使用
make clean清理后重新构建确保代码更新生效