summaryrefslogtreecommitdiffstats
path: root/core/io/resource_loader.h
diff options
context:
space:
mode:
Diffstat (limited to 'core/io/resource_loader.h')
-rw-r--r--core/io/resource_loader.h36
1 files changed, 29 insertions, 7 deletions
diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h
index 9fa558299c..35aff65856 100644
--- a/core/io/resource_loader.h
+++ b/core/io/resource_loader.h
@@ -102,10 +102,14 @@ typedef Error (*ResourceLoaderImport)(const String &p_path);
typedef void (*ResourceLoadedCallback)(Ref<Resource> p_resource, const String &p_path);
class ResourceLoader {
+ friend class LoadToken;
+
enum {
MAX_LOADERS = 64
};
+ struct ThreadLoadTask;
+
public:
enum ThreadLoadStatus {
THREAD_LOAD_INVALID_RESOURCE,
@@ -123,7 +127,8 @@ public:
struct LoadToken : public RefCounted {
String local_path;
String user_path;
- Ref<Resource> res_if_unregistered;
+ uint32_t user_rc = 0; // Having user RC implies regular RC incremented in one, until the user RC reaches zero.
+ ThreadLoadTask *task_if_unregistered = nullptr;
void clear();
@@ -132,10 +137,13 @@ public:
static const int BINARY_MUTEX_TAG = 1;
- static Ref<LoadToken> _load_start(const String &p_path, const String &p_type_hint, LoadThreadMode p_thread_mode, ResourceFormatLoader::CacheMode p_cache_mode);
+ static Ref<LoadToken> _load_start(const String &p_path, const String &p_type_hint, LoadThreadMode p_thread_mode, ResourceFormatLoader::CacheMode p_cache_mode, bool p_for_user = false);
static Ref<Resource> _load_complete(LoadToken &p_load_token, Error *r_error);
private:
+ static LoadToken *_load_threaded_request_reuse_user_token(const String &p_path);
+ static void _load_threaded_request_setup_user_token(LoadToken *p_token, const String &p_path);
+
static Ref<Resource> _load_complete_inner(LoadToken &p_load_token, Error *r_error, MutexLock<SafeBinaryMutex<BINARY_MUTEX_TAG>> &p_thread_load_lock);
static Ref<ResourceFormatLoader> loader[MAX_LOADERS];
@@ -169,9 +177,10 @@ private:
Thread::ID thread_id = 0; // Used if running on an user thread (e.g., simple non-threaded load).
bool awaited = false; // If it's in the pool, this helps not awaiting from more than one dependent thread.
ConditionVariable *cond_var = nullptr; // In not in the worker pool or already awaiting, this is used as a secondary awaiting mechanism.
+ uint32_t awaiters_count = 0;
+ bool need_wait = true;
LoadToken *load_token = nullptr;
String local_path;
- String remapped_path;
String type_hint;
float progress = 0.0f;
float max_reported_progress = 0.0f;
@@ -180,18 +189,27 @@ private:
ResourceFormatLoader::CacheMode cache_mode = ResourceFormatLoader::CACHE_MODE_REUSE;
Error error = OK;
Ref<Resource> resource;
- bool xl_remapped = false;
bool use_sub_threads = false;
HashSet<String> sub_tasks;
+
+ struct ResourceChangedConnection {
+ Resource *source = nullptr;
+ Callable callable;
+ uint32_t flags = 0;
+ };
+ LocalVector<ResourceChangedConnection> resource_changed_connections;
};
- static void _thread_load_function(void *p_userdata);
+ static void _run_load_task(void *p_userdata);
static thread_local int load_nesting;
- static thread_local WorkerThreadPool::TaskID caller_task_id;
static thread_local HashMap<int, HashMap<String, Ref<Resource>>> res_ref_overrides; // Outermost key is nesting level.
- static thread_local Vector<String> *load_paths_stack; // A pointer to avoid broken TLS implementations from double-running the destructor.
+ static thread_local Vector<String> load_paths_stack;
+ static thread_local ThreadLoadTask *curr_load_task;
+
static SafeBinaryMutex<BINARY_MUTEX_TAG> thread_load_mutex;
+ friend SafeBinaryMutex<BINARY_MUTEX_TAG> &_get_res_loader_mutex();
+
static HashMap<String, ThreadLoadTask> thread_load_tasks;
static bool cleaning_tasks;
@@ -208,6 +226,10 @@ public:
static bool is_within_load() { return load_nesting > 0; };
+ static void resource_changed_connect(Resource *p_source, const Callable &p_callable, uint32_t p_flags);
+ static void resource_changed_disconnect(Resource *p_source, const Callable &p_callable);
+ static void resource_changed_emit(Resource *p_source);
+
static Ref<Resource> load(const String &p_path, const String &p_type_hint = "", ResourceFormatLoader::CacheMode p_cache_mode = ResourceFormatLoader::CACHE_MODE_REUSE, Error *r_error = nullptr);
static bool exists(const String &p_path, const String &p_type_hint = "");