CUGL 2.3
Cornell University Game Library
Loading...
Searching...
No Matches
Public Member Functions | Static Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
cugl::AssetManager Class Reference

#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< Tget (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< AssetManageralloc ()
 

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
 

Detailed Description

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.

Constructor & Destructor Documentation

◆ AssetManager()

cugl::AssetManager::AssetManager ( )
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.

◆ ~AssetManager()

cugl::AssetManager::~AssetManager ( )
inline

Deletes this asset manager, disposing of all resources.

Member Function Documentation

◆ access()

template<typename T >
std::shared_ptr< Loader< T > > cugl::AssetManager::access ( ) const
inline

Returns the loader for the given asset Type

The type of the asset is specified by the template parameter T.

Returns
the loader for the given asset Type

◆ alloc()

static std::shared_ptr< AssetManager > cugl::AssetManager::alloc ( )
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.

Returns
a newly allocated asset manager with two auxiliary threads.

◆ attach()

template<typename T >
bool cugl::AssetManager::attach ( const std::shared_ptr< BaseLoader > &  loader)
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

Parameters
loaderThe loader for asset T
Returns
false if there is already a loader for this asset

◆ block()

void cugl::AssetManager::block ( )
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.

◆ complete()

bool cugl::AssetManager::complete ( ) const
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.

Returns
true if the loader has finished loading

◆ detach()

template<typename T >
bool cugl::AssetManager::detach ( )
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.

Returns
true if there was a loader of that Type.

◆ detachAll()

void cugl::AssetManager::detachAll ( )
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.

◆ dispose()

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.

◆ get()

template<typename T >
std::shared_ptr< T > cugl::AssetManager::get ( const std::string  key) const
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.

Parameters
keyThe key to identify the given asset
Returns
the asset for the given key.

◆ init()

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.

Returns
true if the asset manager was initialized successfully

◆ isAttached()

template<typename T >
bool cugl::AssetManager::isAttached ( )
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.

Returns
true if there is a loader for the given asset Type

◆ load()

template<typename T >
bool cugl::AssetManager::load ( const std::string  key,
const std::string  source 
)
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.

Parameters
keyThe key to access the asset after loading
sourceThe pathname to the asset source
Returns
true if the asset was successfully loaded

◆ loadAsync()

template<typename T >
void cugl::AssetManager::loadAsync ( const std::string  key,
const std::string  source,
LoaderCallback  callback 
)
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.

Parameters
keyThe key to access the asset after loading
sourceThe pathname to the asset source
callbackAn optional callback for when the asset is loaded.

◆ loadCount()

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.

Returns
the number of assets currently loaded.

◆ loadDirectory() [1/2]

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.

Parameters
jsonThe JSON asset directory
Returns
true if all assets specified in the directory were successfully loaded.

◆ loadDirectory() [2/2]

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.

Parameters
directoryThe path to the JSON asset directory
Returns
true if all assets specified in the directory were successfully loaded.

◆ loadDirectoryAsync() [1/2]

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.

Parameters
jsonThe JSON asset directory
callbackAn optional callback after each asset is loaded

◆ loadDirectoryAsync() [2/2]

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.

Parameters
directoryThe path to the JSON asset directory
callbackAn optional callback after each asset is loaded

◆ progress()

float cugl::AssetManager::progress ( ) const
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.

Returns
the loader progress as a percentage.

◆ purgeCategory()

bool cugl::AssetManager::purgeCategory ( size_t  hash,
const std::shared_ptr< JsonValue > &  json 
)
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.

Parameters
hashThe hash of the asset type
jsonThe child of asset directory with these assets
Returns
true if all assets of this type were successfully loaded.

◆ readCategory() [1/2]

bool cugl::AssetManager::readCategory ( size_t  hash,
const std::shared_ptr< JsonValue > &  json 
)
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.

Parameters
hashThe hash of the asset type
jsonThe child of asset directory with these assets
Returns
true if all assets of this type were successfully loaded.

◆ readCategory() [2/2]

void cugl::AssetManager::readCategory ( size_t  hash,
const std::shared_ptr< JsonValue > &  json,
LoaderCallback  callback 
)
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.

Parameters
hashThe hash of the asset type
jsonThe child of asset directory with these assets
callbackAn optional callback after each asset is loaded

◆ resume()

void cugl::AssetManager::resume ( )
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.

◆ sync()

void cugl::AssetManager::sync ( )
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.

◆ unload()

template<typename T >
void cugl::AssetManager::unload ( const std::string  key)
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.

Parameters
keythe key referencing the asset

◆ unloadAll()

void cugl::AssetManager::unloadAll ( )
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.

◆ unloadDirectory() [1/2]

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.

Parameters
jsonThe JSON asset directory

◆ unloadDirectory() [2/2]

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.

Parameters
directoryThe path to the JSON asset directory

◆ waitCount()

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.

Returns
the number of assets waiting to load.

Member Data Documentation

◆ _handlers

std::unordered_map<size_t,std::shared_ptr<BaseLoader> > cugl::AssetManager::_handlers
protected

The individual loaders for each type

◆ _jsonKeys

std::unordered_map<std::string,size_t> cugl::AssetManager::_jsonKeys
protected

The JSON keys for each type

◆ _preload

bool cugl::AssetManager::_preload
protected

State variable to manage reading JSON directories

◆ _priority

std::unordered_map<std::string,Uint32> cugl::AssetManager::_priority
protected

The priorities for each JSON key

◆ _wait

std::atomic<bool> cugl::AssetManager::_wait
protected

Wait variable to create a load barrier for directories.

◆ _workers

std::shared_ptr<ThreadPool> cugl::AssetManager::_workers
protected

The central thread for managing all of the loaders


The documentation for this class was generated from the following file: