work on asset manager

This commit is contained in:
Tuomas Katajisto 2026-01-31 20:17:19 +02:00
parent 820a936cc4
commit 9f22ed5452
4 changed files with 105 additions and 54 deletions

View File

@ -0,0 +1,83 @@
#scope_file
hash :: #import "Hash";
MAX_FILE_SIZE :: 2_000_000_000;
buf : [MAX_FILE_SIZE]u8;
Pack_Request :: struct {
name : string;
shouldBlock : bool;
loading : bool = false;
shouldBlockEngine : bool; // Means that the engine loop should do nothing while this is loading...
}
Loaded_Pack :: struct {
nameHash : u32 = 0;
content : Load_Package;
}
Asset_Manager :: struct {
packQueue : [..]Pack_Request;
loadedPacks : [..]Loaded_Pack;
}
g_asset_manager : Asset_Manager;
packcb :: (res: *sfetch_response_t) #c_call {
push_context,defer_pop default_context;
mem : []u8;
mem.count = res.data.size.(s64);
mem.data = res.data.ptr;
pack: Loaded_Pack;
pack.nameHash = hash.get_hash(g_asset_manager.packQueue[0].name);
success := init_from_memory(*pack.content, mem, sprint("%", g_asset_manager.packQueue[0].name));
if !success then print("Failed to load pack!!\n");
array_add(*g_asset_manager.loadedPacks, pack);
array_unordered_remove_by_index(*g_asset_manager.packQueue, 0);
}
#scope_export
// Pack management:
mandatory_loads_done :: () -> bool {
for g_asset_manager.packQueue {
if it.shouldBlockEngine return false;
}
return true;
}
show_loading_screen :: () -> bool {
for g_asset_manager.packQueue {
if it.shouldBlock return true;
}
return false;
}
asset_manager_tick :: () {
if g_asset_manager.packQueue.count > 0 && !g_asset_manager.packQueue[0].loading {
sfetch_send(*(sfetch_request_t.{
path = to_c_string(tprint("./packs/%.pack", g_asset_manager.packQueue[0].name)),
callback = packcb,
buffer = .{
ptr = buf.data,
size = buf.count
}
}));
g_asset_manager.packQueue[0].loading = true;
}
sfetch_dowork();
}
load_pack :: (name: string, shouldBlock: bool = true, shouldBlockEngine: bool = false) {
array_add(*g_asset_manager.packQueue, .{
name = name,
shouldBlock = shouldBlock,
shouldBlockEngine = shouldBlockEngine
});
}
// Asset management:

View File

@ -17,19 +17,22 @@ Mixer_Play_Task :: struct {
audio : *Audio_Data; audio : *Audio_Data;
bus : Mixer_Bus; bus : Mixer_Bus;
mode : Play_Mode; mode : Play_Mode;
curSample : s64; curSample : s64 = 0;
startTime : float64; startTime : float64 = 0;
delay : float64; delay : float64 = 0;
silenceBeforeRepeat : float64; silenceBeforeRepeat : float64 = 0;
} }
Mixer_Config :: struct { Mixer_Config :: struct {
musicVolume : float = 0.5; @Slider,0,1,0.1
masterVolume : float = 0.5; @Slider,0,1,0.1 masterVolume : float = 0.5; @Slider,0,1,0.1
dialogueVolume : float = 0.5; @Slider,0,1,0.1 dialogueVolume : float = 0.5; @Slider,0,1,0.1
soundEffectVolume : float = 0.5; @Slider,0,1,0.1 soundEffectVolume : float = 0.5; @Slider,0,1,0.1
} }
g_mixer : Mixer;
Mixer :: struct { Mixer :: struct {
#if OS != .WASM { #if OS != .WASM {
// If we are on WASM, the Thread module mutex does not work. // If we are on WASM, the Thread module mutex does not work.
@ -50,22 +53,21 @@ Mixer :: struct {
// Removes tasks from the mixer's task list that // Removes tasks from the mixer's task list that
// no longer have a reason to be on the task list. // no longer have a reason to be on the task list.
// Eg. a sound that is .ONESHOT but has already been played. // Eg. a sound that is .ONESHOT but has already been played.
mixer_clean_tasks :: (mixer: *Mixer) { mixer_clean_tasks :: () {
mixer_lock(mixer); mixer_lock(*g_mixer);
defer mixer_unlock(mixer); defer mixer_unlock(*g_mixer);
} }
mixer_add_task :: (mixer: *Mixer, task: Mixer_Play_Task) { mixer_add_task :: (task: Mixer_Play_Task) {
mixer_lock(mixer); mixer_lock(*g_mixer);
defer mixer_unlock(mixer); defer mixer_unlock(*g_mixer);
} }
mixer_get_samples :: (mixer: *Mixer, samples: *float, sampleCount: s32, channelCount: s32) { mixer_get_samples :: (samples: *float, sampleCount: s32, channelCount: s32) {
mixer_lock(mixer); mixer_lock(*g_mixer);
defer mixer_unlock(mixer); defer mixer_unlock(*g_mixer);
} }

View File

@ -1,45 +1,9 @@
g_asset_pack : Load_Package; g_asset_pack : Load_Package;
#scope_file
MAX_FILE_SIZE :: 2_000_000_000;
buf : [MAX_FILE_SIZE]u8;
mandatory_loads_left : s32 = 0;
packcb :: (res: *sfetch_response_t) #c_call {
push_context,defer_pop default_context;
mem : []u8;
mem.count = res.data.size.(s64);
mem.data = res.data.ptr;
print("Mem count %\n", mem.count);
success := init_from_memory(*g_asset_pack, mem, "main_asset_pack");
print("Succesfully loaded main asset pack!\n");
mandatory_loads_left -= 1;
}
#scope_export #scope_export
init_after_mandatory_done : bool = false; init_after_mandatory_done : bool = false;
mandatory_loads_done :: () -> bool {
return mandatory_loads_left <= 0;
}
init_asset_pack_load :: () {
mandatory_loads_left += 1;
sfetch_send(*(sfetch_request_t.{
path = "./packs/assets.pack".data,
callback = packcb,
buffer = .{
ptr = buf.data,
size = buf.count
}
}));
}
add_font_from_pack :: (path: string) { add_font_from_pack :: (path: string) {
ok, entry := table_find(*g_asset_pack.lookup, path); ok, entry := table_find(*g_asset_pack.lookup, path);
if !ok { if !ok {

View File

@ -28,6 +28,7 @@ stbi :: #import "stb_image";
#load "world.jai"; #load "world.jai";
#load "utils.jai"; #load "utils.jai";
#load "audio/audio.jai"; #load "audio/audio.jai";
#load "assets/asset_manager.jai";
#if USE_SAMPLE_GAME { #if USE_SAMPLE_GAME {
#load "../sample_game/game.jai"; #load "../sample_game/game.jai";
@ -107,9 +108,10 @@ init :: () {
state.pass_action_clear_gbuf.colors[0] = .{ load_action = .CLEAR, clear_value = .{ r = 0, g = 0, b = 1000, a = 0 } }; state.pass_action_clear_gbuf.colors[0] = .{ load_action = .CLEAR, clear_value = .{ r = 0, g = 0, b = 1000, a = 0 } };
state.pass_action.colors[0] = .{ load_action = .LOAD }; state.pass_action.colors[0] = .{ load_action = .LOAD };
init_asset_pack_load();
useless_mem : [1]u8; useless_mem : [1]u8;
debug_font = get_font_at_size(useless_mem, 15); debug_font = get_font_at_size(useless_mem, 15);
load_pack("assets", true, true);
} }
init_after_asset_pack :: () { init_after_asset_pack :: () {
@ -153,8 +155,7 @@ frame :: () {
delta_time = get_time() - last_frame_time; delta_time = get_time() - last_frame_time;
last_frame_time = get_time(); last_frame_time = get_time();
asset_manager_tick();
sfetch_dowork();
if mandatory_loads_done() && !init_after_mandatory_done { if mandatory_loads_done() && !init_after_mandatory_done {
init_after_asset_pack(); init_after_asset_pack();
@ -162,6 +163,7 @@ frame :: () {
} }
if !mandatory_loads_done() then return; if !mandatory_loads_done() then return;
fonsClearState(state.fons); fonsClearState(state.fons);
frame_start_time := get_time(); frame_start_time := get_time();