Open 3D Engine AtomCore API Reference 23.10.0
O3DE is an open-source, fully-featured, high-fidelity, modular 3D engine for building games and simulations, available to every industry.
AZ::Data::InstanceDatabase< Type > Class Template Referencefinal

#include <InstanceDatabase.h>

Inherits AZ::Data::InstanceDatabaseInterface.

Public Member Functions

 AZ_CLASS_ALLOCATOR (InstanceDatabase, AZ::SystemAllocator)
 
Data::Instance< Type > Find (const InstanceId &id) const
 
Data::Instance< Type > FindOrCreate (const InstanceId &id, const Asset< AssetData > &asset, const AZStd::any *param=nullptr)
 
Data::Instance< Type > FindOrCreate (const Asset< AssetData > &asset, const AZStd::any *param=nullptr)
 Calls the above FindOrCreate using an InstanceId created from the asset.
 
Data::Instance< Type > Create (const Asset< AssetData > &asset, const AZStd::any *param=nullptr)
 Calls FindOrCreate using a random InstanceId.
 
void TEMPOrphan (const InstanceId &id)
 
void ForEach (AZStd::function< void(Type &)> callback)
 
void ForEach (AZStd::function< void(const Type &)> callback) const
 

Static Public Member Functions

static void Create (const AssetType &assetType, const InstanceHandler< Type > &handler, bool checkAssetIds=true)
 
static void Destroy ()
 
static bool IsReady ()
 
static InstanceDatabaseInstance ()
 

Additional Inherited Members

virtual void ReleaseInstance (InstanceData *instance, const InstanceId &instanceId)=0
 

Detailed Description

template<typename Type>
class AZ::Data::InstanceDatabase< Type >

This class is a simple database of typed instances. An 'instance' in this context is any class which inherits from InstanceData, is created at runtime from an asset, and has a unique instance id. The purpose of this system is to control de-duplication of instances at runtime, and to associate instance types with their originating asset types.

The database has itself singleton access, but it should be owned by the corresponding system (which is in charge of creation / destruction of the database). To use the database, you may instantiate it using one of the following approaches: 1) Instantiate one InstanceDatabase for each concrente instance class. Use this approach if all concrete instance classes are known at compile time. 2) Instantiate one InstanceDatabase for a known instance base class, and then register multiple InstanceHandlers for each concrete instance class. Use this approach if only the instance base class is known at compile time and the concrete instance classes are only known at runtime. For example, Atom provides abstract StreamingImageControllerAsset and StreamingImageController classes, and a game-specific gem can provide custom implementations by adding a handler to InstanceDatabase<StreamingImageController>.

The database allows you to find an instance from its corresponding InstanceId. Alternatively, you can 'find or create' an instance, which will create the instance if it doesn't already exist, or return you the existing instance. The 'find or create' operation takes an asset as input. Instances are designed to be trivially created from their parent asset.

The database does NOT own instances. Ownership is returned to you in the form of a smart pointer (Data::Instance<>). This is the same ownership model used by the asset manager.

The system is thread-safe. You can create / destroy instances from any thread, however Instances should not be copied between threads, they should always be retrieved from the InstanceDatabase directly.

Example Usage (using instantiation approach #1 described above):

// Create the database.
// Provide your own creator (and optional deleter) to control allocation / initialization of your object.
handler.m_createFunction = [] (Data::AssetData* assetData) { return aznew MyInstanceType(assetData); };
Data::InstanceDatabase<MyInstanceType>::Create(azrtti_typeid<MyAssetType>(), handler);
Data::Asset<MyAssetType> myAsset{ASSETID_1};
// Create an instance id from the asset id (1-to-1 mapping).
// Find or create an instance from an asset.
Data::Instance<MyInstanceType> instance = Data::InstanceDatabase<MyInstanceType>::Instance().FindOrCreate(instanceId, myAsset);
// Create an instance by name.
Data::InstanceId instanceIdName = Data::InstanceId::CreateName("HelloWorld");
// Creates a new instance from the same asset (the old instance is de-ref'd).
instance = Data::InstanceDatabase<MyInstanceType>::Instance().FindOrCreate(instanceIdName, myAsset);
// Finds an existing instance.
Data::Instance<MyInstanceType> instance2 = Data::InstanceDatabase<MyInstanceType>::Instance().Find(instanceIdName);
instance == instance2; // true
// Find or create an existing instance.
Data::Instance<MyInstanceType> instance3 = Data::InstanceDatabase<MyInstanceType>::Instance().FindOrCreate(instanceIdName, myAsset);
instance == instance2 == instance3; // true
// INVALID: Create an instance using a different asset.
Data::Asset<MyAssetType> myAsset2{ASSETID_2};
// This will assert. You can only request an instance using the SAME asset each time. If the system detects a mismatch it
// will throw an error.
Data::Instance<MyInstanceType> instance3 = Data::InstanceDatabase<MyInstanceType>::Instance().FindOrCreate(instanceIdName, myAsset2);
// After all objects are out of scope! The system will report an error if objects are still active on destruction.
Data::InstanceDatabase<MyInstanceType>::Destroy();
Definition: InstanceDatabase.h:158
static void Create(const AssetType &assetType, const InstanceHandler< Type > &handler, bool checkAssetIds=true)
Definition: InstanceDatabase.h:495
Data::Instance< Type > FindOrCreate(const InstanceId &id, const Asset< AssetData > &asset, const AZStd::any *param=nullptr)
Definition: InstanceDatabase.h:289
Data::Instance< Type > Find(const InstanceId &id) const
Definition: InstanceDatabase.h:277
Definition: InstanceDatabase.h:34
CreateFunction m_createFunction
Definition: InstanceDatabase.h:60
Definition: InstanceId.h:25
static InstanceId CreateName(const char *name)
static InstanceId CreateFromAssetId(const AssetId &assetId)

Member Function Documentation

◆ Create()

template<typename Type >
void AZ::Data::InstanceDatabase< Type >::Create ( const AssetType &  assetType,
const InstanceHandler< Type > &  handler,
bool  checkAssetIds = true 
)
static

Create the InstanceDatabase with a single handler. Use this function when creating an InstanceDatabase that will handle concrete classes of Type.

Parameters
assetType- All instances will be based on subclasses of this asset type.
handler- An InstanceHandler that creates instances of assetType assets.
checkAssetIds- If true, it will be validated that "instance->m_assetId == asset.GetId()"

◆ Find()

template<typename Type >
Data::Instance< Type > AZ::Data::InstanceDatabase< Type >::Find ( const InstanceId id) const

Attempts to find an instance associated with the provided id. If the instance exists, it is returned. If no instance is found, nullptr is returned. It is safe to call this from multiple threads.

Parameters
idThe id used to find an instance in the database.

◆ FindOrCreate()

template<typename Type >
Data::Instance< Type > AZ::Data::InstanceDatabase< Type >::FindOrCreate ( const InstanceId id,
const Asset< AssetData > &  asset,
const AZStd::any *  param = nullptr 
)

Attempts to find an instance associated with the provided id. If it exists, it is returned. Otherwise, it is created using the provided asset data and then returned. It is safe to call this method from multiple threads, even with the same id. The call is synchronous and other threads will block until creation is complete.

PERFORMANCE NOTE: If the asset data is not loaded and creation is required, the system will perform a BLOCKING load on the asset. If this behavior is not desired, the user should either ensure the asset is loaded prior to calling this method, or call Find instead.

Parameters
idThe id used to find or create an instance in the database.
assetThe asset used to initialize the instance, if it does NOT already exist. If the instance exists, the asset id is checked against the existing instance. If validation is enabled, the system will error if the created asset id does not match the provided asset id. It is required that you consistently provide the same asset when acquiring an instance.
Returns
Returns a smart pointer to the instance, which was either found or created.

◆ ForEach()

template<typename Type >
void AZ::Data::InstanceDatabase< Type >::ForEach ( AZStd::function< void(Type &)>  callback)

A helper function to visit every instance in the database and calls the provided callback method. Note: this function can be slow depending on how many instances in the database

◆ TEMPOrphan()

template<typename Type >
void AZ::Data::InstanceDatabase< Type >::TEMPOrphan ( const InstanceId id)

Removes the instance data from the database. Does not release it. References to existing instances will remain valid, but new calls to Create/FindOrCreate will create a new instance This function is temporary, to provide functionality needed for Model hot-reloading, but will be removed once the Model class does not need it anymore.

Parameters
idThe id of the instance to remove

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