VisuTwin Canvas
C++ 3D Engine — Metal Backend
Loading...
Searching...
No Matches
resourceLoader.h
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2025-2026 Arnis Lektauers
3//
4// Created by Arnis Lektauers on 12.10.2025.
5//
6#pragma once
7
8#include <atomic>
9#include <condition_variable>
10#include <deque>
11#include <functional>
12#include <memory>
13#include <mutex>
14#include <optional>
15#include <string>
16#include <thread>
17#include <unordered_map>
18#include <vector>
19
20namespace visutwin::canvas
21{
22 class Engine;
23
24 // ── Loaded data produced by background thread ──────────────────────────
25
35 {
37 std::string url;
38
40 std::vector<uint8_t> bytes;
41
43 struct PixelData
44 {
45 std::vector<uint8_t> pixels;
46 std::vector<float> hdrPixels;
47 int width = 0;
48 int height = 0;
49 int channels = 0;
50 bool isHdr = false;
51 };
52
53 std::optional<PixelData> pixelData;
54
59 std::shared_ptr<void> preparsed;
60
67 std::shared_ptr<void> preparedData;
68 };
69
70 // ── Callback types ─────────────────────────────────────────────────────
71
72 using LoadSuccessCallback = std::function<void(std::unique_ptr<LoadedData>)>;
73 using LoadErrorCallback = std::function<void(const std::string& error)>;
74
75 // ── Resource handler base ──────────────────────────────────────────────
76
85 {
86 public:
87 virtual ~ResourceHandler() = default;
88
95 virtual std::unique_ptr<LoadedData> load(const std::string& url) = 0;
96 };
97
98 // ── Async resource loader ──────────────────────────────────────────────
99
133 {
134 public:
135 explicit ResourceLoader(const std::shared_ptr<Engine>& engine);
137
138 // Non-copyable, non-movable (owns a thread).
141
143 void addHandler(const std::string& type, std::unique_ptr<ResourceHandler> handler);
144
146 void removeHandler(const std::string& type);
147
160 void load(const std::string& url, const std::string& type,
161 LoadSuccessCallback onSuccess, LoadErrorCallback onError = nullptr);
162
173 void processCompletions(int maxCompletions = 0);
174
176 void shutdown();
177
179 bool hasPending() const;
180
181 private:
182 void workerLoop();
183
184 struct Request
185 {
186 std::string url;
187 std::string type;
188 LoadSuccessCallback onSuccess;
189 LoadErrorCallback onError;
190 };
191
192 struct Completion
193 {
194 std::unique_ptr<LoadedData> data;
195 std::string error;
196 LoadSuccessCallback onSuccess;
197 LoadErrorCallback onError;
198 };
199
200 std::weak_ptr<Engine> _engine;
201
202 // Handler registry — written from the main thread only, read from worker.
203 std::unordered_map<std::string, std::unique_ptr<ResourceHandler>> _handlers;
204
205 // Worker thread.
206 std::thread _worker;
207 std::atomic<bool> _running{false};
208
209 // Request queue (main thread → worker).
210 std::mutex _requestMutex;
211 std::condition_variable _requestCV;
212 std::deque<Request> _requests;
213
214 // Completion queue (worker → main thread).
215 std::mutex _completionMutex;
216 std::deque<Completion> _completions;
217
218 std::atomic<int> _pendingCount{0};
219 };
220
221 // ── Built-in resource handlers ─────────────────────────────────────────
222
227 {
228 public:
229 std::unique_ptr<LoadedData> load(const std::string& url) override;
230 };
231
237 {
238 public:
239 std::unique_ptr<LoadedData> load(const std::string& url) override;
240 };
241
244 {
245 public:
246 std::unique_ptr<LoadedData> load(const std::string& url) override;
247 };
248}
std::unique_ptr< LoadedData > load(const std::string &url) override
Central application orchestrator managing scenes, rendering, input, and resource loading.
Definition engine.h:38
std::unique_ptr< LoadedData > load(const std::string &url) override
virtual ~ResourceHandler()=default
virtual std::unique_ptr< LoadedData > load(const std::string &url)=0
ResourceLoader(const std::shared_ptr< Engine > &engine)
void processCompletions(int maxCompletions=0)
void removeHandler(const std::string &type)
void load(const std::string &url, const std::string &type, LoadSuccessCallback onSuccess, LoadErrorCallback onError=nullptr)
void addHandler(const std::string &type, std::unique_ptr< ResourceHandler > handler)
ResourceLoader(const ResourceLoader &)=delete
ResourceLoader & operator=(const ResourceLoader &)=delete
std::unique_ptr< LoadedData > load(const std::string &url) override
std::function< void(std::unique_ptr< LoadedData >)> LoadSuccessCallback
std::function< void(const std::string &error)> LoadErrorCallback
Decoded pixel data — populated only by TextureResourceHandler.
std::vector< uint8_t > pixels
LDR: RGBA8 interleaved.
std::vector< float > hdrPixels
HDR: RGBA32F interleaved.
std::vector< uint8_t > bytes
Raw file bytes (always available for container / font types).
std::optional< PixelData > pixelData
std::shared_ptr< void > preparedData
std::string url
Source file path.
std::shared_ptr< void > preparsed