Resource manager

The resource manager is a singleton. It can be created or accessed using the same code:

task

Task: Creating or accessing the resource manager

// Create the resource manager on first call or retrieve it on other calls:
RED::Object* resmgr = RED::Factory::CreateInstance( CID_REDResourceManager );
if( !resmgr )
{
  // Handle critical startup errors here.
}

// Access the resource manager interface:
RED::IResourceManager* iresmgr = resmgr->As< RED::IResourceManager >();

The resource manager is a singleton. Therefore, the first call to the factory will create the object, and all subsequent calls will return the created object. So it's a normal way of doing to access the resource manager object address by creating it again. The resource manager creation code should not fail otherwise REDsdk can't start. If this arise, please check that a fresh REDsdk installation can start, otherwise please check your licensing.

The resource manager serves several purposes:

It can be also used to set / retrieve some basic informations on the engine, such as:

So, this is a key object in any REDsdk application. The fact that the resource manager is a singleton makes it easy to access from anywhere in the calling application.

Releasing all REDsdk resources

On exit, after a reset, for the purpose of getting back memory, an application may want to delete all resources used by REDsdk. This can be achieved by destroying the resource manager of the application. On using the RED::Factory::DeleteInstance method for the resource manager, all resources in REDsdk will be destroyed. All data in the video memory will be released too.

After destruction, REDsdk can be restarted by creating another resource manager singleton.

Shared graphic resources

There are different kinds of resources that are shared among REDsdk objects:

Generally speaking, it's the responsibility of the calling application to manage how shared resources are used. On the destruction of an image, REDsdk does not parse all materials to remove that image from all the found shaders using it. This because REDsdk can't know what should be set instead of the image. If the image can be destroyed by the application, then it's the responsibility of the application to make sure that this image is not used anywhere else by the engine. If this rule is not enforced, the engine may return RED_SCG_INVALID_IMAGE_ADDRESS.

Similarly, releasing a material or a font does not invalidate the usage of this material or font from all shapes in the REDsdk scene graphs that exist. It's the responsibility of the calling application to ensure that the deleted resource is not used anymore before releasing it from the REDsdk resource manager.

Finally, shader programs are loaded using RED::IResourceManager::LoadShaderFromString and never discarded from the resource manager.

Please note that all images, materials and fonts generated in the cluster after loading .red files are under the control of the RED::IDataManager of the cluster. This is the data manager that will release these resources on releasing contexts.

task

Task: Creating or destroying an image

// Access the cluster's resource manager:
RED::Object* resmgr = RED::Factory::CreateInstance( CID_REDResourceManager );
RED::IResourceManager* iresmgr = resmgr->As< RED::IResourceManager >();
const RED::State& state = iresmgr->BeginState();

// Create an image (2D in this case, there's one creation method for each type of image):
RED::Object* image;
RC_TEST( iresmgr->CreateImage2D( image, state ) );

// Delete the image after use:
RC_TEST( iresmgr->DeleteImage( image, state ) );

The destruction of an image is a synchronous task. It should occur from the rendering thread of the application, and it's the responsibility of the application to ensure that the image is not used anymore in any shader of REDsdk.

task

Task: Creating or destroying a material

// Access the cluster's resource manager:
RED::Object* resmgr = RED::Factory::CreateInstance( CID_REDResourceManager );
RED::IResourceManager* iresmgr = resmgr->As< RED::IResourceManager >();
const RED::State& state = iresmgr->BeginState();

// Create a material:
RED::Object* material;
RC_TEST( iresmgr->CreateMaterial( material, state ) );

// Delete the material after use:
RC_TEST( iresmgr->DeleteMaterial( material, state ) );

The material destruction is a transaction managed operation that can occur from the application's writer thread. It's the responsibility of the calling application to ensure that the material is not used anymore in REDsdk prior to its destruction.

task

Task: Creating or destroying a font

// Access the cluster's resource manager:
RED::Object* resmgr = RED::Factory::CreateInstance( CID_REDResourceManager );
RED::IResourceManager* iresmgr = resmgr->As< RED::IResourceManager >();
const RED::State& state = iresmgr->BeginState();

// Create a font:
RED::Object* font;
RC_TEST( iresmgr->CreateFont( font, state ) );

// Delete the font after use:
RC_TEST( iresmgr->DeleteFont( font, state ) );

The font destruction is a transaction managed operation that can occur from the application's writer thread. It's the responsibility of the calling application to ensure that the font is not used anymore in REDsdk prior to its destruction.

Cleanup methods

REDsdk offsers cleanup methods that can be used to collect and erase all resources that are not in use anymore. Calling these methods can be time consuming if there are lots of objects in the cluster. Any resource that is not in use in the cluster will be released unless specified otherwise in the cleanup method. See: