fix resource watch list merging & deduplication
This commit is contained in:
parent
726ad90784
commit
d8f1d646da
BIN
res/graphics/tim.ase
(Stored with Git LFS)
BIN
res/graphics/tim.ase
(Stored with Git LFS)
Binary file not shown.
@ -369,9 +369,8 @@ INTERNAL void reload_shader(struct dx11_shader *old_shader, struct dx11_shader_d
|
||||
}
|
||||
|
||||
#if RESOURCE_RELOADING
|
||||
INTERNAL RESOURCE_WATCH_CALLBACK_FUNC_DEF(shader_resource_watch_callback, info)
|
||||
INTERNAL RESOURCE_WATCH_CALLBACK_FUNC_DEF(shader_resource_watch_callback, name)
|
||||
{
|
||||
struct string name = info->name;
|
||||
struct dx11_shader_desc *desc = (struct dx11_shader_desc *)fixed_dict_get(&G.shader_info_lookup, name);
|
||||
if (desc) {
|
||||
logf_info("Shader source file \"%F\" has changed", FMT_STR(name));
|
||||
|
||||
@ -183,7 +183,14 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(resource_watch_monitor_thread_entry_poi
|
||||
struct sys_watch_info_list res = sys_watch_wait(temp.arena, &watch);
|
||||
struct sys_lock lock = sys_mutex_lock_e(&G.watch_dispatcher_mutex);
|
||||
{
|
||||
G.watch_dispatcher_info_list = sys_watch_info_copy(&G.watch_dispatcher_info_arena, res);
|
||||
struct sys_watch_info_list list_part = sys_watch_info_copy(&G.watch_dispatcher_info_arena, res);
|
||||
if (G.watch_dispatcher_info_list.last) {
|
||||
G.watch_dispatcher_info_list.last->next = list_part.first;
|
||||
list_part.first->prev = G.watch_dispatcher_info_list.last;
|
||||
G.watch_dispatcher_info_list.last = list_part.last;
|
||||
} else {
|
||||
G.watch_dispatcher_info_list = list_part;
|
||||
}
|
||||
}
|
||||
sys_mutex_unlock(&lock);
|
||||
sys_condition_variable_broadcast(&G.watch_dispatcher_cv);
|
||||
@ -199,7 +206,7 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(resource_watch_monitor_thread_entry_poi
|
||||
* the dispatch of these callbacks, allowing for deduplication of file
|
||||
* modification notifications. */
|
||||
|
||||
#define WATCH_DISPATCHER_DELAY_SECONDS 0.100
|
||||
#define WATCH_DISPATCHER_DELAY_SECONDS 0.050
|
||||
#define WATCH_DISPATCHER_DEDUP_DICT_BINS 128
|
||||
|
||||
INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(resource_watch_dispatcher_thread_entry_point, _)
|
||||
@ -221,6 +228,7 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(resource_watch_dispatcher_thread_entry_
|
||||
|
||||
/* Pull watch info from queue */
|
||||
struct sys_watch_info_list watch_info_list = sys_watch_info_copy(temp.arena, G.watch_dispatcher_info_list);
|
||||
MEMZERO_STRUCT(&G.watch_dispatcher_info_list);
|
||||
arena_reset(&G.watch_dispatcher_info_arena);
|
||||
|
||||
/* Unlock and run callbacks */
|
||||
@ -228,20 +236,18 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(resource_watch_dispatcher_thread_entry_
|
||||
{
|
||||
struct fixed_dict dedup_dict = fixed_dict_init(temp.arena, WATCH_DISPATCHER_DEDUP_DICT_BINS);
|
||||
for (struct sys_watch_info *info = watch_info_list.first; info; info = info->next) {
|
||||
/* Do not run callbacks for the same file more than once */
|
||||
b32 skip = false;
|
||||
if (info->kind == SYS_WATCH_INFO_KIND_MODIFIED) {
|
||||
/* Skip modified notifications for the same file */
|
||||
if ((u64)fixed_dict_get(&dedup_dict, info->name) != 1) {
|
||||
fixed_dict_set(temp.arena, &dedup_dict, info->name, (void *)1);
|
||||
} else {
|
||||
if ((u64)fixed_dict_get(&dedup_dict, info->name) == 1) {
|
||||
skip = true;
|
||||
}
|
||||
} else {
|
||||
fixed_dict_set(temp.arena, &dedup_dict, info->name, (void *)1);
|
||||
}
|
||||
if (!skip) {
|
||||
struct sys_lock callbacks_lock = sys_mutex_lock_s(&G.watch_callbacks_mutex);
|
||||
for (u64 i = 0; i < G.num_watch_callbacks; ++i) {
|
||||
resource_watch_callback *callback = G.watch_callbacks[i];
|
||||
callback(info);
|
||||
callback(info->name);
|
||||
}
|
||||
sys_mutex_unlock(&callbacks_lock);
|
||||
}
|
||||
|
||||
@ -39,8 +39,8 @@ b32 resource_exists(struct string path);
|
||||
#define resource_get_name(res_ptr) STRING((res_ptr)->_file_name_len, (res_ptr)->_file_name_text)
|
||||
#endif
|
||||
|
||||
#define RESOURCE_WATCH_CALLBACK_FUNC_DEF(func_name, arg_info) void func_name(struct sys_watch_info *arg_info)
|
||||
typedef RESOURCE_WATCH_CALLBACK_FUNC_DEF(resource_watch_callback, info);
|
||||
#define RESOURCE_WATCH_CALLBACK_FUNC_DEF(func_name, arg_name) void func_name(struct string arg_name)
|
||||
typedef RESOURCE_WATCH_CALLBACK_FUNC_DEF(resource_watch_callback, name);
|
||||
|
||||
#if RESOURCE_RELOADING
|
||||
void resource_register_watch_callback(resource_watch_callback *callback);
|
||||
|
||||
10
src/sprite.c
10
src/sprite.c
@ -655,7 +655,6 @@ INTERNAL void cache_node_load_sheet(struct cache_node *n, struct sprite_tag tag)
|
||||
logf_info("Loading sprite sheet [%F] \"%F\"", FMT_HEX(n->hash.v), FMT_STR(path));
|
||||
i64 start_ns = sys_time_ns();
|
||||
|
||||
//ASSERT(string_ends_with(path, LIT(".ase")));
|
||||
ASSERT(n->kind == CACHE_NODE_KIND_SHEET);
|
||||
|
||||
/* TODO: Replace arena allocs w/ buddy allocator */
|
||||
@ -1076,9 +1075,8 @@ INTERNAL WORK_TASK_FUNC_DEF(sprite_load_task, arg)
|
||||
|
||||
#if RESOURCE_RELOADING
|
||||
|
||||
INTERNAL RESOURCE_WATCH_CALLBACK_FUNC_DEF(sprite_resource_watch_callback, info)
|
||||
INTERNAL RESOURCE_WATCH_CALLBACK_FUNC_DEF(sprite_resource_watch_callback, name)
|
||||
{
|
||||
struct string name = info->name;
|
||||
struct sprite_tag tag = sprite_tag_from_path(name);
|
||||
for (enum cache_node_kind kind = 0; kind < NUM_CACHE_NODE_KINDS; ++kind) {
|
||||
struct cache_node_hash hash = cache_node_hash_from_tag_hash(tag.hash, kind);
|
||||
@ -1088,6 +1086,7 @@ INTERNAL RESOURCE_WATCH_CALLBACK_FUNC_DEF(sprite_resource_watch_callback, info)
|
||||
{
|
||||
for (struct cache_node *n = bin->first; n; n = n->next_in_bin) {
|
||||
if (n->hash.v == hash.v) {
|
||||
logf_info("Sprite resource file \"%F\" has changed and will be reloaded.", FMT_STR(name));
|
||||
atomic_i32_eval_exchange(&n->out_of_date, 1);
|
||||
}
|
||||
}
|
||||
@ -1162,14 +1161,11 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(sprite_evictor_thread_entry_point, arg)
|
||||
struct cache_node_refcount refcount = *(struct cache_node_refcount *)&refcount_uncast;
|
||||
if (refcount.count <= 0) {
|
||||
#if RESOURCE_RELOADING
|
||||
/* Check if file changed for resource reloading */
|
||||
if (!consider_for_eviction) {
|
||||
/* Force evict out-of-date sprites */
|
||||
if (atomic_i32_eval(&n->out_of_date)) {
|
||||
logf_info("Resource file for sprite texture/sheet [%F] has changed. Evicting to allow for reloading.", FMT_HEX(n->hash.v));
|
||||
consider_for_eviction = true;
|
||||
force_evict = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check usage time */
|
||||
|
||||
@ -786,6 +786,7 @@ struct sys_watch_info_list sys_watch_wait(struct arena *arena, struct sys_watch
|
||||
list.last = info;
|
||||
} else {
|
||||
list.first = info;
|
||||
list.last = info;
|
||||
}
|
||||
|
||||
struct string16 name16 = ZI;
|
||||
@ -857,6 +858,7 @@ struct sys_watch_info_list sys_watch_info_copy(struct arena *arena, struct sys_w
|
||||
dst_list.last = dst;
|
||||
} else {
|
||||
dst_list.first = dst;
|
||||
dst_list.last = dst;
|
||||
}
|
||||
}
|
||||
return dst_list;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user