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/path.h"
21#include "io/assignregistry.h"
22#include "db/dbfactory.h"
23#include "db/database.h"
24
25namespace Resources
26{
28{
31public:
35 virtual ~ResourceServer();
36
38 void Open();
40 void Close();
41
43 void Update(IndexT frameIndex);
44
46 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);
48 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);
50 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);
52 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);
53
55 Resources::ResourceId CreateResource(const IO::Path& res, std::function<void(const Resources::ResourceId)> success = nullptr, std::function<void(const Resources::ResourceId)> failed = nullptr, bool immediate = false, bool stream = true);
57 Resources::ResourceId CreateResource(const IO::Path& 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);
59 template<class METADATA> Resources::ResourceId CreateResource(const IO::Path& 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);
61 template<class METADATA> Resources::ResourceId CreateResource(const IO::Path& 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);
62
64 void DiscardResource(const Resources::ResourceId res);
66 void DiscardResources(const Util::StringAtom& tag);
70 void ReloadResource(const ResourceName& res, std::function<void(const Resources::ResourceId)> success = nullptr, std::function<void(const Resources::ResourceId)> failed = nullptr);
72 void SetMinLod(const ResourceId& id, float lod, bool immediate);
74 void CreateResourceListener(const ResourceId& id, std::function<void(const Resources::ResourceId)> success, std::function<void(const Resources::ResourceId)> failed = nullptr);
75
77 Core::Rtti* GetType(const Resources::ResourceId id);
78
80 const Resources::ResourceName GetName(const Resources::ResourceId id) const;
82 const Util::StringAtom GetTag(const Resources::ResourceId id) const;
84 const Resource::State GetState(const Resources::ResourceId id) const;
86 const SizeT GetUsage(const Resources::ResourceId id) const;
88 bool HasResource(const Resources::ResourceId id) const;
90 const Resources::ResourceId GetId(const Resources::ResourceName& name) const;
91
93 void RegisterStreamLoader(const Util::StringAtom& ext, const Ptr<ResourceLoader>& loader);
95 void DeregisterStreamLoader(const Util::StringAtom& ext, const Ptr<ResourceLoader>& loader);
97 template <class POOL_TYPE> POOL_TYPE* GetStreamLoader() const;
99 bool HasStreamLoader(const Util::StringAtom& ext) const;
101 bool HasStreamLoader(const IO::URN& urn) const;
103 bool HasStreamLoader(const IO::Path& path) const;
104
106 void WaitForLoaderThread();
107
110private:
111 friend class ResourceLoader;
112
113 bool open;
118};
119
120//------------------------------------------------------------------------------
125inline Resources::ResourceId
127 const ResourceName& id
128 , std::function<void(const Resources::ResourceId)> success
129 , std::function<void(const Resources::ResourceId)> failed
130 , bool immediate
131 , bool stream
132)
133{
134 return this->CreateResource(id, "", success, failed, immediate, stream);
135}
136
137//------------------------------------------------------------------------------
142inline Resources::ResourceId
144 const ResourceName& res
145 , const Util::StringAtom& tag
146 , std::function<void(const Resources::ResourceId)> success
147 , std::function<void(const Resources::ResourceId)> failed
148 , bool immediate
149 , bool stream
150)
151{
152 // get resource loader by extension
154 IndexT i = this->extensionMap.FindIndex(ext);
155 n_warn_fmt(i != InvalidIndex, "No resource loader is associated with file extension '%s'", ext.AsCharPtr());
156 if (i == InvalidIndex)
157 return Resources::InvalidResourceId;
158 const Ptr<ResourceLoader>& loader = this->loaders[this->extensionMap.ValueAtIndex(i)].downcast<ResourceLoader>();
159
160 // create container and cast to actual resource type
161 Resources::ResourceId id = loader->CreateResource(IO::URI(res.AsString()), nullptr, 0, tag, success, failed, immediate, stream);
162 return id;
163}
164
165//------------------------------------------------------------------------------
168inline Resources::ResourceId
170 const IO::Path& res,
171 std::function<void(const Resources::ResourceId)> success,
172 std::function<void(const Resources::ResourceId)> failed,
173 bool immediate,
174 bool stream
175)
176{
177 return CreateResource(res, "", success, failed, immediate, stream);
178}
179
180//------------------------------------------------------------------------------
183inline Resources::ResourceId
185 const IO::Path& res,
186 const Util::StringAtom& tag,
187 std::function<void(const Resources::ResourceId)> success,
188 std::function<void(const Resources::ResourceId)> failed,
189 bool immediate,
190 bool stream
191)
192{
193 // get resource loader by extension
194 IndexT i = this->extensionMap.FindIndex(res.GetType());
195 n_assert_fmt(i != InvalidIndex, "No resource loader is associated with URN namespace '%s'", res.GetType().AsCharPtr());
196 const Ptr<ResourceLoader>& loader = this->loaders[this->extensionMap.ValueAtIndex(i)].downcast<ResourceLoader>();
197
198 // create container and cast to actual resource type
199 Resources::ResourceId id = loader->CreateResource(res, nullptr, 0, tag, success, failed, immediate, stream);
200 return id;
201}
202
203//------------------------------------------------------------------------------
206template<class METADATA>
207inline Resources::ResourceId
209 const ResourceName& res
210 , const METADATA& metaData
211 , std::function<void(const Resources::ResourceId)> success
212 , std::function<void(const Resources::ResourceId)> failed
213 , bool immediate
214 , bool stream
215)
216{
217 return this->CreateResource(res, metaData, "", success, failed, immediate, stream);
218}
219
220//------------------------------------------------------------------------------
223template<class METADATA>
224inline Resources::ResourceId
226 const ResourceName& res
227 , const METADATA& metaData
228 , const Util::StringAtom& tag
229 , std::function<void(const Resources::ResourceId)> success
230 , std::function<void(const Resources::ResourceId)> failed
231 , bool immediate
232 , bool stream
233)
234{
235 // get resource loader by extension
237 IndexT i = this->extensionMap.FindIndex(ext);
238 n_warn_fmt(i != InvalidIndex, "No resource loader is associated with file extension '%s'", ext.AsCharPtr());
239 if (i == InvalidIndex)
240 return Resources::InvalidResourceId;
241 const Ptr<ResourceLoader>& loader = this->loaders[this->extensionMap.ValueAtIndex(i)].downcast<ResourceLoader>();
242
243 // create container and cast to actual resource type
244 Resources::ResourceId id = loader->CreateResource(IO::URI(res.Value()), &metaData, sizeof(METADATA), tag, success, failed, immediate, stream);
245 return id;
246}
247
248//------------------------------------------------------------------------------
251inline void
252ResourceServer::ReloadResource(const ResourceName& res, std::function<void(const Resources::ResourceId)> success, std::function<void(const Resources::ResourceId)> failed)
253{
254 // get resource loader by extension
256 IndexT i = this->extensionMap.FindIndex(ext);
257 n_warn_fmt(i != InvalidIndex, "No resource loader is associated with file extension '%s'", ext.AsCharPtr());
258 if (i == InvalidIndex)
259 return;
260 const Ptr<ResourceLoader>& loader = this->loaders[this->extensionMap.ValueAtIndex(i)].downcast<ResourceLoader>();
261
262 // create container and cast to actual resource type
263 loader->ReloadResource(res, success, failed);
264}
265
266//------------------------------------------------------------------------------
269inline bool
271{
272 IndexT i = this->extensionMap.FindIndex(ext);
273 return i != InvalidIndex;
274}
275
276//------------------------------------------------------------------------------
279inline bool
281{
282 IndexT i = this->extensionMap.FindIndex(urn.GetNamespace());
283 return i != InvalidIndex;
284}
285
286//------------------------------------------------------------------------------
289inline bool
291{
292 IndexT i = this->extensionMap.FindIndex(path.GetType());
293 return i != InvalidIndex;
294}
295
296//------------------------------------------------------------------------------
299inline void
300ResourceServer::SetMinLod(const ResourceId& id, float lod, bool immediate)
301{
302 // get id of loader
303 const Ids::Id8 loaderid = id.loaderIndex;
304
305 // get resource loader by extension
306 n_assert(this->loaders.Size() > loaderid);
307 const Ptr<ResourceLoader>& loader = this->loaders[loaderid].downcast<ResourceLoader>();
308
309 // update LOD
310 loader->SetMinLod(id, lod, immediate);
311}
312
313//------------------------------------------------------------------------------
316inline void
318 const ResourceId& id,
319 std::function<void(const Resources::ResourceId)> success,
320 std::function<void(const Resources::ResourceId)> failed
321)
322{
323 // get id of loader
324 const Ids::Id8 loaderid = id.loaderIndex;
325
326 // get resource loader by extension
327 n_assert(this->loaders.Size() > loaderid);
328 const Ptr<ResourceLoader>& loader = this->loaders[loaderid].downcast<ResourceLoader>();
329
330 loader->CreateListener(id, success, failed);
331}
332
333//------------------------------------------------------------------------------
337inline void
338ResourceServer::DiscardResource(const Resources::ResourceId id)
339{
340 // get id of loader
341 const Ids::Id8 loaderid = id.loaderIndex;
342
343 // get resource loader by extension
344 n_assert(this->loaders.Size() > loaderid);
345 const Ptr<ResourceLoader>& loader = this->loaders[loaderid].downcast<ResourceLoader>();
346
347 // discard container
348 loader->DiscardResource(id);
349}
350
351//------------------------------------------------------------------------------
354inline const Resources::ResourceName
355ResourceServer::GetName(const Resources::ResourceId id) const
356{
357 // get resource loader by extension
358 n_assert(this->loaders.Size() > id.loaderIndex);
359 const Ptr<ResourceLoader>& loader = this->loaders[id.loaderIndex];
360 return loader->GetName(id);
361}
362
363//------------------------------------------------------------------------------
366inline const Util::StringAtom
367ResourceServer::GetTag(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->GetTag(id);
373}
374
375//------------------------------------------------------------------------------
379ResourceServer::GetState(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->GetState(id);
385}
386
387//------------------------------------------------------------------------------
390inline const SizeT
391ResourceServer::GetUsage(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->GetUsage(id);
397}
398
399//------------------------------------------------------------------------------
402inline bool
403ResourceServer::HasResource(const Resources::ResourceId id) const
404{
405 if (this->loaders.Size() <= id.loaderIndex) return false;
406 {
407 const Ptr<ResourceLoader>& loader = this->loaders[id.loaderIndex];
408 if (loader->HasResource(id)) return true;
409 return false;
410 }
411}
412
413//------------------------------------------------------------------------------
416inline const Resources::ResourceId
418{
419 IndexT i;
420 for (i = 0; i < this->loaders.Size(); i++)
421 {
422 Resources::ResourceId id = this->loaders[i]->GetId(name);
423 if (id != Resources::ResourceId::Invalid()) return id;
424 }
425 return Resources::ResourceId::Invalid();
426}
427
428//------------------------------------------------------------------------------
431template <class POOL_TYPE>
432inline POOL_TYPE*
434{
435 static_assert(std::is_base_of<ResourceLoader, POOL_TYPE>::value, "Type requested is not a stream pool");
436 IndexT i = this->typeMap.FindIndex(&POOL_TYPE::RTTI);
437 if (i != InvalidIndex)
438 {
439 return static_cast<POOL_TYPE*>(this->loaders[this->typeMap.ValueAtIndex(i)].get());
440 }
441
442 n_error("No loader registered for this type");
443 return nullptr;
444}
445
446//------------------------------------------------------------------------------
450inline Resources::ResourceId
452 const ResourceName& res
453 , const Util::StringAtom& tag
454 , std::function<void(const Resources::ResourceId)> success = nullptr
455 , std::function<void(const Resources::ResourceId)> failed = nullptr
456 , bool immediate = false
457 , bool stream = true
458)
459{
460 return ResourceServer::Instance()->CreateResource(res, tag, success, failed, immediate, stream);
461}
462
463//------------------------------------------------------------------------------
467template <class METADATA>
468inline Resources::ResourceId
470 const ResourceName& res
471 , const METADATA& metaData
472 , const Util::StringAtom& tag
473 , std::function<void(const Resources::ResourceId)> success = nullptr
474 , std::function<void(const Resources::ResourceId)> failed = nullptr
475 , bool immediate = false
476 , bool stream = true
477)
478{
479 return ResourceServer::Instance()->CreateResource(res, metaData, tag, success, failed, immediate, stream);
480}
481
482//------------------------------------------------------------------------------
486inline Resources::ResourceId
488 const IO::Path& res,
489 const Util::StringAtom& tag,
490 std::function<void(const Resources::ResourceId)> success = nullptr,
491 std::function<void(const Resources::ResourceId)> failed = nullptr,
492 bool immediate = false,
493 bool stream = true
494)
495{
496 return ResourceServer::Instance()->CreateResource(res, tag, success, failed, immediate, stream);
497}
498
499//------------------------------------------------------------------------------
503inline void
505 const ResourceId& id
506 , std::function<void(const Resources::ResourceId)> success
507 , std::function<void(const Resources::ResourceId)> failed = nullptr
508)
509{
510 return ResourceServer::Instance()->CreateResourceListener(id, success, failed);
511}
512
513//------------------------------------------------------------------------------
516inline void
517SetMinLod(const ResourceId& id, float lod, bool immediate)
518{
519 return ResourceServer::Instance()->SetMinLod(id, lod, immediate);
520}
521
522//------------------------------------------------------------------------------
525inline void
526DiscardResource(const Resources::ResourceId id)
527{
528 ResourceServer::Instance()->DiscardResource(id);
529}
530
531//------------------------------------------------------------------------------
534inline void
536{
537 return ResourceServer::Instance()->ReloadResource(res);
538}
539
540//------------------------------------------------------------------------------
543inline void
545{
546 ResourceServer::Instance()->WaitForLoaderThread();
547}
548
549//------------------------------------------------------------------------------
552template <class POOL_TYPE>
553inline POOL_TYPE*
555{
556 static_assert(std::is_base_of<ResourceLoader, POOL_TYPE>::value, "Template argument is not a ResourceCache type!");
557 return ResourceServer::Instance()->GetStreamLoader<POOL_TYPE>();
558}
559
560} // namespace Resources
The common base class of Nebula.
Definition refcounted.h:38
Nebula's runtime type information for one class.
Definition rtti.h:27
A path is an abstraction around file paths.
Definition path.h:26
const Util::String & GetType() const
Get type.
Definition path.cc:414
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:285
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:300
__DeclareClass(ResourceServer)
void Close()
close manager
Definition resourceserver.cc:55
__DeclareInterfaceSingleton(ResourceServer)
bool HasStreamLoader(const Util::StringAtom &ext) const
query if a stream loader is registered for a given extension
Definition resourceserver.h:270
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:317
void Open()
open manager
Definition resourceserver.cc:44
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:126
ResourceServer()
constructor
Definition resourceserver.cc:25
Util::Dictionary< Util::StringAtom, IndexT > extensionMap
Definition resourceserver.h:114
Util::Dictionary< const Core::Rtti *, IndexT > typeMap
Definition resourceserver.h:116
const Resources::ResourceId GetId(const Resources::ResourceName &name) const
get id from name
Definition resourceserver.h:417
friend class ResourceLoader
Definition resourceserver.h:111
void DiscardResources(const Util::StringAtom &tag)
discard all resources by tag (stream-managed)
Definition resourceserver.cc:167
bool HasResource(const Resources::ResourceId id) const
check if resource id is valid
Definition resourceserver.h:403
Resources::ResourceId CreateResource(const IO::Path &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)
overload which also takes an identifying tag, which is used to group-discard resources
void DiscardResource(const Resources::ResourceId res)
discard resource (stream-managed)
Definition resourceserver.h:338
virtual ~ResourceServer()
destructor
Definition resourceserver.cc:34
Core::Rtti * GetType(const Resources::ResourceId id)
get type of resource pool this resource was allocated with
Definition resourceserver.cc:201
Util::Dictionary< Util::StringAtom, IndexT > loaderMap
Definition resourceserver.h:115
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:252
const Resources::ResourceName GetName(const Resources::ResourceId id) const
get resource name
Definition resourceserver.h:355
Util::Array< Ptr< ResourceLoader > > loaders
Definition resourceserver.h:117
const Resource::State GetState(const Resources::ResourceId id) const
get resource state
Definition resourceserver.h:379
Resources::ResourceId CreateResource(const IO::Path &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)
create a new resource (stream-managed), which will be loaded at some later point, if not already load...
void DeregisterStreamLoader(const Util::StringAtom &ext, const Ptr< ResourceLoader > &loader)
deregisters a stream pool
Definition resourceserver.cc:111
const SizeT GetUsage(const Resources::ResourceId id) const
get usage
Definition resourceserver.h:391
bool HasPendingResources()
returns true if there are pending resources in-flight
Definition resourceserver.cc:181
const Util::StringAtom GetTag(const Resources::ResourceId id) const
get tag resource was first registered with
Definition resourceserver.h:367
void LoadDefaultResources()
goes through all pools and sets up their default resources
Definition resourceserver.cc:138
POOL_TYPE * GetStreamLoader() const
get stream pool for later use
Definition resourceserver.h:433
bool open
Definition resourceserver.h:113
void RegisterStreamLoader(const Util::StringAtom &ext, const Ptr< ResourceLoader > &loader)
register a stream pool, which takes an extension and the RTTI of the resource type to create
Definition resourceserver.cc:99
void WaitForLoaderThread()
Wait for all loader threads.
Definition resourceserver.cc:216
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:61
#define n_warn_fmt(exp, msg,...)
Definition debug.h:64
#define n_assert(exp)
Definition debug.h:58
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:451
POOL_TYPE * GetStreamLoader()
Definition resourceserver.h:554
void DiscardResource(const Resources::ResourceId id)
Definition resourceserver.h:526
@ Update
Definition resourceloader.h:53
void WaitForLoaderThread()
Definition resourceserver.h:544
void ReloadResource(const ResourceName &res)
Definition resourceserver.h:535
Util::StringAtom ResourceName
Definition resourceid.h:33
void SetMinLod(const ResourceId &id, float lod, bool immediate)
Definition resourceserver.h:517
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:504
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