summaryrefslogtreecommitdiffstats
path: root/game/client
diff options
context:
space:
mode:
authoruntodesu <kirill@untode.su>2025-09-11 14:13:39 +0500
committeruntodesu <kirill@untode.su>2025-09-11 14:13:39 +0500
commit8784cbfebcb8a0220fb947a6070032e20b80fc2f (patch)
tree2e03a2c013ed7b19a5dafaba1ddfb05c1878449a /game/client
parentf0cc06c7388acb32b86301965c5b2547e4e3b919 (diff)
downloadvoxelius-8784cbfebcb8a0220fb947a6070032e20b80fc2f.tar.bz2
voxelius-8784cbfebcb8a0220fb947a6070032e20b80fc2f.zip
Another qfengine graft: resource management
DECOPYPASTA DECOPYPASTA DECOPYPASTA DECOPYPASTA
Diffstat (limited to 'game/client')
-rw-r--r--game/client/main.cc17
-rw-r--r--game/client/resource/sound_effect.cc64
-rw-r--r--game/client/resource/sound_effect.hh2
-rw-r--r--game/client/resource/texture_gui.cc56
-rw-r--r--game/client/resource/texture_gui.hh4
5 files changed, 42 insertions, 101 deletions
diff --git a/game/client/main.cc b/game/client/main.cc
index 51d4670..72c116e 100644
--- a/game/client/main.cc
+++ b/game/client/main.cc
@@ -221,6 +221,11 @@ int main(int argc, char** argv)
spdlog::info("opengl: version: {}", reinterpret_cast<const char*>(glGetString(GL_VERSION)));
spdlog::info("opengl: renderer: {}", reinterpret_cast<const char*>(glGetString(GL_RENDERER)));
+ BinFile::register_resource();
+ Image::register_resource();
+ TextureGUI::register_resource();
+ SoundEffect::register_resource();
+
glDisable(GL_MULTISAMPLE);
IMGUI_CHECKVERSION();
@@ -406,22 +411,14 @@ int main(int argc, char** argv)
globals::window_framecount += 1;
- resource::soft_cleanup<BinFile>();
- resource::soft_cleanup<Image>();
-
- resource::soft_cleanup<SoundEffect>();
- resource::soft_cleanup<TextureGUI>();
+ resource::soft_cleanup();
threading::update();
}
client_game::shutdown();
- resource::hard_cleanup<BinFile>();
- resource::hard_cleanup<Image>();
-
- resource::hard_cleanup<SoundEffect>();
- resource::hard_cleanup<TextureGUI>();
+ resource::hard_cleanup();
spdlog::info("client: shutdown after {} frames", globals::window_framecount);
spdlog::info("client: average framerate: {:.03f} FPS", 1.0f / globals::window_frametime_avg);
diff --git a/game/client/resource/sound_effect.cc b/game/client/resource/sound_effect.cc
index 75d5984..fad5b18 100644
--- a/game/client/resource/sound_effect.cc
+++ b/game/client/resource/sound_effect.cc
@@ -3,11 +3,10 @@
#include "client/resource/sound_effect.hh"
#include "core/resource/resource.hh"
+#include "core/utils/physfs.hh"
#include "client/globals.hh"
-static emhash8::HashMap<std::string, resource_ptr<SoundEffect>> resource_map;
-
static std::size_t drwav_read_physfs(void* file, void* output, std::size_t count)
{
return static_cast<std::size_t>(PHYSFS_readBytes(reinterpret_cast<PHYSFS_File*>(file), output, count));
@@ -23,38 +22,32 @@ static drwav_bool32 drwav_seek_physfs(void* file, int offset, drwav_seek_origin
}
}
-template<>
-resource_ptr<SoundEffect> resource::load<SoundEffect>(std::string_view name, unsigned int flags)
+static const void* sound_effect_load_func(const char* name, std::uint32_t flags)
{
- auto it = resource_map.find(std::string(name));
-
- if(it != resource_map.cend()) {
- // Return an existing resource
- return it->second;
- }
+ assert(name);
if(globals::sound_ctx == nullptr) {
// Sound is disabled
return nullptr;
}
- auto file = PHYSFS_openRead(std::string(name).c_str());
+ auto file = PHYSFS_openRead(name);
if(file == nullptr) {
- spdlog::warn("resource: {} [SoundEffect]: {}", name, PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
+ spdlog::warn("sfx: {}: {}", name, utils::physfs_error());
return nullptr;
}
drwav wav_info;
if(!drwav_init(&wav_info, &drwav_read_physfs, &drwav_seek_physfs, file, nullptr)) {
- spdlog::warn("resource: {} [SoundEffect]: drwav_init failed", name);
+ spdlog::warn("sfx: {}: drwav_init failed", name);
PHYSFS_close(file);
return nullptr;
}
if(wav_info.channels != 1) {
- spdlog::warn("resource: {} [SoundEffect]: only mono sound files are allowed", name);
+ spdlog::warn("sfx: {}: only mono sound files are allowed", name);
drwav_uninit(&wav_info);
PHYSFS_close(file);
return nullptr;
@@ -68,7 +61,7 @@ resource_ptr<SoundEffect> resource::load<SoundEffect>(std::string_view name, uns
drwav_uninit(&wav_info);
PHYSFS_close(file);
- auto new_resource = std::make_shared<SoundEffect>();
+ auto new_resource = new SoundEffect();
new_resource->name = std::string(name);
alGenBuffers(1, &new_resource->buffer);
@@ -76,42 +69,21 @@ resource_ptr<SoundEffect> resource::load<SoundEffect>(std::string_view name, uns
delete[] samples;
- return resource_map.insert_or_assign(std::string(name), new_resource).first->second;
-}
-
-template<>
-void resource::hard_cleanup<SoundEffect>(void)
-{
- for(const auto& it : resource_map) {
- if(it.second.use_count() > 1L) {
- spdlog::warn("resource: zombie resource [SoundEffect] {} [use_count={}]", it.first, it.second.use_count());
- }
- else {
- spdlog::debug("resource: releasing [SoundEffect] {}", it.first);
- }
-
- alDeleteBuffers(1, &it.second->buffer);
- }
-
- resource_map.clear();
+ return new_resource;
}
-template<>
-void resource::soft_cleanup<SoundEffect>(void)
+static void sound_effect_free_func(const void* resource)
{
- auto iter = resource_map.cbegin();
-
- while(iter != resource_map.cend()) {
- if(iter->second.use_count() == 1L) {
- spdlog::debug("resource: releasing [SoundEffect] {}", iter->first);
+ assert(resource);
- alDeleteBuffers(1, &iter->second->buffer);
+ auto sound_effect = reinterpret_cast<const SoundEffect*>(resource);
- iter = resource_map.erase(iter);
+ alDeleteBuffers(1, &sound_effect->buffer);
- continue;
- }
+ delete sound_effect;
+}
- iter = std::next(iter);
- }
+void SoundEffect::register_resource(void)
+{
+ resource::register_loader<SoundEffect>(&sound_effect_load_func, &sound_effect_free_func);
}
diff --git a/game/client/resource/sound_effect.hh b/game/client/resource/sound_effect.hh
index 8b1372b..8fa3da4 100644
--- a/game/client/resource/sound_effect.hh
+++ b/game/client/resource/sound_effect.hh
@@ -3,6 +3,8 @@
#pragma once
struct SoundEffect final {
+ static void register_resource(void);
+
std::string name;
ALuint buffer;
};
diff --git a/game/client/resource/texture_gui.cc b/game/client/resource/texture_gui.cc
index 415845d..beb2f54 100644
--- a/game/client/resource/texture_gui.cc
+++ b/game/client/resource/texture_gui.cc
@@ -5,17 +5,9 @@
#include "core/resource/image.hh"
#include "core/resource/resource.hh"
-static emhash8::HashMap<std::string, resource_ptr<TextureGUI>> resource_map;
-
-template<>
-resource_ptr<TextureGUI> resource::load<TextureGUI>(std::string_view name, unsigned int flags)
+static const void* texture_gui_load_func(const char* name, std::uint32_t flags)
{
- auto it = resource_map.find(std::string(name));
-
- if(it != resource_map.cend()) {
- // Return an existing resource
- return it->second;
- }
+ assert(name);
unsigned int image_load_flags = 0U;
@@ -62,54 +54,30 @@ resource_ptr<TextureGUI> resource::load<TextureGUI>(std::string_view name, unsig
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
- auto new_resource = std::make_shared<TextureGUI>();
+ auto new_resource = new TextureGUI();
new_resource->handle = static_cast<ImTextureID>(gl_texture);
new_resource->size.x = image->size.x;
new_resource->size.y = image->size.y;
- return resource_map.insert_or_assign(std::string(name), new_resource).first->second;
+ return new_resource;
}
return nullptr;
}
-template<>
-void resource::hard_cleanup<TextureGUI>(void)
+static void texture_gui_free_func(const void* resource)
{
- for(const auto& it : resource_map) {
- if(it.second.use_count() > 1L) {
- spdlog::warn("resource: zombie resource [TextureGUI] {} [use_count={}]", it.first, it.second.use_count());
- }
- else {
- spdlog::debug("resource: releasing [TextureGUI] {}", it.first);
- }
+ assert(resource);
- auto gl_texture = static_cast<GLuint>(it.second->handle);
+ auto texture_gui = reinterpret_cast<const TextureGUI*>(resource);
+ auto gl_texture = static_cast<GLuint>(texture_gui->handle);
- glDeleteTextures(1, &gl_texture);
- }
+ glDeleteTextures(1, &gl_texture);
- resource_map.clear();
+ delete texture_gui;
}
-template<>
-void resource::soft_cleanup<TextureGUI>(void)
+void TextureGUI::register_resource(void)
{
- auto iter = resource_map.cbegin();
-
- while(iter != resource_map.cend()) {
- if(iter->second.use_count() == 1L) {
- spdlog::debug("resource: releasing [TextureGUI] {}", iter->first);
-
- auto gl_texture = static_cast<GLuint>(iter->second->handle);
-
- glDeleteTextures(1, &gl_texture);
-
- iter = resource_map.erase(iter);
-
- continue;
- }
-
- iter = std::next(iter);
- }
+ resource::register_loader<TextureGUI>(&texture_gui_load_func, &texture_gui_free_func);
}
diff --git a/game/client/resource/texture_gui.hh b/game/client/resource/texture_gui.hh
index 855596e..988c642 100644
--- a/game/client/resource/texture_gui.hh
+++ b/game/client/resource/texture_gui.hh
@@ -9,7 +9,9 @@ constexpr static unsigned int TEXTURE_GUI_LOAD_LINEAR_MIN = 0x0008;
constexpr static unsigned int TEXTURE_GUI_LOAD_VFLIP = 0x0010;
constexpr static unsigned int TEXTURE_GUI_LOAD_GRAYSCALE = 0x0020;
-struct TextureGUI {
+struct TextureGUI final {
+ static void register_resource(void);
+
ImTextureID handle;
glm::ivec2 size;
};