Nebula
Loading...
Searching...
No Matches
resourceserver.h
Go to the documentation of this file.
1#pragma once
2//------------------------------------------------------------------------------
11//------------------------------------------------------------------------------
12#include <functional>
13#include "core/refcounted.h"
14#include "ids/id.h"
15#include "core/singleton.h"
16#include "resourceid.h"
17#include "resourceloader.h"
19#include "io/urn.h"
20#include "io/assignregistry.h"
21#include "db/dbfactory.h"
22#include "db/database.h"
23
24namespace Resources
25{
27{
30public:
34 virtual ~ResourceServer();
35
37 void Open();
39 void Close();
40
42 void Update(IndexT frameIndex);
43
45 Resources::ResourceId CreateResource(const ResourceName& res, std::function<void(const Resources::ResourceId)> success = nullptr, std::function<void(const Resources::ResourceId)> failed = nullptr, bool immediate = false, bool stream = true);
47 Resources::ResourceId CreateResource(const ResourceName& res, const Util::StringAtom& tag, std::function<void(const Resources::ResourceId)> success = nullptr, std::function<void(const Resources::ResourceId)> failed = nullptr, bool immediate = false, bool stream = true);
49 template<class METADATA> Resources::ResourceId CreateResource(const ResourceName& res, const METADATA& metaData, std::function<void(const Resources::ResourceId)> success = nullptr, std::function<void(const Resources::ResourceId)> failed = nullptr, bool immediate = false, bool stream = true);
51 template<class METADATA> Resources::ResourceId CreateResource(const ResourceName& res, const METADATA& metaData, const Util::StringAtom& tag, std::function<void(const Resources::ResourceId)> success = nullptr, std::function<void(const Resources::ResourceId)> failed = nullptr, bool immediate = false, bool stream = true);
52
54 Resources::ResourceId CreateResource(const IO::URN& res, std::function<void(const Resources::ResourceId)> success = nullptr, std::function<void(const Resources::ResourceId)> failed = nullptr, bool immediate = false, bool stream = true);
56 Resources::ResourceId CreateResource(const IO::URN& res, const Util::StringAtom& tag, std::function<void(const Resources::ResourceId)> success = nullptr, std::function<void(const Resources::ResourceId)> failed = nullptr, bool immediate = false, bool stream = true);
58 template<class METADATA> Resources::ResourceId CreateResource(const IO::URN& res, const METADATA& metaData, std::function<void(const Resources::ResourceId)> success = nullptr, std::function<void(const Resources::ResourceId)> failed = nullptr, bool immediate = false, bool stream = true);
60 template<class METADATA> Resources::ResourceId CreateResource(const IO::URN& res, const METADATA& metaData, const Util::StringAtom& tag, std::function<void(const Resources::ResourceId)> success = nullptr, std::function<void(const Resources::ResourceId)> failed = nullptr, bool immediate = false, bool stream = true);
61
63 void DiscardResource(const Resources::ResourceId res);
65 void DiscardResources(const Util::StringAtom& tag);
69 void ReloadResource(const ResourceName& res, std::function<void(const Resources::ResourceId)> success = nullptr, std::function<void(const Resources::ResourceId)> failed = nullptr);
71 void SetMinLod(const ResourceId& id, float lod, bool immediate);
73 void CreateResourceListener(const ResourceId& id, std::function<void(const Resources::ResourceId)> success, std::function<void(const Resources::ResourceId)> failed = nullptr);
74
76 Core::Rtti* GetType(const Resources::ResourceId id);
77
79 const Resources::ResourceName GetName(const Resources::ResourceId id) const;
81 const Util::StringAtom GetTag(const Resources::ResourceId id) const;
83 const Resource::State GetState(const Resources::ResourceId id) const;
85 const SizeT GetUsage(const Resources::ResourceId id) const;
87 bool HasResource(const Resources::ResourceId id) const;
89 const Resources::ResourceId GetId(const Resources::ResourceName& name) const;
90
92 void RegisterStreamLoader(const Util::StringAtom& ext, const Core::Rtti& loaderClass);
94 void DeregisterStreamLoader(const Util::StringAtom& ext, const Core::Rtti& loaderClass);
96 template <class POOL_TYPE> POOL_TYPE* GetStreamLoader() const;
98 bool HasStreamLoader(const Util::StringAtom& ext) const;
99
101 void WaitForLoaderThread();
102
105private:
106 friend class ResourceLoader;
107
108 bool open;
113
114 static int32_t UniquePoolCounter;
115};
116
117//------------------------------------------------------------------------------
122inline Resources::ResourceId
124 const ResourceName& id
125 , std::function<void(const Resources::ResourceId)> success
126 , std::function<void(const Resources::ResourceId)> failed
127 , bool immediate
128 , bool stream
129)
130{
131 return this->CreateResource(id, "", success, failed, immediate, stream);
132}
133
134//------------------------------------------------------------------------------
139inline Resources::ResourceId
141 const ResourceName& res
142 , const Util::StringAtom& tag
143 , std::function<void(const Resources::ResourceId)> success
144 , std::function<void(const Resources::ResourceId)> failed
145 , bool immediate
146 , bool stream
147)
148{
149 // get resource loader by extension
151 IndexT i = this->extensionMap.FindIndex(ext);
152 n_assert_fmt(i != InvalidIndex, "No resource loader is associated with file extension '%s'", ext.AsCharPtr());
153 const Ptr<ResourceLoader>& loader = this->loaders[this->extensionMap.ValueAtIndex(i)].downcast<ResourceLoader>();
154
155 // create container and cast to actual resource type
156 Resources::ResourceId id = loader->CreateResource(IO::URI(res.AsString()), nullptr, 0, tag, success, failed, immediate, stream);
157 return id;
158}
159
160//------------------------------------------------------------------------------
163inline Resources::ResourceId
165 const IO::URN& res
166 , std::function<void(const Resources::ResourceId)> success
167 , std::function<void(const Resources::ResourceId)> failed
168 , bool immediate
169 , bool stream
170)
171{
172 return CreateResource(res, "", success, failed, immediate, stream);
173}
174
175//------------------------------------------------------------------------------
178inline Resources::ResourceId
180 const IO::URN& res
181 , const Util::StringAtom& tag
182 , std::function<void(const Resources::ResourceId)> success
183 , std::function<void(const Resources::ResourceId)> failed
184 , bool immediate
185 , bool stream
186)
187{
188 // get resource loader by extension
189 IndexT i = this->extensionMap.FindIndex(res.GetNamespace());
190 n_assert_fmt(i != InvalidIndex, "No resource loader is associated with URN namespace '%s'", res.GetNamespace().AsCharPtr());
191 const Ptr<ResourceLoader>& loader = this->loaders[this->extensionMap.ValueAtIndex(i)].downcast<ResourceLoader>();
192
193 // create container and cast to actual resource type
194 Resources::ResourceId id = loader->CreateResource(res, nullptr, 0, tag, success, failed, immediate, stream);
195 return id;
196}
197
198//------------------------------------------------------------------------------
201template<class METADATA>
202inline Resources::ResourceId
204 const ResourceName& res
205 , const METADATA& metaData
206 , std::function<void(const Resources::ResourceId)> success
207 , std::function<void(const Resources::ResourceId)> failed
208 , bool immediate
209 , bool stream
210)
211{
212 return this->CreateResource(res, metaData, "", success, failed, immediate, stream);
213}
214
215//------------------------------------------------------------------------------
218template<class METADATA>
219inline Resources::ResourceId
221 const ResourceName& res
222 , const METADATA& metaData
223 , const Util::StringAtom& tag
224 , std::function<void(const Resources::ResourceId)> success
225 , std::function<void(const Resources::ResourceId)> failed
226 , bool immediate
227 , bool stream
228)
229{
230 // get resource loader by extension
232 IndexT i = this->extensionMap.FindIndex(ext);
233 n_assert_fmt(i != InvalidIndex, "No resource loader is associated with file extension '%s'", ext.AsCharPtr());
234 const Ptr<ResourceLoader>& loader = this->loaders[this->extensionMap.ValueAtIndex(i)].downcast<ResourceLoader>();
235
236 // create container and cast to actual resource type
237 Resources::ResourceId id = loader->CreateResource(IO::URI(res.Value()), &metaData, sizeof(METADATA), tag, success, failed, immediate, stream);
238 return id;
239}
240
241//------------------------------------------------------------------------------
244template<class METADATA>
245inline Resources::ResourceId ResourceServer::CreateResource(
246 const IO::URN& res
247 , const METADATA& metaData
248 , std::function<void(const Resources::ResourceId)> success
249 , std::function<void(const Resources::ResourceId)> failed
250 , bool immediate
251 , bool stream
252)
253{
254 return CreateResource(res, metaData, "", success, failed, immediate, stream);
255}
256
257//------------------------------------------------------------------------------
260template<class METADATA>
261inline Resources::ResourceId ResourceServer::CreateResource(
262 const IO::URN& res
263 , const METADATA& metaData
264 , const Util::StringAtom& tag
265 , std::function<void(const Resources::ResourceId)> success
266 , std::function<void(const Resources::ResourceId)> failed
267 , bool immediate
268 , bool stream
269)
270{
271 // get resource loader by extension
272 IndexT i = this->extensionMap.FindIndex(res.GetNamespace());
273 n_assert_fmt(i != InvalidIndex, "No resource loader is associated with URN namespace '%s'", res.GetNamespace().AsCharPtr());
274 const Ptr<ResourceLoader>& loader = this->loaders[this->extensionMap.ValueAtIndex(i)].downcast<ResourceLoader>();
275
276 // create container and cast to actual resource type
277 Resources::ResourceId id = loader->CreateResource(res, &metaData, sizeof(METADATA), tag, success, failed, immediate, stream);
278 return id;
279}
280
281//------------------------------------------------------------------------------
284inline void
285ResourceServer::ReloadResource(const ResourceName& res, std::function<void(const Resources::ResourceId)> success, std::function<void(const Resources::ResourceId)> failed)
286{
287 // get resource loader by extension
289 IndexT i = this->extensionMap.FindIndex(ext);
290 n_assert_fmt(i != InvalidIndex, "No resource loader is associated with file extension '%s'", ext.AsCharPtr());
291 const Ptr<ResourceLoader>& loader = this->loaders[this->extensionMap.ValueAtIndex(i)].downcast<ResourceLoader>();
292
293 // create container and cast to actual resource type
294 loader->ReloadResource(res, success, failed);
295}
296
297
298//------------------------------------------------------------------------------
301inline bool
303{
304 IndexT i = this->extensionMap.FindIndex(ext);
305 return i != InvalidIndex;
306}
307
308//------------------------------------------------------------------------------
311inline void
312ResourceServer::SetMinLod(const ResourceId& id, float lod, bool immediate)
313{
314 // get id of loader
315 const Ids::Id8 loaderid = id.loaderIndex;
316
317 // get resource loader by extension
318 n_assert(this->loaders.Size() > loaderid);
319 const Ptr<ResourceLoader>& loader = this->loaders[loaderid].downcast<ResourceLoader>();
320
321 // update LOD
322 loader->SetMinLod(id, lod, immediate);
323}
324
325//------------------------------------------------------------------------------
328inline void
330 const ResourceId& id,
331 std::function<void(const Resources::ResourceId)> success,
332 std::function<void(const Resources::ResourceId)> failed
333)
334{
335 // get id of loader
336 const Ids::Id8 loaderid = id.loaderIndex;
337
338 // get resource loader by extension
339 n_assert(this->loaders.Size() > loaderid);
340 const Ptr<ResourceLoader>& loader = this->loaders[loaderid].downcast<ResourceLoader>();
341
342 loader->CreateListener(id, success, failed);
343}
344
345//------------------------------------------------------------------------------
349inline void
350ResourceServer::DiscardResource(const Resources::ResourceId id)
351{
352 // get id of loader
353 const Ids::Id8 loaderid = id.loaderIndex;
354
355 // get resource loader by extension
356 n_assert(this->loaders.Size() > loaderid);
357 const Ptr<ResourceLoader>& loader = this->loaders[loaderid].downcast<ResourceLoader>();
358
359 // discard container
360 loader->DiscardResource(id);
361}
362
363//------------------------------------------------------------------------------
366inline const Resources::ResourceName
367ResourceServer::GetName(const Resources::ResourceId id) const
368{
369 // get resource loader by extension
370 n_assert(this->loaders.Size() > id.loaderIndex);
371 const Ptr<ResourceLoader>& loader = this->loaders[id.loaderIndex];
372 return loader->GetName(id.resourceId);
373}
374
375//------------------------------------------------------------------------------
378inline const Util::StringAtom
379ResourceServer::GetTag(const Resources::ResourceId id) const
380{
381 // get resource loader by extension
382 n_assert(this->loaders.Size() > id.loaderIndex);
383 const Ptr<ResourceLoader>& loader = this->loaders[id.loaderIndex];
384 return loader->GetTag(id.resourceId);
385}
386
387//------------------------------------------------------------------------------
391ResourceServer::GetState(const Resources::ResourceId id) const
392{
393 // get resource loader by extension
394 n_assert(this->loaders.Size() > id.loaderIndex);
395 const Ptr<ResourceLoader>& loader = this->loaders[id.loaderIndex];
396 return loader->GetState(id.resourceId);
397}
398
399//------------------------------------------------------------------------------
402inline const SizeT
403ResourceServer::GetUsage(const Resources::ResourceId id) const
404{
405 // get resource loader by extension
406 n_assert(this->loaders.Size() > id.loaderIndex);
407 const Ptr<ResourceLoader>& loader = this->loaders[id.loaderIndex];
408 return loader->GetUsage(id.resourceId);
409}
410
411//------------------------------------------------------------------------------
414inline bool
415ResourceServer::HasResource(const Resources::ResourceId id) const
416{
417 if (this->loaders.Size() <= id.loaderIndex) return false;
418 {
419 const Ptr<ResourceLoader>& loader = this->loaders[id.loaderIndex];
420 if (loader->HasResource(id)) return true;
421 return false;
422 }
423}
424
425//------------------------------------------------------------------------------
428inline const Resources::ResourceId
430{
431 IndexT i;
432 for (i = 0; i < this->loaders.Size(); i++)
433 {
434 Resources::ResourceId id = this->loaders[i]->GetId(name);
435 if (id != Resources::ResourceId::Invalid()) return id;
436 }
437 return Resources::ResourceId::Invalid();
438}
439
440//------------------------------------------------------------------------------
443template <class POOL_TYPE>
444inline POOL_TYPE*
446{
447 static_assert(std::is_base_of<ResourceLoader, POOL_TYPE>::value, "Type requested is not a stream pool");
448 IndexT i = this->typeMap.FindIndex(&POOL_TYPE::RTTI);
449 if (i != InvalidIndex)
450 {
451 return static_cast<POOL_TYPE*>(this->loaders[this->typeMap.ValueAtIndex(i)].get());
452 }
453
454 n_error("No loader registered for this type");
455 return nullptr;
456}
457
458//------------------------------------------------------------------------------
462inline Resources::ResourceId
464 const ResourceName& res
465 , const Util::StringAtom& tag
466 , std::function<void(const Resources::ResourceId)> success = nullptr
467 , std::function<void(const Resources::ResourceId)> failed = nullptr
468 , bool immediate = false
469 , bool stream = true
470)
471{
472 return ResourceServer::Instance()->CreateResource(res, tag, success, failed, immediate, stream);
473}
474
475//------------------------------------------------------------------------------
479template <class METADATA>
480inline Resources::ResourceId
482 const ResourceName& res
483 , const METADATA& metaData
484 , const Util::StringAtom& tag
485 , std::function<void(const Resources::ResourceId)> success = nullptr
486 , std::function<void(const Resources::ResourceId)> failed = nullptr
487 , bool immediate = false
488 , bool stream = true
489)
490{
491 return ResourceServer::Instance()->CreateResource(res, metaData, tag, success, failed, immediate, stream);
492}
493
494//------------------------------------------------------------------------------
498inline Resources::ResourceId
500 const IO::URN& res
501 , const Util::StringAtom& tag
502 , std::function<void(const Resources::ResourceId)> success = nullptr
503 , std::function<void(const Resources::ResourceId)> failed = nullptr
504 , bool immediate = false
505 , bool stream = true
506)
507{
508 return ResourceServer::Instance()->CreateResource(res, tag, success, failed, immediate, stream);
509}
510
511//------------------------------------------------------------------------------
515template <class METADATA>
516inline Resources::ResourceId
518 const IO::URN& res
519 , const METADATA& metaData
520 , const Util::StringAtom& tag
521 , std::function<void(const Resources::ResourceId)> success = nullptr
522 , std::function<void(const Resources::ResourceId)> failed = nullptr
523 , bool immediate = false
524 , bool stream = true
525)
526{
527 return ResourceServer::Instance()->CreateResource(res, metaData, tag, success, failed, immediate, stream);
528}
529
530//------------------------------------------------------------------------------
534inline void
536 const ResourceId& id
537 , std::function<void(const Resources::ResourceId)> success
538 , std::function<void(const Resources::ResourceId)> failed = nullptr
539)
540{
541 return ResourceServer::Instance()->CreateResourceListener(id, success, failed);
542}
543
544//------------------------------------------------------------------------------
547inline void
548SetMinLod(const ResourceId& id, float lod, bool immediate)
549{
550 return ResourceServer::Instance()->SetMinLod(id, lod, immediate);
551}
552
553//------------------------------------------------------------------------------
556inline void
557DiscardResource(const Resources::ResourceId id)
558{
559 ResourceServer::Instance()->DiscardResource(id);
560}
561
562//------------------------------------------------------------------------------
565inline void
567{
568 return ResourceServer::Instance()->ReloadResource(res);
569}
570
571//------------------------------------------------------------------------------
574inline void
576{
577 ResourceServer::Instance()->WaitForLoaderThread();
578}
579
580//------------------------------------------------------------------------------
583template <class POOL_TYPE>
584inline POOL_TYPE*
586{
587 static_assert(std::is_base_of<ResourceLoader, POOL_TYPE>::value, "Template argument is not a ResourceCache type!");
588 return ResourceServer::Instance()->GetStreamLoader<POOL_TYPE>();
589}
590
591} // namespace Resources
The common base class of Nebula.
Definition refcounted.h:38
Nebula's runtime type information for one class.
Definition rtti.h:27
An URI object can split a Uniform Resource Identifier string into its components or build a string fr...
Definition uri.h:67
A URN (Uniform Resource Name) is a URI (Uniform Resource Identifier) that uses the "urn" scheme.
Definition urn.h:24
const Util::String & GetNamespace() const
get Namespace component
Definition urn.h:269
Nebula's smart pointer class which manages the life time of RefCounted objects.
Definition ptr.h:38
State
Definition resource.h:26
void SetMinLod(const ResourceId &id, float lod, bool immediate)
stream in a new LOD
Definition resourceserver.h:312
__DeclareClass(ResourceServer)
void Close()
close manager
Definition resourceserver.cc:57
__DeclareInterfaceSingleton(ResourceServer)
bool HasStreamLoader(const Util::StringAtom &ext) const
query if a stream loader is registered for a given extension
Definition resourceserver.h:302
void CreateResourceListener(const ResourceId &id, std::function< void(const Resources::ResourceId)> success, std::function< void(const Resources::ResourceId)> failed=nullptr)
Create single-fire listener for resource. When resource is loaded, the callbacks will be invoked and ...
Definition resourceserver.h:329
void Open()
open manager
Definition resourceserver.cc:45
Resources::ResourceId CreateResource(const ResourceName &res, std::function< void(const Resources::ResourceId)> success=nullptr, std::function< void(const Resources::ResourceId)> failed=nullptr, bool immediate=false, bool stream=true)
create a new resource (stream-managed), which will be loaded at some later point, if not already load...
Definition resourceserver.h:123
ResourceServer()
constructor
Definition resourceserver.cc:26
Util::Dictionary< Util::StringAtom, IndexT > extensionMap
Definition resourceserver.h:109
Util::Dictionary< const Core::Rtti *, IndexT > typeMap
Definition resourceserver.h:111
const Resources::ResourceId GetId(const Resources::ResourceName &name) const
get id from name
Definition resourceserver.h:429
friend class ResourceLoader
Definition resourceserver.h:106
void DiscardResources(const Util::StringAtom &tag)
discard all resources by tag (stream-managed)
Definition resourceserver.cc:184
bool HasResource(const Resources::ResourceId id) const
check if resource id is valid
Definition resourceserver.h:415
void RegisterStreamLoader(const Util::StringAtom &ext, const Core::Rtti &loaderClass)
register a stream pool, which takes an extension and the RTTI of the resource type to create
Definition resourceserver.cc:101
void DiscardResource(const Resources::ResourceId res)
discard resource (stream-managed)
Definition resourceserver.h:350
void DeregisterStreamLoader(const Util::StringAtom &ext, const Core::Rtti &loaderClass)
deregisters a stream pool
Definition resourceserver.cc:118
virtual ~ResourceServer()
destructor
Definition resourceserver.cc:35
Core::Rtti * GetType(const Resources::ResourceId id)
get type of resource pool this resource was allocated with
Definition resourceserver.cc:218
Util::Dictionary< Util::StringAtom, IndexT > loaderMap
Definition resourceserver.h:110
void ReloadResource(const ResourceName &res, std::function< void(const Resources::ResourceId)> success=nullptr, std::function< void(const Resources::ResourceId)> failed=nullptr)
reload resource
Definition resourceserver.h:285
const Resources::ResourceName GetName(const Resources::ResourceId id) const
get resource name
Definition resourceserver.h:367
Util::Array< Ptr< ResourceLoader > > loaders
Definition resourceserver.h:112
const Resource::State GetState(const Resources::ResourceId id) const
get resource state
Definition resourceserver.h:391
static int32_t UniquePoolCounter
Definition resourceserver.h:114
const SizeT GetUsage(const Resources::ResourceId id) const
get usage
Definition resourceserver.h:403
bool HasPendingResources()
returns true if there are pending resources in-flight
Definition resourceserver.cc:198
const Util::StringAtom GetTag(const Resources::ResourceId id) const
get tag resource was first registered with
Definition resourceserver.h:379
void LoadDefaultResources()
goes through all pools and sets up their default resources
Definition resourceserver.cc:155
POOL_TYPE * GetStreamLoader() const
get stream pool for later use
Definition resourceserver.h:445
bool open
Definition resourceserver.h:108
void WaitForLoaderThread()
Wait for all loader threads.
Definition resourceserver.cc:233
Nebula's dynamic array class.
Definition array.h:61
A collection of key/value pairs with quick value retrieval by key at roughly O(log n).
Definition dictionary.h:35
A StringAtom.
Definition stringatom.h:22
const char * Value() const
get contained string as char ptr (fast)
Definition stringatom.h:362
String AsString() const
get containted string as string object (SLOW!!!)
Definition stringatom.h:372
Nebula's universal string class.
Definition string.h:50
const char * AsCharPtr() const
return contents as character pointer
Definition string.h:577
String GetFileExtension() const
get filename extension without dot
Definition string.cc:1003
void __cdecl n_error(const char *msg,...)
This function is called when a serious situation is encountered which requires abortion of the applic...
Definition debug.cc:138
#define n_assert_fmt(exp, msg,...)
Definition debug.h:53
#define n_assert(exp)
Definition debug.h:50
uint8_t Id8
Definition id.h:141
A resource is a container for some type of file which is loaded.
Definition resource.cc:9
Resources::ResourceId CreateResource(const ResourceName &res, const Util::StringAtom &tag, std::function< void(const Resources::ResourceId)> success=nullptr, std::function< void(const Resources::ResourceId)> failed=nullptr, bool immediate=false, bool stream=true)
TODO: Make templated with success and failed and use a custom allocator to capture the closure.
Definition resourceserver.h:463
POOL_TYPE * GetStreamLoader()
Definition resourceserver.h:585
void DiscardResource(const Resources::ResourceId id)
Definition resourceserver.h:557
@ Update
Definition resourceloader.h:54
void WaitForLoaderThread()
Definition resourceserver.h:575
void ReloadResource(const ResourceName &res)
Definition resourceserver.h:566
Util::StringAtom ResourceName
Definition resourceid.h:33
void SetMinLod(const ResourceId &id, float lod, bool immediate)
Definition resourceserver.h:548
void CreateResourceListener(const ResourceId &id, std::function< void(const Resources::ResourceId)> success, std::function< void(const Resources::ResourceId)> failed=nullptr)
TODO: Make templated with success and failed and use a custom allocator to capture the closure.
Definition resourceserver.h:535
id
Definition resourceid.h:37
static const int InvalidIndex
Definition types.h:47
int SizeT
Definition types.h:42
int IndexT
Definition types.h:41