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
|
#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);
|
struct dx11_shader_desc *desc = (struct dx11_shader_desc *)fixed_dict_get(&G.shader_info_lookup, name);
|
||||||
if (desc) {
|
if (desc) {
|
||||||
logf_info("Shader source file \"%F\" has changed", FMT_STR(name));
|
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_watch_info_list res = sys_watch_wait(temp.arena, &watch);
|
||||||
struct sys_lock lock = sys_mutex_lock_e(&G.watch_dispatcher_mutex);
|
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_mutex_unlock(&lock);
|
||||||
sys_condition_variable_broadcast(&G.watch_dispatcher_cv);
|
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
|
* the dispatch of these callbacks, allowing for deduplication of file
|
||||||
* modification notifications. */
|
* modification notifications. */
|
||||||
|
|
||||||
#define WATCH_DISPATCHER_DELAY_SECONDS 0.100
|
#define WATCH_DISPATCHER_DELAY_SECONDS 0.050
|
||||||
#define WATCH_DISPATCHER_DEDUP_DICT_BINS 128
|
#define WATCH_DISPATCHER_DEDUP_DICT_BINS 128
|
||||||
|
|
||||||
INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(resource_watch_dispatcher_thread_entry_point, _)
|
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 */
|
/* Pull watch info from queue */
|
||||||
struct sys_watch_info_list watch_info_list = sys_watch_info_copy(temp.arena, G.watch_dispatcher_info_list);
|
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);
|
arena_reset(&G.watch_dispatcher_info_arena);
|
||||||
|
|
||||||
/* Unlock and run callbacks */
|
/* 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);
|
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) {
|
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;
|
b32 skip = false;
|
||||||
if (info->kind == SYS_WATCH_INFO_KIND_MODIFIED) {
|
if ((u64)fixed_dict_get(&dedup_dict, info->name) == 1) {
|
||||||
/* 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 {
|
|
||||||
skip = true;
|
skip = true;
|
||||||
}
|
} else {
|
||||||
|
fixed_dict_set(temp.arena, &dedup_dict, info->name, (void *)1);
|
||||||
}
|
}
|
||||||
if (!skip) {
|
if (!skip) {
|
||||||
struct sys_lock callbacks_lock = sys_mutex_lock_s(&G.watch_callbacks_mutex);
|
struct sys_lock callbacks_lock = sys_mutex_lock_s(&G.watch_callbacks_mutex);
|
||||||
for (u64 i = 0; i < G.num_watch_callbacks; ++i) {
|
for (u64 i = 0; i < G.num_watch_callbacks; ++i) {
|
||||||
resource_watch_callback *callback = G.watch_callbacks[i];
|
resource_watch_callback *callback = G.watch_callbacks[i];
|
||||||
callback(info);
|
callback(info->name);
|
||||||
}
|
}
|
||||||
sys_mutex_unlock(&callbacks_lock);
|
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)
|
#define resource_get_name(res_ptr) STRING((res_ptr)->_file_name_len, (res_ptr)->_file_name_text)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define RESOURCE_WATCH_CALLBACK_FUNC_DEF(func_name, arg_info) void func_name(struct sys_watch_info *arg_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, info);
|
typedef RESOURCE_WATCH_CALLBACK_FUNC_DEF(resource_watch_callback, name);
|
||||||
|
|
||||||
#if RESOURCE_RELOADING
|
#if RESOURCE_RELOADING
|
||||||
void resource_register_watch_callback(resource_watch_callback *callback);
|
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));
|
logf_info("Loading sprite sheet [%F] \"%F\"", FMT_HEX(n->hash.v), FMT_STR(path));
|
||||||
i64 start_ns = sys_time_ns();
|
i64 start_ns = sys_time_ns();
|
||||||
|
|
||||||
//ASSERT(string_ends_with(path, LIT(".ase")));
|
|
||||||
ASSERT(n->kind == CACHE_NODE_KIND_SHEET);
|
ASSERT(n->kind == CACHE_NODE_KIND_SHEET);
|
||||||
|
|
||||||
/* TODO: Replace arena allocs w/ buddy allocator */
|
/* TODO: Replace arena allocs w/ buddy allocator */
|
||||||
@ -1076,9 +1075,8 @@ INTERNAL WORK_TASK_FUNC_DEF(sprite_load_task, arg)
|
|||||||
|
|
||||||
#if RESOURCE_RELOADING
|
#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);
|
struct sprite_tag tag = sprite_tag_from_path(name);
|
||||||
for (enum cache_node_kind kind = 0; kind < NUM_CACHE_NODE_KINDS; ++kind) {
|
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);
|
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) {
|
for (struct cache_node *n = bin->first; n; n = n->next_in_bin) {
|
||||||
if (n->hash.v == hash.v) {
|
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);
|
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;
|
struct cache_node_refcount refcount = *(struct cache_node_refcount *)&refcount_uncast;
|
||||||
if (refcount.count <= 0) {
|
if (refcount.count <= 0) {
|
||||||
#if RESOURCE_RELOADING
|
#if RESOURCE_RELOADING
|
||||||
/* Check if file changed for resource reloading */
|
/* Force evict out-of-date sprites */
|
||||||
if (!consider_for_eviction) {
|
|
||||||
if (atomic_i32_eval(&n->out_of_date)) {
|
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;
|
consider_for_eviction = true;
|
||||||
force_evict = true;
|
force_evict = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Check usage time */
|
/* Check usage time */
|
||||||
|
|||||||
@ -786,6 +786,7 @@ struct sys_watch_info_list sys_watch_wait(struct arena *arena, struct sys_watch
|
|||||||
list.last = info;
|
list.last = info;
|
||||||
} else {
|
} else {
|
||||||
list.first = info;
|
list.first = info;
|
||||||
|
list.last = info;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct string16 name16 = ZI;
|
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;
|
dst_list.last = dst;
|
||||||
} else {
|
} else {
|
||||||
dst_list.first = dst;
|
dst_list.first = dst;
|
||||||
|
dst_list.last = dst;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return dst_list;
|
return dst_list;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user