Commit e5b5f698 authored by Johannes Braun's avatar Johannes Braun
Browse files

Changed ressource containers and message queue to not crash on simple actions

parent 8c03e399
......@@ -4,7 +4,7 @@
#include <core/rendering/gbuffer.h>
#include <core/objects/skybox.h>
#include <core/objects/light.h>
#include <core/res/resources.h>
#include <core/res/res.h>
#include <components/PlayerController.h>
#include <components/FramerateCounter.h>
......@@ -33,7 +33,7 @@ int main(int argc, char* argv[])
cam_node->makeComponent<component::FramerateCounter>();
//Attach plane as child in front of the camera.
auto plane = core::Resources::getInstance().getColladaMesh(files::asset("meshes/scenery/TY_Plane.dae"), "Cube_001");
auto plane = core::global_resources::scenes.get(files::asset("meshes/scenery/cbox.dae"), 1.0f)->find("#Cube_001-mesh");
cam_node->attach(plane);
plane->transform.position = { 0, -2.f, -15 };
plane->transform.rotate({ glm::radians(-90.f), glm::radians(90.f), 0.f });
......
#include <core/base/program.h>
#include <core/rendering/texture_renderer.h>
#include <core/state.h>
#include <core/res/resources.h>
#include <core/res/res.h>
#include <util/files.h>
#include <util/images.h>
......@@ -75,7 +75,7 @@ int main(int argc, char* argv[])
// ... draw a button which loads a dae file.
else if (std::binary_search(extensions.begin(), extensions.end(), path.extension().string()) && ImGui::FeatureButton(path.filename().string().c_str(), ImVec2(ImGui::GetContentRegionAvailWidth(), 32)))
{
image = core::Resources::getInstance().getTextureHDR(path);
image = core::global_resources::textures_hdr.get(path);
zoom = 1.f;
}
}
......@@ -115,7 +115,7 @@ int main(int argc, char* argv[])
// ... draw a button which loads a dae file.
else if (std::binary_search(extensions.begin(), extensions.end(), path.extension().string()) && ImGui::FeatureButton(path.filename().string().c_str(), ImVec2(ImGui::GetContentRegionAvailWidth(), 32)))
{
heatmap_other_image = core::Resources::getInstance().getTextureHDR(path);
heatmap_other_image = core::global_resources::textures_hdr.get(path);
if (!image)
{
Log_Error << "Please select a source image first!";
......
#include <core/state.h>
#include <core/res/resources.h>
#include <core/res/res.h>
#include <core/objects/skybox.h>
#include <core/rendering/batch_renderer.h>
......
#include <core/state.h>
#include <core/res/resources.h>
#include <core/res/res.h>
#include <core/objects/skybox.h>
#include <components/PlayerController.h>
......@@ -15,7 +15,7 @@ int main(int argc, char* argv[])
core::state::initialize(files::asset("/preferences/default.xml"));
// Load a scene and attach it to the constant root
core::state::graph_root->attach(core::Resources::getInstance().getColladaFile(files::asset("meshes/scenery/House.dae")));
core::state::graph_root->attach(core::global_resources::scenes.get(files::asset("meshes/scenery/cbox.dae"), 1.0f));
// Create a skybox
core::state::skybox->reset(core::Skybox::collectFilesFrom(files::asset("textures/ryfjallet/")));
......
#include <core/state.h>
#include <core/res/resources.h>
#include <core/res/res.h>
#include <core/objects/skybox.h>
#include <components/PlayerController.h>
......@@ -13,7 +13,7 @@ int main(int argc, char* argv[])
core::state::initialize(files::asset("/preferences/default.xml"));
// Load a scene and attach it to the constant root
core::state::graph_root->attach(core::Resources::getInstance().getColladaFile(files::asset("meshes/scenery/cbox.dae")));
core::state::graph_root->attach(core::global_resources::scenes.get(files::asset("meshes/scenery/cbox.dae"), 1.0f));
// Create a skybox
core::state::skybox->reset(core::Skybox::collectFilesFrom(files::asset("textures/ryfjallet/")));
......
......@@ -10,7 +10,7 @@
#include <core/objects/skybox.h>
#include <core/rendering/gbuffer.h>
#include <core/rendering/batch_render_list.h>
#include <core/res/resources.h>
#include <core/res/res.h>
#include <raytrace/tracer/pathtracer.h>
......@@ -62,7 +62,7 @@ int main(int argc, char* argv[])
// Make some ambient sound source
al::listenerf(al::ListenerParam::eGain, 0.02f);
auto audio_buffer = core::Resources::getInstance().getAudioBuffer(env_audio_path);
auto audio_buffer = core::global_resources::sounds.get(env_audio_path);
auto environment_source = core::state::graph_root->makeComponent<core::SoundSource>(audio_buffer->id());
environment_source->setLooping(true);
environment_source->play();
......@@ -114,7 +114,7 @@ void loadScene(const fs::path& path, float scale)
core::state::graph_root->clearChildren();
//Initialize some scene graph from an obj file
if (auto scene = core::Resources::getInstance().getColladaFile(path, scale))
if (auto scene = core::global_resources::scenes.get(path, scale))
{
core::state::graph_root->attach(scene);
}
......
#include "splash_screen.h"
#include <core/res/resources.h>
#include <core/res/res.h>
#include <core/time.h>
#include <util/files.h>
#include "pugixml/pugixml.hpp"
namespace glare
{
......@@ -39,7 +40,7 @@ namespace glare
if (asset_path != "") {
m_background_config |= 1 << 3;
m_background_texture = Resources::getInstance().getTexture(files::asset(asset_path));
m_background_texture = global_resources::textures_ldr.get(files::asset(asset_path));
m_background_scale = splash_background.child("texture").attribute("scale").as_float();
}
......@@ -50,8 +51,8 @@ namespace glare
{
m_duration = duration;
m_logo_renderer = core::DefaultTextureRenderers::makeCenterTextureRenderer();
m_texture = Resources::getInstance().getTexture(logo);
m_sound = Resources::getInstance().getAudioBuffer(sound);
m_texture = global_resources::textures_ldr.get(logo);
m_sound = global_resources::sounds.get(sound);
m_sound_source = std::make_unique<core::SoundSource>(m_sound->id());
m_logo_renderer->shader().uniform("u_background_color", m_color);
......
......@@ -10,7 +10,8 @@
#include <core/rendering/batch_renderer.h>
#include <core/rendering/mesh_drawable.h>
#include "resources.h"
//#include "resources.h"
#include "res.h"
namespace glare
{
......@@ -739,7 +740,7 @@ namespace glare
{
path = path.substr(6, path.size() - 6);
}
data->images.emplace(id, Resources::getInstance().getTexture(directory + "/" + path));
data->images.emplace(id, global_resources::textures_ldr.get(directory + "/" + path));
}
}
......
#include "res.h"
#include "collada.h"
namespace glare
{
namespace core
{
namespace global_resources
{
const SimpleResourceStorage<TextureRGBA_UB> textures_ldr = SimpleResourceStorage<TextureRGBA_UB>([](const fs::path& path)
{
return textures::loadTexture<TextureRGBA_UB>(path);
});
const SimpleResourceStorage<TextureRGBA_32F> textures_hdr = SimpleResourceStorage<TextureRGBA_32F>([](const fs::path& path)
{
return textures::loadTexture<TextureRGBA_32F>(path);
});
const SimpleResourceStorage<SoundBuffer> sounds = SimpleResourceStorage<SoundBuffer>([](const fs::path& path)
{
return std::make_shared<SoundBuffer>(path);
});
const SimpleResourceStorage<Font> fonts = SimpleResourceStorage<Font>([](const fs::path& path)
{
return std::make_shared<Font>(path);
});
const SimpleResourceStorage<GraphNode, float> scenes = SimpleResourceStorage<GraphNode, float>([](const fs::path& path, float import_scale)
{
return Collada().load(path, import_scale);
});
}
}
}
\ No newline at end of file
#ifndef INCLUDE_RES_H
#define INCLUDE_RES_H
#include <functional>
#include <string>
#include <map>
#include <memory>
#include "util/log.h"
#include <core/res/texture2d.h>
#include "core/audio/sound_buffer.h"
#include "fonts.h"
#include "core/graph/node.h"
namespace glare
{
namespace core
{
template<typename T, typename TLoader, typename... Args>
struct ResourceStorage
{
explicit ResourceStorage(TLoader loader);
std::shared_ptr<T> get(const std::string& identifier, Args... args, bool force_reload = false) const;
std::shared_ptr<T> get(const fs::path& identifier, Args... args) const;
private:
TLoader m_loader;
mutable std::map<std::string, std::shared_ptr<T>> m_storage;
};
template <typename T, typename TLoader, typename ... Args>
ResourceStorage<T, TLoader, Args...>::ResourceStorage(TLoader loader)
: m_loader(loader)
{
}
template <typename T, typename TLoader, typename ... Args>
std::shared_ptr<T> ResourceStorage<T, TLoader, Args...>::get(const std::string& identifier, Args... args, bool force_reload) const
{
try {
if (m_storage.count(identifier) == 0 || force_reload)
{
// object not existing yet.
auto loaded_resource = m_loader(identifier, args...);
m_storage.emplace(identifier, loaded_resource);
return loaded_resource;
}
return m_storage[identifier];
}
catch (...)
{
Log_Error << "Failed to load the resource (identifier: \"" << identifier << "\"!";
return nullptr;
}
}
template <typename T, typename TLoader, typename ... Args>
std::shared_ptr<T> ResourceStorage<T, TLoader, Args...>::get(const fs::path& identifier, Args... args) const
{
return get(identifier.string(), args..., false);
}
namespace global_resources
{
template<typename T, typename ...Args> using SimpleResourceStorage = ResourceStorage<T, std::shared_ptr<T>(*)(const fs::path&, Args...), Args...>;
extern const SimpleResourceStorage<TextureRGBA_UB> textures_ldr;
extern const SimpleResourceStorage<TextureRGBA_32F> textures_hdr;
extern const SimpleResourceStorage<SoundBuffer> sounds;
extern const SimpleResourceStorage<Font> fonts;
extern const SimpleResourceStorage<GraphNode, float> scenes;
}
}
}
#endif //!INCLUDE_RES_H
\ No newline at end of file
#include "Resources.h"
namespace glare
{
namespace core
{
std::shared_ptr<TextureRGBA_UB> Resources::getTexture(const fs::path& path, bool force_reload)
{
return m_texture_storage.get(path.string(), force_reload, [&]() -> std::shared_ptr<TextureRGBA_UB>
{
return textures::loadTexture<TextureRGBA_UB>(path);
});
}
std::shared_ptr<TextureRGBA_32F> Resources::getTextureHDR(const fs::path& path, bool force_reload)
{
return m_texture_storage_hdr.get(path.string(), force_reload, [&]() -> std::shared_ptr<TextureRGBA_32F>
{
return textures::loadTexture<TextureRGBA_32F>(path);
});
}
std::shared_ptr<SoundBuffer> Resources::getAudioBuffer(const fs::path &path, bool force_reload)
{
return m_audio_storage.get(path.string(), force_reload, [&]() -> std::shared_ptr<SoundBuffer>
{
return std::make_shared<SoundBuffer>(path);
});
}
std::shared_ptr<Font> Resources::getFont(const fs::path& path, bool force_reload)
{
return m_fonts_storage.get(path.string(), force_reload, [&] () -> std::shared_ptr<Font>
{
return std::make_shared<Font>(path);
});
}
std::shared_ptr<GraphNode> Resources::getColladaFile(const fs::path &scene_path, float import_scale, bool force_reload)
{
return m_collada_scenes_storage.get(scene_path.string(), force_reload, [&]() {
if (fs::exists(scene_path))
{
Collada collada_loader;
return collada_loader.load(scene_path, import_scale);
}
else
{
return std::shared_ptr<core::GraphNode>(nullptr);
}
});
}
std::shared_ptr<core::GraphNode> Resources::getColladaNode(const fs::path &scene_path, const std::string &node_name, float import_scale, bool force_reload)
{
return getColladaFile(scene_path, import_scale, force_reload)->find(node_name);
}
std::shared_ptr<core::GraphNode> Resources::getColladaMesh(const fs::path &scene_path, const std::string &mesh_name, float import_scale, bool force_reload)
{
return getColladaFile(scene_path, import_scale, force_reload)->find("#" + mesh_name + "-mesh");
}
}
}
#ifndef INCLUDE_RESOURCES_H
#define INCLUDE_RESOURCES_H
#include <filesystem>
#include <functional>
#include <map>
#include <memory>
#include <pugixml/pugixml.hpp>
#include <util/log.h>
#include <util/singleton.h>
#include <core/audio/sound_buffer.h>
#include "collada.h"
#include "fonts.h"
#include "texture2d.h"
#include <mutex>
namespace glare
{
namespace core
{
namespace fs = std::experimental::filesystem;
template<typename T>
class ResourceStorage
{
public:
std::shared_ptr<T> get(const std::string &id, bool force_reload, std::function<std::shared_ptr<T>()> do_when_not_available);
void put(const std::string &id, std::shared_ptr<T> object);
private:
std::map<std::string, std::weak_ptr<T>> m_storage;
};
class Resources : public Singleton<Resources>
{
public:
std::shared_ptr<core::TextureRGBA_UB> getTexture(const fs::path &path, bool force_reload = false);
std::shared_ptr<core::TextureRGBA_32F> getTextureHDR(const fs::path &path, bool force_reload = false);
std::shared_ptr<core::Font> getFont(const fs::path &path, bool force_reload = false);
std::shared_ptr<core::GraphNode> getColladaFile(const fs::path &scene_path, float import_scale = 1.f, bool force_reload = false);
std::shared_ptr<core::GraphNode> getColladaNode(const fs::path &scene_path, const std::string &node_name, float import_scale = 1.f, bool force_reload = false);
std::shared_ptr<core::GraphNode> getColladaMesh(const fs::path &scene_path, const std::string &mesh_name, float import_scale = 1.f, bool force_reload = false);
std::shared_ptr<core::SoundBuffer> getAudioBuffer(const fs::path &path, bool force_reload = false);
private:
ResourceStorage<core::TextureRGBA_UB> m_texture_storage;
ResourceStorage<core::TextureRGBA_32F> m_texture_storage_hdr;
ResourceStorage<core::Font> m_fonts_storage;
ResourceStorage<core::GraphNode> m_collada_scenes_storage;
ResourceStorage<core::SoundBuffer> m_audio_storage;
};
template <typename T>
std::shared_ptr<T> ResourceStorage<T>::get(const std::string &id, bool force_reload, std::function<std::shared_ptr<T>()> do_when_not_available)
{
static std::mutex mtx;
std::unique_lock<std::mutex> lock(mtx);
if (m_storage.count(id) == 0 || m_storage[id].expired())
force_reload = true;
if (force_reload)
{
auto element = do_when_not_available();
m_storage.emplace(id, element);
return element;
}
else
{
return m_storage[id].lock();
Log_Debug << "Loading resource " << id << " from resource storage.";
}
}
template <typename T>
void ResourceStorage<T>::put(const std::string &id, std::shared_ptr<T> object)
{
m_storage.emplace(id, object);
}
}
}
#endif //INCLUDE_RESOURCES_H
......@@ -164,6 +164,8 @@ namespace glare
void quit()
{
//Lock message handler to not receive any messages and accessing an invalid messaging queue when destroying the node graph
messaging::Handler::getInstance().lock();
window->close();
gbuffer->cleanUp();
splash_screen.reset();
......
......@@ -3,7 +3,8 @@
#include <util/files.h>
#include <core/Time.h>
#include <core/res/resources.h>
#include <core/res/res.h>
#include "pugixml/pugixml.hpp"
namespace glare
{
......
......@@ -42,10 +42,15 @@ namespace messaging
void Handler::unregisterReceiver(uint32_t for_id, Receiver &receiver) {
const std::unique_lock<std::mutex> lock(m_receiver_mutex);
if(m_receiver_list.size() != 0 && m_receiver_list.count(for_id) != 0)
if (m_receiver_list.size() != 0 && m_receiver_list.count(for_id) != 0)
m_receiver_list[for_id].erase(receiver.id());
}
void Handler::lock()
{
m_is_locked = true;
}
void Handler::handleMessage(message_t &message) {
//foreach receiver -> handle(msg)
const std::unique_lock<std::mutex> lock(m_receiver_mutex);
......@@ -57,6 +62,8 @@ namespace messaging
}
void Handler::handleAllMessages() {
if (m_is_locked) return;
message_t* message;
{
const std::unique_lock<std::mutex> lock(m_queue_mutex);
......@@ -67,16 +74,15 @@ namespace messaging
while (true) {
handleMessage(*message);
{
const std::unique_lock<std::mutex> lock(m_queue_mutex);
m_message_queue.pop();
if (m_message_queue.empty()) {
m_is_running = false;
break;
}
message = &m_message_queue.front();
const std::unique_lock<std::mutex> lock(m_queue_mutex);
m_message_queue.pop();
if (m_message_queue.empty()) {
m_is_running = false;
break;
}
message = &m_message_queue.front();
}
}
}
\ No newline at end of file
......@@ -88,12 +88,13 @@ namespace messaging
void registerReceiver(uint32_t for_id, Receiver &receiver);
void unregisterReceiver(uint32_t for_id, Receiver &receiver);
void lock();
private:
void handleMessage(message_t &message);
void handleAllMessages();
private:
bool m_is_locked = false;
bool m_is_running = false;
std::map<uint32_t, std::map<uint64_t, Receiver*>> m_receiver_list;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment