|
33 | 33 | #include "core/io/marshalls.h"
|
34 | 34 | #include "core/object/ref_counted.h"
|
35 | 35 | #include "core/os/os.h"
|
| 36 | +#include "core/os/semaphore.h" |
36 | 37 | #include "core/templates/oa_hash_map.h"
|
37 | 38 | #include "core/templates/rid.h"
|
38 | 39 | #include "core/templates/rid_owner.h"
|
@@ -1234,6 +1235,81 @@ bool VariantUtilityFunctions::is_same(const Variant &p_a, const Variant &p_b) {
|
1234 | 1235 | return p_a.identity_compare(p_b);
|
1235 | 1236 | }
|
1236 | 1237 |
|
| 1238 | +class CallableCustomSuspend : public CallableCustom { |
| 1239 | + Semaphore *semaphore = nullptr; |
| 1240 | + Variant *return_value = nullptr; |
| 1241 | + |
| 1242 | + // Never really going to execute since disconnection is automatic. |
| 1243 | + static bool _equal_func(const CallableCustom *p_a, const CallableCustom *p_b) { |
| 1244 | + const CallableCustomSuspend *A = static_cast<const CallableCustomSuspend *>(p_a); |
| 1245 | + const CallableCustomSuspend *B = static_cast<const CallableCustomSuspend *>(p_b); |
| 1246 | + |
| 1247 | + return A->semaphore == B->semaphore; |
| 1248 | + } |
| 1249 | + |
| 1250 | + // Never really going to execute since disconnection is automatic. |
| 1251 | + static bool _less_func(const CallableCustom *p_a, const CallableCustom *p_b) { |
| 1252 | + const CallableCustomSuspend *A = static_cast<const CallableCustomSuspend *>(p_a); |
| 1253 | + const CallableCustomSuspend *B = static_cast<const CallableCustomSuspend *>(p_b); |
| 1254 | + |
| 1255 | + return A->semaphore < B->semaphore; |
| 1256 | + } |
| 1257 | + |
| 1258 | +public: |
| 1259 | + //for every type that inherits, these must always be the same for this type |
| 1260 | + virtual uint32_t hash() const override { |
| 1261 | + return size_t(semaphore); |
| 1262 | + } |
| 1263 | + |
| 1264 | + virtual String get_as_text() const override { |
| 1265 | + return "SemaphoreCallable"; |
| 1266 | + } |
| 1267 | + |
| 1268 | + virtual CompareEqualFunc get_compare_equal_func() const override { |
| 1269 | + return _equal_func; |
| 1270 | + } |
| 1271 | + |
| 1272 | + virtual CompareLessFunc get_compare_less_func() const override { |
| 1273 | + return _less_func; |
| 1274 | + } |
| 1275 | + |
| 1276 | + virtual ObjectID get_object() const override { |
| 1277 | + return ObjectID(); |
| 1278 | + } |
| 1279 | + |
| 1280 | + virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override { |
| 1281 | + semaphore->post(); |
| 1282 | + if (p_argcount == 1) { // If passed one argument, will be returned. |
| 1283 | + if (return_value) { |
| 1284 | + *return_value = *p_arguments[0]; |
| 1285 | + } |
| 1286 | + } else if (p_argcount > 1) { |
| 1287 | + r_call_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; |
| 1288 | + r_call_error.argument = p_argcount; |
| 1289 | + r_call_error.expected = 1; |
| 1290 | + return; |
| 1291 | + } |
| 1292 | + |
| 1293 | + r_call_error.error = Callable::CallError::CALL_OK; |
| 1294 | + } |
| 1295 | + |
| 1296 | + CallableCustomSuspend(Semaphore *p_semaphore, Variant *r_return_value) { |
| 1297 | + semaphore = p_semaphore; |
| 1298 | + return_value = r_return_value; |
| 1299 | + } |
| 1300 | +}; |
| 1301 | + |
| 1302 | +Variant VariantUtilityFunctions::thread_suspend(Signal p_resume) { |
| 1303 | + Semaphore semaphore; |
| 1304 | + Variant return_value; |
| 1305 | + |
| 1306 | + p_resume.connect(Callable(memnew(CallableCustomSuspend(&semaphore, &return_value))), Object::CONNECT_ONE_SHOT); |
| 1307 | + |
| 1308 | + semaphore.wait(); |
| 1309 | + |
| 1310 | + return return_value; |
| 1311 | +} |
| 1312 | + |
1237 | 1313 | #ifdef DEBUG_METHODS_ENABLED
|
1238 | 1314 | #define VCALLR *ret = p_func(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...)
|
1239 | 1315 | #define VCALL p_func(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...)
|
@@ -1855,6 +1931,8 @@ void Variant::_register_variant_utility_functions() {
|
1855 | 1931 | FUNCBINDR(rid_from_int64, sarray("base"), Variant::UTILITY_FUNC_TYPE_GENERAL);
|
1856 | 1932 |
|
1857 | 1933 | FUNCBINDR(is_same, sarray("a", "b"), Variant::UTILITY_FUNC_TYPE_GENERAL);
|
| 1934 | + |
| 1935 | + FUNCBINDR(thread_suspend, sarray("on_signal"), Variant::UTILITY_FUNC_TYPE_GENERAL); |
1858 | 1936 | }
|
1859 | 1937 |
|
1860 | 1938 | void Variant::_unregister_variant_utility_functions() {
|
|
0 commit comments