patterncppMinor
Resource manager implementation, with resources being organized in a scope-like hierarchy
Viewed 0 times
resourcesresourcewithhierarchylikebeingscopeorganizedmanagerimplementation
Problem
The original question where the general concept of this implementation was discussed: Using ID's with a "scope" -like hierarchy
I have designed a resource manager as part of a game programming project that I have been working on as a hobby. Implementing as much functionality as possible in the least amount of time and effort is not my goal, instead my focus has been on learning how to design and implement a relatively large software project by myself.
An usage example for the submitted code:
```
//We will first create three resource contexts: the global context, and
//..two local contexts specific to each window
auto globalCtx = ResourceContext::makeGlobalContext();
auto gameCtx = globalCtx.makeLocalContext();
auto editorCtx = globalCtx.makeLocalContext();
//The virtual filesystem maps file ID:s to system paths. Since there is no
//..reason to create two separate virtual filesystems (one for each window)
//..we will make a new VirtualFs object in the global context.
auto vFilesys = globalCtx->make("/data/index.xml");
//The game's main window is created in the game's context (gameCtx).
auto mainWindow = gameCtx->make("Game", 800, 600, SDL_WINDOW_SHOWN,
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
//The editor window is created in the editor context (editorCtx). If both
//..windows were simply created in the global context, the second call to
//..globalContext->make(...) would simply return a shared_ptr to
//..the previously created game window.
auto editorWindow = editorCtx->make("Editor", 300, 600,
SDL_WINDOW_SHOWN, SDL_RENDERER_ACCELERATED);
//The hero belongs to the main window. Instead of passing a reference to
//..the window, we pass the game context. The Sprite code first searches
//..for a Window instance in the gameContext, and finds mainWindow, then
//..searches for a VirtualFs, which it does not find at first, but after
//..automatically searching in the parent context (globalCtx) too a
//..VirtualFs in
I have designed a resource manager as part of a game programming project that I have been working on as a hobby. Implementing as much functionality as possible in the least amount of time and effort is not my goal, instead my focus has been on learning how to design and implement a relatively large software project by myself.
An usage example for the submitted code:
```
//We will first create three resource contexts: the global context, and
//..two local contexts specific to each window
auto globalCtx = ResourceContext::makeGlobalContext();
auto gameCtx = globalCtx.makeLocalContext();
auto editorCtx = globalCtx.makeLocalContext();
//The virtual filesystem maps file ID:s to system paths. Since there is no
//..reason to create two separate virtual filesystems (one for each window)
//..we will make a new VirtualFs object in the global context.
auto vFilesys = globalCtx->make("/data/index.xml");
//The game's main window is created in the game's context (gameCtx).
auto mainWindow = gameCtx->make("Game", 800, 600, SDL_WINDOW_SHOWN,
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
//The editor window is created in the editor context (editorCtx). If both
//..windows were simply created in the global context, the second call to
//..globalContext->make(...) would simply return a shared_ptr to
//..the previously created game window.
auto editorWindow = editorCtx->make("Editor", 300, 600,
SDL_WINDOW_SHOWN, SDL_RENDERER_ACCELERATED);
//The hero belongs to the main window. Instead of passing a reference to
//..the window, we pass the game context. The Sprite code first searches
//..for a Window instance in the gameContext, and finds mainWindow, then
//..searches for a VirtualFs, which it does not find at first, but after
//..automatically searching in the parent context (globalCtx) too a
//..VirtualFs in
Solution
I can't answer all your questions, but here are some things you can improve or some guidelines you can follow:
-
In your function
into that:
-
Whenever possible, try to replace your
into that:
Technically speaking, you can go even further and use the
-
You could try to be consistent and use
All of those tips are only guidelines to properly use c++11 and nothing is actually specific to your code. I unfortunately did not managed to really dive into your code and think about its logic. You will have to wait for another answer if you want to improve it too.
- Always pass
std::shared_ptrby const reference. There are several reasons for this, some of them are explained in GOTW #91 by Herb Sutter.
-
In your function
make, you problem want to take the parameters by universal reference and use std::forward instead of simply passing them. Therefore, you can tranform this:template
std::shared_ptr make(Arg... ctorArgs)
{
return makeNamed(std::string(), ctorArgs...);
}into that:
template
std::shared_ptr make(Arg&&... ctorArgs)
{
return makeNamed(std::string(), std::forward(ctorArgs)...);
}-
Whenever possible, try to replace your
insert functions by emplace functions, especially when you created an object to immediately store it. You can turn this:auto keyValPair = std::make_pair(id, std::weak_ptr());
auto &mappedPtr = resourceMap.insert(keyValPair).first->second;into that:
auto &mappedPtr = resourceMap
.emplace(id, std::weak_ptr())
.first->second;Technically speaking, you can go even further and use the
std::pair piecewise construction to create your values directly in the std::pair directly in the std::map:auto &mappedPtr = resourceMap
.emplace(
std::piecewise_construct,
std::forward_as_tuple(id),
std::forward_as_tuple(std::weak_ptr())
).first->second;-
You could try to be consistent and use
std::make_shared everywhere instead of using new from time to time. I know that std::make_shared has problems to interact with private or protected constructors. However, there are some workarounds that you can use if you want to consistently use std::make_shared whenever possible.All of those tips are only guidelines to properly use c++11 and nothing is actually specific to your code. I unfortunately did not managed to really dive into your code and think about its logic. You will have to wait for another answer if you want to improve it too.
Code Snippets
template<typename T, typename...Arg>
std::shared_ptr<T> make(Arg... ctorArgs)
{
return makeNamed<T>(std::string(), ctorArgs...);
}template<typename T, typename...Arg>
std::shared_ptr<T> make(Arg&&... ctorArgs)
{
return makeNamed<T>(std::string(), std::forward<Arg>(ctorArgs)...);
}auto keyValPair = std::make_pair(id, std::weak_ptr<Resource>());
auto &mappedPtr = resourceMap.insert(keyValPair).first->second;auto &mappedPtr = resourceMap
.emplace(id, std::weak_ptr<Resource>())
.first->second;auto &mappedPtr = resourceMap
.emplace(
std::piecewise_construct,
std::forward_as_tuple(id),
std::forward_as_tuple(std::weak_ptr<Resource>())
).first->second;Context
StackExchange Code Review Q#43733, answer score: 4
Revisions (0)
No revisions yet.