Skip to content

Commit

Permalink
fix: decorate base type
Browse files Browse the repository at this point in the history
  • Loading branch information
X3ZvaWQ committed Jan 23, 2024
1 parent 9fb2b2a commit d1a8a04
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 214 deletions.
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ export { default as LuaMultiReturn } from './multireturn';
// use the bindings rather than the wrappers.
export { default as LuaApi } from './api';
export { default as Lua } from './lua';
export { JsType } from './type-bind';
export * from './type-bind';
export * from './definitions';
97 changes: 44 additions & 53 deletions src/thread.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,27 +153,36 @@ export default class LuaThread {
return this.luaApi.lua_remove(this.address, index);
}

public pushBasicValue(target: unknown, options: PushValueOptions): boolean {
if (target === undefined || target === null) {
this.luaApi.lua_pushnil(this.address);
} else if (typeof target === 'number') {
if (Number.isInteger(target)) {
this.luaApi.lua_pushinteger(this.address, target);
} else {
this.luaApi.lua_pushnumber(this.address, target);
}
} else if (typeof target === 'string') {
this.luaApi.lua_pushstring(this.address, target);
} else if (typeof target === 'boolean') {
this.luaApi.lua_pushboolean(this.address, target ? 1 : 0);
} else if (lodash.isPlainObject(target) || lodash.isArray(target)) {
this.pushTable(target as Record<string | number, any>, options);
} else {
return false;
}
return true;
}

public pushValue(target: unknown, options: PushValueOptions = {}): void {
// 如果值是JsType decorate
if (target instanceof JsType && target.target) {
const startTop = this.getTop();

if (target instanceof JsType) {
// 如果值是JsType decorate, 针对这一个值设置metatable
if (target._push) {
target._push({ thread: this, target: target.target, options });
} else {
if (target === undefined || target === null) {
this.luaApi.lua_pushnil(this.address);
} else if (typeof target === 'number') {
if (Number.isInteger(target)) {
this.luaApi.lua_pushinteger(this.address, target);
} else {
this.luaApi.lua_pushnumber(this.address, target);
}
} else if (typeof target === 'string') {
this.luaApi.lua_pushstring(this.address, target);
} else if (typeof target === 'boolean') {
this.luaApi.lua_pushboolean(this.address, target ? 1 : 0);
} else if (lodash.isPlainObject(target) || lodash.isArray(target)) {
this.pushTable(target as Record<string | number, any>, options);
} else {
if (!this.pushBasicValue(target.target, options)) {
const ref = this.luaApi.ref(target);
const luaPointer = this.luaApi.lua_newuserdata(this.address, PointerSize);
this.luaApi.module.setValue(luaPointer, ref, '*');
Expand All @@ -183,49 +192,31 @@ export default class LuaThread {
target._pushMetaTable(this);
this.luaApi.lua_setmetatable(this.address, -2);
}
return;
}

// 如果值是线程
if (target instanceof LuaThread) {
} else if (target instanceof LuaThread) {
// 如果值是线程
const isMain = this.luaApi.lua_pushthread(target.address) === 1;
if (!isMain) {
this.luaApi.lua_xmove(target.address, this.address, 1);
}
return;
}

const startTop = this.getTop();
// js-lua 类型之间的转换
if (target === undefined || target === null) {
this.luaApi.lua_pushnil(this.address);
} else if (typeof target === 'number') {
if (Number.isInteger(target)) {
this.luaApi.lua_pushinteger(this.address, target);
} else {
this.luaApi.lua_pushnumber(this.address, target);
}
} else if (typeof target === 'string') {
this.luaApi.lua_pushstring(this.address, target);
} else if (typeof target === 'boolean') {
this.luaApi.lua_pushboolean(this.address, target ? 1 : 0);
} else if (lodash.isPlainObject(target) || lodash.isArray(target)) {
this.pushTable(target as Record<string | number, any>, options);
} else {
// 其他类型没有对应的lua类型,当userdata处理,找到对应js类型的metatable,绑定上
const type = this.types.find((t) => (t.match as (...args: any[]) => any)(target)) as JsType;

if (type._push) {
// 类型自定义push行为
type._push({ thread: this, target, options, type });
} else {
// 默认push行为
const ref = this.luaApi.ref(target);
const luaPointer = this.luaApi.lua_newuserdata(this.address, PointerSize);
this.luaApi.module.setValue(luaPointer, ref, '*');
// js-lua 类型之间的转换
if (!this.pushBasicValue(target, options)) {
// 其他类型没有对应的lua类型,当userdata处理,找到对应js类型的metatable,绑定上
const type = this.types.find((t) => (t.match as (...args: any[]) => any)(target)) as JsType;

if (type._push) {
// 类型自定义push行为
type._push({ thread: this, target, options, type });
} else {
// 默认push行为
const ref = this.luaApi.ref(target);
const luaPointer = this.luaApi.lua_newuserdata(this.address, PointerSize);
this.luaApi.module.setValue(luaPointer, ref, '*');

this.luaApi.luaL_getmetatable(this.address, type?._name);
this.luaApi.lua_setmetatable(this.address, -2);
this.luaApi.luaL_getmetatable(this.address, type?._name);
this.luaApi.lua_setmetatable(this.address, -2);
}
}
}

Expand Down
14 changes: 9 additions & 5 deletions test/debug.mjs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { Lua } from '../dist/index.js';
import { JsType, Lua } from '../dist/index.js';

// This file was created as a sandbox to test and debug on vscode
const lua = await Lua.create();

lua.ctx.null = JsType.decorate(null).tostring(() => 'null');

lua.global.loadString(`
local i = 0
while true do i = i + 1 end
local args = { ... }
assert(args[1] == null, string.format("expected first argument to be null, got %s", tostring(args[1])))
return null, args[1], tostring(null)
`);

await lua.global.run(0, { timeout: 5 }).catch((e) => console.log(e));
lua.global.pushValue(null);
const res = await lua.global.run(1);
expect(res).to.deep.equal([null, null, 'null']);
Loading

0 comments on commit d1a8a04

Please sign in to comment.