| 196 | } |
| 197 | |
| 198 | Variant GDScriptFunctionState::resume(const Variant &p_arg) { |
| 199 | ERR_FAIL_NULL_V(function, Variant()); |
| 200 | { |
| 201 | MutexLock lock(GDScriptLanguage::singleton->mutex); |
| 202 | |
| 203 | if (!scripts_list.in_list()) { |
| 204 | #ifdef DEBUG_ENABLED |
| 205 | ERR_FAIL_V_MSG(Variant(), "Resumed function '" + state.function_name + "()' after await, but script is gone. At script: " + state.script_path + ":" + itos(state.line)); |
| 206 | #else |
| 207 | return Variant(); |
| 208 | #endif |
| 209 | } |
| 210 | if (state.instance && !instances_list.in_list()) { |
| 211 | #ifdef DEBUG_ENABLED |
| 212 | ERR_FAIL_V_MSG(Variant(), "Resumed function '" + state.function_name + "()' after await, but class instance is gone. At script: " + state.script_path + ":" + itos(state.line)); |
| 213 | #else |
| 214 | return Variant(); |
| 215 | #endif |
| 216 | } |
| 217 | // Do these now to avoid locking again after the call |
| 218 | scripts_list.remove_from_list(); |
| 219 | instances_list.remove_from_list(); |
| 220 | } |
| 221 | |
| 222 | state.result = p_arg; |
| 223 | Callable::CallError err; |
| 224 | Variant ret = function->call(nullptr, nullptr, 0, err, &state); |
| 225 | |
| 226 | bool completed = true; |
| 227 | |
| 228 | // If the return value is a GDScriptFunctionState reference, |
| 229 | // then the function did await again after resuming. |
| 230 | if (ret.is_ref_counted()) { |
| 231 | GDScriptFunctionState *gdfs = Object::cast_to<GDScriptFunctionState>(ret); |
| 232 | if (gdfs && gdfs->function == function) { |
| 233 | completed = false; |
| 234 | // Keep the first state alive via reference. |
| 235 | gdfs->first_state = first_state.is_valid() ? first_state : Ref<GDScriptFunctionState>(this); |
| 236 | } |
| 237 | } |
| 238 | |
| 239 | function = nullptr; //cleaned up; |
| 240 | state.result = Variant(); |
| 241 | |
| 242 | if (completed) { |
| 243 | _clear_stack(); |
| 244 | } |
| 245 | |
| 246 | return ret; |
| 247 | } |
| 248 | |
| 249 | void GDScriptFunctionState::_clear_stack() { |
| 250 | if (state.stack_size) { |
no test coverage detected