Resource Usage – Arma Reforger
Jump to navigation
Jump to search
Lou Montana (talk | contribs) m (Fix example) |
Lou Montana (talk | contribs) m (Fix) |
||
Line 1: | Line 1: | ||
{{TOC|side}} | <!-- {{TOC|side}} --> | ||
A {{Link/Enfusion|armaR|Resource}} object is a source of data through many classes ({{Link/Enfusion|armaR|BaseContainer}}, {{Link/Enfusion|armaR|IEntitySource}} etc). | A {{Link/Enfusion|armaR|Resource}} object is a source of data through many classes ({{Link/Enfusion|armaR|BaseResourceObject}} and its {{Link/Enfusion|armaR|BaseContainer}}, {{Link/Enfusion|armaR|IEntitySource}} etc). | ||
Due to how | Due to how resource references are managed, some safeties are required. | ||
Line 7: | Line 7: | ||
Resources are managed by the engine, outside of script's reach. | Resources are managed by the engine, outside of script's reach. | ||
If the script loses reference to a Resource object, the engine may dispose of it instantly or at some point in the future, deleting also its related BaseContainer objects. | If the script loses reference to a Resource object, the engine may dispose of it instantly or at some point in the future, deleting also its related BaseContainer/IEntitySource/etc objects (it is impossible to have a strong {{hl|ref}} to a BaseContainer object in script).<br> | ||
To avoid this, always keep a reference to the parent Resource. | To avoid this, always keep a reference to the parent Resource. | ||
Line 90: | Line 90: | ||
| {{n/a}} | | {{n/a}} | ||
| <enforce> | | <enforce> | ||
// this is fine - a Managed instance is created, resource can be dropped | // this is fine - a Managed instance is created, resource reference can be dropped | ||
// simplified, from {{Link/Enfusion|armaR|SCR_BaseContainerTools}}.CreateInstanceFromPrefab() | // simplified, from {{Link/Enfusion|armaR|SCR_BaseContainerTools}}.CreateInstanceFromPrefab() | ||
static Managed CreateInstanceFromPrefab(ResourceName prefab) | static Managed CreateInstanceFromPrefab(ResourceName prefab) |
Latest revision as of 18:04, 15 November 2023
A Resource object is a source of data through many classes (BaseResourceObject and its BaseContainer, IEntitySource etc). Due to how resource references are managed, some safeties are required.
Good Practice
Resources are managed by the engine, outside of script's reach.
If the script loses reference to a Resource object, the engine may dispose of it instantly or at some point in the future, deleting also its related BaseContainer/IEntitySource/etc objects (it is impossible to have a strong ref to a BaseContainer object in script).
To avoid this, always keep a reference to the parent Resource.
Examples
Bad Example | Good Example |
---|---|
static BaseContainer GetBaseContainer(ResourceName resourceName)
{
// the only reference to said Resource is here and will be lost at the end of the scope
Resource resource = Resource.Load(resourceName);
if (!resource.IsValid())
return null;
return resource.GetResource().ToBaseContainer();
// resource's reference is dropped here
// the returned BaseContainer may become null at any time,
// even with a script's reference
} |
static BaseContainer GetBaseContainer(notnull Resource resource)
{
if (!resource.IsValid())
return null;
return resource.GetResource().ToBaseContainer();
// resource's reference is managed by the method caller
} |
// GetBaseContainer being the above method
BaseContainer baseContainer = GetBaseContainer(m_sPrefab);
string name = baseContainer.GetClassName(); // may result in a null pointer exception |
Resource resource = Resource.Load(m_sPrefab);
BaseContainer baseContainer = GetBaseContainer(resource);
string name = baseContainer.GetClassName(); // fine as long as a reference to resource is kept |
// beware of loops!
array<BaseContainer> baseContainers = {}; // strong ref is not possible
Resource resource;
foreach (ResourceName resourceName : resourceNames)
{
resource = Resource.Load(resourceName);
if (!resource.IsValid())
continue;
baseContainers.Insert(resource.GetResource().ToBaseContainer());
// reference to resource is lost at each loop end
}
Process(baseContainers); // the array may contain nulls |
array<ref Resource> resources = {};
array<BaseContainer> baseContainers = {};
Resource resource;
foreach (ResourceName resourceName : resourceNames)
{
resource = Resource.Load(resourceName);
if (!resource.IsValid())
continue;
resources.Insert(resource);
baseContainers.Insert(resource.GetResource().ToBaseContainer());
// reference to resource is kept in the resources array
}
Process(baseContainers); // all references are kept
resources = null; // this can now be done without issue |
N/A | // this is fine - a Managed instance is created, resource reference can be dropped
// simplified, from SCR_BaseContainerTools.CreateInstanceFromPrefab()
static Managed CreateInstanceFromPrefab(ResourceName prefab)
{
Resource resource = Resource.Load(prefab);
if (!resource.IsValid())
return null;
BaseContainer baseContainer = resource.GetResource().ToBaseContainer();
if (!baseContainer)
return null;
return BaseContainerTools.CreateInstanceFromContainer(baseContainer);
// resource reference is dropped but the created instance will remain
} |