CUGL 2.3
Cornell University Game Library
|
#include <CUAssetManager.h>
Public Member Functions | |
AssetManager () | |
~AssetManager () | |
void | dispose () |
bool | init () |
template<typename T > | |
bool | attach (const std::shared_ptr< BaseLoader > &loader) |
template<typename T > | |
bool | isAttached () |
template<typename T > | |
bool | detach () |
void | detachAll () |
template<typename T > | |
std::shared_ptr< Loader< T > > | access () const |
size_t | loadCount () const |
size_t | waitCount () const |
bool | complete () const |
float | progress () const |
template<typename T > | |
std::shared_ptr< T > | get (const std::string key) const |
template<typename T > | |
bool | load (const std::string key, const std::string source) |
template<typename T > | |
void | loadAsync (const std::string key, const std::string source, LoaderCallback callback) |
template<typename T > | |
void | unload (const std::string key) |
void | unloadAll () |
bool | loadDirectory (const std::shared_ptr< JsonValue > &json) |
bool | loadDirectory (const std::string directory) |
void | loadDirectoryAsync (const std::shared_ptr< JsonValue > &json, LoaderCallback callback) |
void | loadDirectoryAsync (const std::string directory, LoaderCallback callback) |
bool | unloadDirectory (const std::shared_ptr< JsonValue > &json) |
bool | unloadDirectory (const std::string directory) |
Static Public Member Functions | |
static std::shared_ptr< AssetManager > | alloc () |
Protected Member Functions | |
bool | readCategory (size_t hash, const std::shared_ptr< JsonValue > &json) |
void | readCategory (size_t hash, const std::shared_ptr< JsonValue > &json, LoaderCallback callback) |
bool | purgeCategory (size_t hash, const std::shared_ptr< JsonValue > &json) |
void | sync () |
void | block () |
void | resume () |
Protected Attributes | |
std::unordered_map< size_t, std::shared_ptr< BaseLoader > > | _handlers |
std::unordered_map< std::string, size_t > | _jsonKeys |
std::unordered_map< std::string, Uint32 > | _priority |
std::shared_ptr< ThreadPool > | _workers |
bool | _preload |
std::atomic< bool > | _wait |
This class is loader/manager for handling a wide variety of assets.
This asset manager is uses to manage a collection of loaders. Loaders must be "attached" to the asset manager. The asset manager does not come with a collection of loaders pre-installed. You will need to do this yourself in the start-up code for each scene. Once a loader is attached to this asset manager, the manager obtains ownership of the loader. It will be responsible for garbage collection when it is done.
Like loaders, an asset manager both loads an asset and allows it to be referenced at any time via a key. This allows us to easily decouple asset loading from the rest of the application. To access an asset, you just need a (weak or strong) reference to the asset loader. However, we do not make asset managers a singleton, because different player modes may want different asset managers.
Disposing an asset manager unloads all of the assets. However, assets may still be used after an asset manager is destroyed, provided that they still have a smart pointer referencing them.
IMPORTANT: This class is not even remotely thread-safe. Do not call any of these methods outside of the main CUGL thread.
|
inline |
Creates a degenerate asset manager with no attached threads.
NEVER USE A CONSTRUCTOR WITH NEW. If you want to allocate an asset manager on the heap, use one of the static constructors instead.
|
inline |
Deletes this asset manager, disposing of all resources.
Returns the loader for the given asset Type
The type of the asset is specified by the template parameter T.
|
inlinestatic |
Returns a newly allocated asset manager.
The asset manager has a single thread, as some of the asset loading operations (particularly fonts) cannot be run in multiple threads simultaneously. However, it will run in a distinct thread from the main application.
This constructor does not attach any loaders. It simply creates an object that is ready to accept loader objects.
|
inline |
Attaches the given loader to the asset manager
The type of the asset is specified by the template parameter T. Once attached, all assets of type T will use this loader for this scene. In addition, this asset manager will obtain ownership of the loader and be responsible for its garbage collection.
If the loader has a nonempty JSON key, then it will support asset directories. It its JSON key is already in use, then it will not its JSON key will be set to empty
loader | The loader for asset T |
|
protected |
Blocks the asset manager until the next animation frame.
Any assets queued after a block will not be added to thread pool until at least one animation frame has passed. This method is used to implement the sync()
method.
|
inline |
Returns true if the loader has finished loading all assets.
It is not safe to use asynchronously loaded assets until all loading is complete. This method allows us to determine when asset loading is complete via polling.
|
inline |
Detaches a loader for an asset type
The type of the asset is specified by the template parameter T. The loader will be released and deleted if there are no further (smart pointer) references to it.
|
inline |
Detaches all loaders from this asset manager
The loaders will be released and deleted if there are no further (smart pointer) references to them.
void cugl::AssetManager::dispose | ( | ) |
Detaches all the attached loaders and deletes all auxiliary threads.
Unlike the destructor, this does not destroy the asset manager. However, you will need to reinitialize the manager (to restart the auxiliary threads) and reattach all loaders to use the asset manager again.
|
inline |
Returns the asset for the given key.
The type of the asset is specified by the template parameter T. Because the method is parameterized by the type, it is safe to reuse keys for different types. However, this is not recommended.
key | The key to identify the given asset |
bool cugl::AssetManager::init | ( | ) |
Initializes a new asset manager.
The asset manager has a single thread, as some of the asset loading operations (particularly fonts) cannot be run in multiple threads simultaneously. However, it will run in a distinct thread from the main application.
This initializer does not attach any loaders. It simply creates an object that is ready to accept loader objects.
|
inline |
Returns true if there is a loader for the given asset Type
The type of the asset is specified by the template parameter T.
|
inline |
Loads an asset and assigns it to the given key.
The type of the asset is specified by the template parameter T. Because the method is parameterized by the type, it is safe to reuse keys for different types. However, this is not recommended.
This method essentially calls BaseLoader#load
in the appropriate loader. If there is no loader for the given type, the method will fail.
The asset will be loaded synchronously. This means it will be available immediately. This method should be limited to those times in which an asset is really necessary immediately, such as for a loading screen.
key | The key to access the asset after loading |
source | The pathname to the asset source |
|
inline |
Adds a new asset to the loading queue.
The type of the asset is specified by the template parameter T. Because the method is parameterized by the type, it is safe to reuse keys for different types. However, this is not recommended.
This method essentially calls BaseLoader#loadAsync
in the appropriate loader. If there is no loader for the given type, the method will fail.
The asset will be loaded asynchronously. When it is finished loading, it will be added to this loader, and accessible under the given key. This method will mark the loading process as not complete, even if it was completed previously. It is not safe to access the loaded asset until it is complete again.
The optional callback function will be called with the asset status when the loading either completes or fails.
key | The key to access the asset after loading |
source | The pathname to the asset source |
callback | An optional callback for when the asset is loaded. |
size_t cugl::AssetManager::loadCount | ( | ) | const |
Returns the number of assets currently loaded.
This method is a rough way to determine how many assets have been loaded so far. This method counts each asset equally regardless of the memory requirements of each asset.
The value returned is the sum of the loadCount for all attached loaders.
bool cugl::AssetManager::loadDirectory | ( | const std::shared_ptr< JsonValue > & | json | ) |
Synchronously loads all assets in the given directory.
JSON directories provide a robust way for us to load a collection of assets. Instead of having to define parameters like asset key, font size, or texture wrap in the code, we can specify them in a JSON file. This JSON file (called the asset directory) is read by the asset manager, and directs the various loaders to load in assets.
Currently JSON loading supports five types of assets, with the following names: "textures", "fonts", "music", "soundfx", and "jsons". See the method BaseLoader#read
in each of the individual loaders for a description of the suported JSON format. A loader must still be attached for the asset manager to read that type of asset. If the asset directory contains an asset for which there is no attached asset manager, those specific assets will not be loaded.
This method will try to load as many assets from the directory as it can. If any asset fails to load, it will return false. However, some assets may still be loaded and safe to access.
json | The JSON asset directory |
bool cugl::AssetManager::loadDirectory | ( | const std::string | directory | ) |
Synchronously loads all assets in the given directory.
JSON directories provide a robust way for us to load a collection of assets. Instead of having to define parameters like asset key, font size, or texture wrap in the code, we can specify them in a JSON file. This JSON file (called the asset directory) is read by the asset manager, and directs the various loaders to load in assets.
Currently JSON loading supports five types of assets, with the following names: "textures", "fonts", "music", "soundfx", and "jsons". See the method BaseLoader#read
in each of the individual loaders for a description of the suported JSON format. A loader must still be attached for the asset manager to read that type of asset. If the asset directory contains an asset for which there is no attached asset manager, those specific assets will not be loaded.
This method will try to load as many assets from the directory as it can. If any asset fails to load, it will return false. However, some assets may still be loaded and safe to access.
directory | The path to the JSON asset directory |
void cugl::AssetManager::loadDirectoryAsync | ( | const std::shared_ptr< JsonValue > & | json, |
LoaderCallback | callback | ||
) |
Asynchronously loads all assets in the given directory.
JSON directories provide a robust way for us to load a collection of assets. Instead of having to define parameters like asset key, font size, or texture wrap in the code, we can specify them in a JSON file. This JSON file (called the asset directory) is read by the asset manager, and directs the various loaders to load in assets.
JSON support is determined modularly by the loaders. Each loader has an associated JSON key, given by BaseLoader#getJsonKey
. The key corresponds to a top-level object in the JSON file. That loader is responsible for processing the object for that key. This means that asset directories are highly flexible, and their entries are only restricted by the loaders that the programmer provides.
Some loaders depend upon each other. For example Scene2Loader
typically requires TextureLoader
to finish loading all textures first. To support this relationship, loaders have priorities, given by BaseLoader#getPriority
. Loaders with higher priority are guaranteed to complete before moving on to loaders of lower priority.
Currently JSON loading supports five types of assets, with the following names: "textures", "fonts", "music", "soundfx", and "jsons". See the method BaseLoader#read
in each of the individual loaders for a description of the suported JSON format. A loader must still be attached for the asset manager to read that type of asset. If the asset directory contains an asset for which there is no attached asset manager, those specific assets will not be loaded.
As an asynchronous load, all asset loading will take place outside of the main thread. However, assets such as fonts and textures will need the OpenGL context to complete, so part of their asset loading may take place in the main thread via the Application#schedule
interface. You may either poll this interface to determine when the assets are loaded or use optional callbacks.
The optional callback function will be called each time an individual asset loads or fails to load. However, if the entire category fails to load, the callback function will be given the asset category name (e.g. "soundfx") as the asset key.
json | The JSON asset directory |
callback | An optional callback after each asset is loaded |
void cugl::AssetManager::loadDirectoryAsync | ( | const std::string | directory, |
LoaderCallback | callback | ||
) |
Asynchronously loads all assets in the given directory.
JSON directories provide a robust way for us to load a collection of assets. Instead of having to define parameters like asset key, font size, or texture wrap in the code, we can specify them in a JSON file. This JSON file (called the asset directory) is read by the asset manager, and directs the various loaders to load in assets.
JSON support is determined modularly by the loaders. Each loader has an associated JSON key, given by BaseLoader#getJsonKey
. The key corresponds to a top-level object in the JSON file. That loader is responsible for processing the object for that key. This means that asset directories are highly flexible, and their entries are only restricted by the loaders that the programmer provides.
Some loaders depend upon each other. For example Scene2Loader
typically requires TextureLoader
to finish loading all textures first. To support this relationship, loaders have priorities, given by BaseLoader#getPriority
. Loaders with higher priority are guaranteed to complete before moving on to loaders of lower priority.
As an asynchronous load, all asset loading will take place outside of the main thread. However, assets such as fonts and textures will need the OpenGL context to complete, so part of their asset loading may take place in the main thread via the Application#schedule
interface. You may either poll this interface to determine when the assets are loaded or use optional callbacks.
The optional callback function will be called each time an individual asset loads or fails to load. However, if the entire category fails to load, the callback function will be given the asset category name (e.g. "soundfx") as the asset key.
directory | The path to the JSON asset directory |
callback | An optional callback after each asset is loaded |
|
inline |
Returns the loader progress as a percentage.
This method returns a value between 0 and 1. A value of 0 means no assets have been loaded. A value of 1 means that all assets have been loaded.
Anything in-between indicates that there are assets which have been loaded asynchronously and have not completed loading. It is not safe to use asynchronously loaded assets until all loading is complete.
|
protected |
Immediately removes an asset category previously loaded from the JSON file
This method is used by the unloadDirectory
method to remove assets a category at a time. Unloading is instantaneous and occurs in the main thread.
hash | The hash of the asset type |
json | The child of asset directory with these assets |
|
protected |
Synchronously reads an asset category from a JSON file
JSON directories provide a robust way for us to load a collection of assets. Instead of having to define parameters like asset key, font size, or texture wrap in the code, we can specify them in a JSON file. This JSON file (called the asset directory) is read by the asset manager, and directs the various loaders to load in assets.
Currently JSON loading supports five types of assets, with the following names: "textures", "fonts", "music", "soundfx", and "jsons". See the method BaseLoader#read
in each of the individual loaders for a description of the suported JSON format. A loader must still be attached for the asset manager to read that type of asset. If the asset directory contains an asset for which there is no attached asset manager, those specific assets will not be loaded.
hash | The hash of the asset type |
json | The child of asset directory with these assets |
|
protected |
Asynchronously reads an asset category from a JSON file
JSON directories provide a robust way for us to load a collection of assets. Instead of having to define parameters like asset key, font size, or texture wrap in the code, we can specify them in a JSON file. This JSON file (called the asset directory) is read by the asset manager, and directs the various loaders to load in assets.
Currently JSON loading supports five types of assets, with the following names: "textures", "fonts", "music", "soundfx", and "jsons". See the method BaseLoader#read
in each of the individual loaders for a description of the suported JSON format. A loader must still be attached for the asset manager to read that type of asset. If the asset directory contains an asset for which there is no attached asset manager, those specific assets will not be loaded.
As an asynchronous read, all asset loading will take place outside of the main thread. However, assets such as fonts and textures will need the OpenGL context to complete, so part of their asset loading may take place in the main thread via the Application#schedule
interface. You may either poll this interface to determine when the assets are loaded or use optional callbacks.
The optional callback function will be called each time an individual asset loads or fails to load. However, if the entire category fails to load, the callback function will be given the asset category name (e.g. "soundfx") as the asset key.
hash | The hash of the asset type |
json | The child of asset directory with these assets |
callback | An optional callback after each asset is loaded |
|
protected |
Resumes a previously blocked the asset manager.
Any assets queued after a block will not be added to thread pool until at least one animation frame has passed. This method is used to implement the sync()
method.
|
protected |
Synchronizes the asset manager to wait until all assets have finished.
This method is necessary for assets whose construction depends on previously loaded assets (e.g. scene graphs). In the current architecture, this method is only correct if the asset manager loads assets in a single thread.
|
inline |
Unloads the asset for the given key.
The type of the asset is specified by the template parameter T. Because the method is parameterized by the type, it is safe to reuse keys for different types. However, this is not recommended.
This method simply unloads the asset from this asset manager. If there are active smart pointers still referencing the asset, it still may remain in memory. However, the rest of the program can no longer access the asset by key.
key | the key referencing the asset |
|
inline |
Unloads all assets present in this loader.
This method unloads all assets associated with this loader. If there are active smart pointers still referencing the assets, they still may remain in memory. However, the rest of the program can no longer access these assets.
bool cugl::AssetManager::unloadDirectory | ( | const std::shared_ptr< JsonValue > & | json | ) |
Unloads all assets for the given directory.
This method unloads only those assets associated with the given directory. If there are active smart pointers still referencing the assets, they still may remain in memory. However, the rest of the program can no longer access these assets.
json | The JSON asset directory |
bool cugl::AssetManager::unloadDirectory | ( | const std::string | directory | ) |
Unloads all assets for the given directory.
This method unloads only those assets associated with the given directory. If there are active smart pointers still referencing the assets, they still may remain in memory. However, the rest of the program can no longer access these assets.
directory | The path to the JSON asset directory |
size_t cugl::AssetManager::waitCount | ( | ) | const |
Returns the number of assets waiting to load.
This is a rough way to determine how many assets are still pending. An asset is pending if it has been loaded asychronously, and the loading process has not yet finished. This method counts each asset equally regardless of the memory requirements of each asset.
The value returned is the sum of the waitCount for all attached loaders.
|
protected |
The individual loaders for each type
|
protected |
The JSON keys for each type
|
protected |
State variable to manage reading JSON directories
|
protected |
The priorities for each JSON key
|
protected |
Wait variable to create a load barrier for directories.
|
protected |
The central thread for managing all of the loaders