Brenta Engine 1.2
Loading...
Searching...
No Matches
asset.hpp
1// SPDX-License-Identifier: MIT
2// Author: Giovanni Santini
3// Mail: giovanni.santini@proton.me
4// Github: @San7o
5
6#pragma once
7
8#include <brenta/fswatcher.hpp>
9
10#include <tenno/memory.hpp>
11#include <tenno/thread.hpp>
12
13#include <unordered_map>
14
15namespace brenta
16{
17
18class Gui;
19class Texture;
20class Model;
21class Material;
22class Scene;
23class Font;
24class Sound;
25class SoundAsset;
26class Shader;
27
28//
29// The central Asset Manager
30// -------------------------
31//
32// The asset manager is an interface to create and hold certain
33// onjects. The api is the same for all types of objects.
34//
35// All objects have an identifier which you provide when you
36// create a new object with the `new_asset<T>(...)` function. You
37// need to pass the identifier (a string) and a builder for `T`.
38//
39// After creation, you can get the object with `get<T>(id)` and reload
40// it with `reload<T>(id)`. If you enable hot reloading, this can be
41// done automatically when a change is detected in the source files in
42// the filesystem.
43//
44// The asset manager holds either weak references, or it owns the
45// data. Weak references are kept in memory as long as their owner
46// exists, the asset manager does not partecipate in its ownership but
47// it provides a way to create more references to that object. This
48// can be useful for loading levels, as all resources are deallocated
49// automatically when you change scene.
50//
52{
53public:
54
55 using AssetId = std::string;
56
57 template<typename T>
58 struct Asset;
59 template<typename T>
60 struct AssetOwned;
61 struct HotReloadItem;
62
63 friend class Gui;
64
65 enum class AssetType
66 {
67 Model,
68 Texture,
70 Scene,
71 Shader,
72 Font,
73 Sound,
74 };
75
76 //
77 // AssetManager API
78 // ----------------
79 //
80 // You can use the following functions with their specialization,
81 // for example:
82 //
83 // tenno::shared_ptr<Model> new_asset<Model>("my_model", builder);
84 // reload<Model>("my_model");
85 //
86 template<typename T>
87 static tenno::shared_ptr<T> new_asset(const AssetId& id,
88 typename T::Builder& builder);
89 template<typename T>
90 static tenno::shared_ptr<T> get(const AssetId& id);
91 template<typename T>
92 static bool reload(const AssetId& id);
93 // Wipe out everything
94 static void clear();
95
96 //
97 // Hotreload API
98 //
99
100 static void hotreload_activate();
101 static void hotreload_deactivate();
102 // Call this function to reload the assets that needs update
103 static void hotreload_update();
104
105private:
106
107 static std::unordered_map<AssetId, Asset<Model>> models;
108 static std::unordered_map<AssetId, Asset<Texture>> textures;
109 static std::unordered_map<AssetId, Asset<Material>> materials;
110 static std::unordered_map<AssetId, Asset<Shader>> shaders;
111 static std::unordered_map<AssetId, Asset<Font>> fonts;
112 static std::unordered_map<AssetId, AssetOwned<Scene>> scenes;
113 static std::unordered_map<AssetId, AssetOwned<SoundAsset>> sound_assets;
114
115
116 // Private constructor for singleton
117 AssetManager() = default;
118
119 // Hotreloading
120
121 static bool hotreload_active;
122 static FilesystemWatcher fswatcher;
123 // This thread uses fswathcer to watch for events, and writes them
124 // to reload_pending. You need to call hotrealod_update to consume
125 // the pending assets. The thread is created with
126 // hotreload_activate and destroyed with hotreload_deactivate. So we
127 // don't have any performance penalty if we don't want to use this.
128 static tenno::jthread hotreload_thread;
129 static tenno::mutex hotreload_pending_mutex;
130 static tenno::vector<HotReloadItem> hotreload_pending;
131 static std::unordered_map<std::filesystem::path,
132 HotReloadItem> hotreload_entries;
133
134};
135
136template<typename T>
138{
139 T::Builder builder;
140 tenno::weak_ptr<T> ptr;
141};
142
143template<typename T>
145{
146 T::Builder builder;
147 tenno::shared_ptr<T> ptr;
148};
149
151{
152 AssetType type;
153 AssetId id;
154};
155
156} // namespace brenta