31
31
#include " gdscript_language_protocol.h"
32
32
33
33
#include " core/config/project_settings.h"
34
+ #include " core/error/error_list.h"
35
+ #include " core/io/resource_loader.h"
34
36
#include " editor/doc_tools.h"
35
37
#include " editor/editor_help.h"
36
38
#include " editor/editor_log.h"
@@ -238,6 +240,8 @@ void GDScriptLanguageProtocol::poll(int p_limit_usec) {
238
240
on_client_connected ();
239
241
}
240
242
243
+ scene_cache._check_thread_for_cache_update ();
244
+
241
245
HashMap<int , Ref<LSPeer>>::Iterator E = clients.begin ();
242
246
while (E != clients.end ()) {
243
247
Ref<LSPeer> peer = E->value ;
@@ -350,17 +354,17 @@ GDScriptLanguageProtocol::GDScriptLanguageProtocol() {
350
354
scene_cache.workspace = workspace;
351
355
}
352
356
353
- void SceneCache::_get_owners (EditorFileSystemDirectory *efsd , String p_path, List<String> &owners ) {
354
- if (!efsd ) {
357
+ void SceneCache::_get_owners (EditorFileSystemDirectory *p_efsd , String p_path, List<String> &r_owners ) {
358
+ if (!p_efsd ) {
355
359
return ;
356
360
}
357
361
358
- for (int i = 0 ; i < efsd ->get_subdir_count (); i++) {
359
- _get_owners (efsd ->get_subdir (i), p_path, owners );
362
+ for (int i = 0 ; i < p_efsd ->get_subdir_count (); i++) {
363
+ _get_owners (p_efsd ->get_subdir (i), p_path, r_owners );
360
364
}
361
365
362
- for (int i = 0 ; i < efsd ->get_file_count (); i++) {
363
- Vector<String> deps = efsd ->get_file_deps (i);
366
+ for (int i = 0 ; i < p_efsd ->get_file_count (); i++) {
367
+ Vector<String> deps = p_efsd ->get_file_deps (i);
364
368
bool found = false ;
365
369
for (int j = 0 ; j < deps.size (); j++) {
366
370
if (deps[j] == p_path) {
@@ -372,19 +376,20 @@ void SceneCache::_get_owners(EditorFileSystemDirectory *efsd, String p_path, Lis
372
376
continue ;
373
377
}
374
378
375
- owners .push_back (efsd ->get_file_path (i));
379
+ r_owners .push_back (p_efsd ->get_file_path (i));
376
380
}
377
381
}
378
382
379
383
void SceneCache::_set_owner_scene_node (String p_path) {
380
- Node *owner_scene_node = nullptr ;
381
- List<String> owners;
382
-
383
384
if (cache.has (p_path)) {
384
385
return ;
385
386
}
386
387
388
+ Node *owner_scene_node = nullptr ;
389
+ List<String> owners;
390
+
387
391
_get_owners (EditorFileSystem::get_singleton ()->get_filesystem (), p_path, owners);
392
+ owners_path_cache[p_path] = owners;
388
393
389
394
for (const String &owner : owners) {
390
395
NodePath owner_path = owner;
@@ -399,46 +404,155 @@ void SceneCache::_set_owner_scene_node(String p_path) {
399
404
cache[p_path] = owner_scene_node;
400
405
}
401
406
402
- bool SceneCache::has (const String &p_uri) {
403
- return cache.has (p_uri);
407
+ /* *
408
+ * Does only one threaded request to the ResourceLoader at a time.
409
+ * Because loading the same subresources in parallel can bring up errors in the editor.
410
+ * */
411
+ void SceneCache::_add_owner_scene_request (String p_path = " " ) {
412
+ if (p_path.is_empty ()) {
413
+ if (resource_request_queue.size () > 0 ) {
414
+ p_path = resource_request_queue.front ();
415
+ } else {
416
+ return ;
417
+ }
418
+ }
419
+ if (cache.has (p_path) && resource_request_queue.size () == 0 ) {
420
+ return ;
421
+ }
422
+ if (!cache.has (p_path) && !resource_request_queue.has (p_path)) {
423
+ resource_request_queue.push_back (p_path);
424
+ }
425
+ if (is_loading) {
426
+ return ;
427
+ }
428
+
429
+ String path = resource_request_queue.front ();
430
+ if (!owners_path_cache.has (p_path)) {
431
+ _get_owners (EditorFileSystem::get_singleton ()->get_filesystem (), path, owners_path_cache[p_path]);
432
+ }
433
+ Error r_error = Error::FAILED;
434
+ while (r_error != Error::OK && owners_path_cache[p_path].size () > 0 ) {
435
+ NodePath owner_path = owners_path_cache[p_path].front ()->get ();
436
+ r_error = ResourceLoader::load_threaded_request (owner_path);
437
+ if (r_error != Error::OK) {
438
+ owners_path_cache[path].pop_front ();
439
+ }
440
+ }
441
+ if (owners_path_cache[path].size () > 0 ) {
442
+ is_loading = true ;
443
+ } else {
444
+ cache[path] = nullptr ;
445
+ resource_request_queue.pop_front ();
446
+ _add_owner_scene_request ();
447
+ }
448
+ }
449
+
450
+ void SceneCache::_check_thread_for_cache_update () {
451
+ if (!is_loading) {
452
+ return ;
453
+ }
454
+
455
+ String check_path = resource_request_queue.front ();
456
+
457
+ NodePath owner_path = owners_path_cache[check_path].front ()->get ();
458
+
459
+ if (ResourceLoader::load_threaded_get_status (owner_path) != ResourceLoader::ThreadLoadStatus::THREAD_LOAD_LOADED) {
460
+ return ;
461
+ }
462
+
463
+ is_loading = false ;
464
+
465
+ Ref<PackedScene> owner_res = ResourceLoader::load_threaded_get (owner_path);
466
+ if (owner_res.is_valid ()) {
467
+ cache[check_path] = owner_res->instantiate ();
468
+ owners_path_cache.erase (check_path);
469
+ resource_request_queue.pop_front ();
470
+ _add_owner_scene_request ();
471
+ return ;
472
+ }
473
+ owners_path_cache[check_path].pop_front ();
474
+ if (owners_path_cache[check_path].size () == 0 ) {
475
+ cache[check_path] = nullptr ;
476
+ owners_path_cache.erase (check_path);
477
+ resource_request_queue.pop_front ();
478
+ }
479
+ _add_owner_scene_request ();
480
+ }
481
+
482
+ bool SceneCache::has (const String &p_path) {
483
+ return cache.has (p_path);
404
484
}
405
485
406
- Node *SceneCache::get (const String &p_uri) {
407
- return cache[p_uri];
486
+ Node *SceneCache::get (const String &p_path) {
487
+ bool remote_use_thread = (bool )_EDITOR_GET (" network/language_server/use_thread" );
488
+ if (remote_use_thread) {
489
+ _check_thread_for_cache_update ();
490
+ _add_owner_scene_request (p_path);
491
+ }
492
+ return cache.has (p_path) ? cache[p_path] : nullptr ;
408
493
}
409
494
410
495
Node *SceneCache::get_for_uri (const String &p_uri) {
411
496
String path = workspace->get_file_path (p_uri);
412
- return cache[ path] ;
497
+ return get ( path) ;
413
498
}
414
499
415
500
void SceneCache::set (const String &p_path) {
416
- _set_owner_scene_node (p_path);
501
+ bool remote_use_thread = (bool )_EDITOR_GET (" network/language_server/use_thread" );
502
+ if (remote_use_thread) {
503
+ _check_thread_for_cache_update ();
504
+ _add_owner_scene_request (p_path);
505
+ } else {
506
+ _set_owner_scene_node (p_path);
507
+ }
417
508
}
418
509
419
510
void SceneCache::set_for_uri (const String &p_uri) {
420
511
String path = workspace->get_file_path (p_uri);
421
- _set_owner_scene_node (path);
512
+ set (path);
422
513
}
423
514
424
515
void SceneCache::erase (const String &p_path) {
516
+ bool remote_use_thread = (bool )_EDITOR_GET (" network/language_server/use_thread" );
517
+ if (remote_use_thread && resource_request_queue.has (p_path)) {
518
+ if (is_loading && resource_request_queue.front () == p_path) {
519
+ while (is_loading) {
520
+ _check_thread_for_cache_update ();
521
+ OS::get_singleton ()->delay_usec (50000 );
522
+ }
523
+ } else {
524
+ resource_request_queue.erase (p_path);
525
+ }
526
+ }
527
+ if (!cache.has (p_path)) {
528
+ return ;
529
+ }
425
530
if (cache[p_path]) {
426
531
memdelete (cache[p_path]);
427
532
}
428
533
cache.erase (p_path);
534
+ owners_path_cache.erase (p_path);
429
535
}
430
536
431
537
void SceneCache::erase_for_uri (const String &p_uri) {
432
538
String path = workspace->get_file_path (p_uri);
433
- memdelete (cache[path]);
434
- cache.erase (path);
539
+ erase (path);
435
540
}
436
541
437
542
void SceneCache::clear () {
543
+ if (is_loading) {
544
+ while (is_loading) {
545
+ _check_thread_for_cache_update ();
546
+ OS::get_singleton ()->delay_usec (100 );
547
+ }
548
+ }
549
+ resource_request_queue.clear ();
438
550
for (const KeyValue<String, Node *> &E : cache) {
439
551
if (E.value ) {
440
552
memdelete (E.value );
441
553
}
442
554
}
443
555
cache.clear ();
556
+ owners_path_cache.clear ();
557
+ is_loading = false ;
444
558
}
0 commit comments