(argCount = 0, options?: Partial<LuaThreadRunOptions>)
| 101 | } |
| 102 | |
| 103 | public async run(argCount = 0, options?: Partial<LuaThreadRunOptions>): Promise<MultiReturn> { |
| 104 | const originalTimeout = this.timeout |
| 105 | try { |
| 106 | if (options?.timeout !== undefined) { |
| 107 | this.setTimeout(Date.now() + options.timeout) |
| 108 | } |
| 109 | let resumeResult: LuaResumeResult = this.resume(argCount) |
| 110 | while (resumeResult.result === LuaReturn.Yield) { |
| 111 | // If it's yielded check the timeout. If it's completed no need to |
| 112 | // needlessly discard the output. |
| 113 | if (this.timeout && Date.now() > this.timeout) { |
| 114 | if (resumeResult.resultCount > 0) { |
| 115 | this.pop(resumeResult.resultCount) |
| 116 | } |
| 117 | throw new LuaTimeoutError(`thread timeout exceeded`) |
| 118 | } |
| 119 | if (resumeResult.resultCount > 0) { |
| 120 | const lastValue = this.getValue(-1) |
| 121 | this.pop(resumeResult.resultCount) |
| 122 | |
| 123 | // If there's a result and it's a promise, then wait for it. |
| 124 | if (lastValue === Promise.resolve(lastValue)) { |
| 125 | await lastValue |
| 126 | } else { |
| 127 | // If it's a non-promise, then skip a tick to yield for promises, timers, etc. |
| 128 | await new Promise((resolve) => setImmediate(resolve)) |
| 129 | } |
| 130 | } else { |
| 131 | // If there's nothing to yield, then skip a tick to yield for promises, timers, etc. |
| 132 | await new Promise((resolve) => setImmediate(resolve)) |
| 133 | } |
| 134 | |
| 135 | resumeResult = this.resume(0) |
| 136 | } |
| 137 | |
| 138 | this.assertOk(resumeResult.result) |
| 139 | return this.getStackValues() |
| 140 | } finally { |
| 141 | if (options?.timeout !== undefined) { |
| 142 | this.setTimeout(originalTimeout) |
| 143 | } |
| 144 | } |
| 145 | } |
| 146 | |
| 147 | public runSync(argCount = 0): MultiReturn { |
| 148 | const base = this.getTop() - argCount - 1 // The 1 is for the function to run |
no test coverage detected