Entity Activeness – Arma Reforger
Active Flag and Frame Events
Setting a FRAME event on a component or an entity makes said entity (or component's parent entity) simulated. The ACTIVE flag should be set on entities that are moved every frame but do not have any components using the FRAME event.
Doing so automatically calls an update on the entity along other engine operations such as updating the bounding box, etc.
When activating/deactivating a component, EOnActivate/EOnDeactivate component events are called, meaning that every component needs to take care of its own activation and deactivation by setting or clearing its FRAME flag.
Pre-0.9.8 Behaviour
Before 0.9.8, an ACTIVE flag on the entity would be necessary for any FRAME events. This means that any component which needed the FRAME events would need to set ACTIVE on its owner.
This led to the issue where multiple components could clear the ACTIVE flag event of the entity where another component would still require the FRAME event, bringing to this change.
Good Practices
The first step is to not set the ACTIVE flag on the entity by the component in order to to have FRAME events (pre-0.9.8 way).
And then, as said above, when a component is disabled, it is its job to set/clear its event mask itself when it gets activated/deactivated.
Examples
Bad Example | Good Example |
---|---|
class MyComponent : ScriptComponent
{
override void OnPostInit(IEntity owner)
{
SetEventMask(owner, EntityEvent.FRAME);
owner.SetFlags(EntityFlags.ACTIVE);
}
} |
class MyComponent : ScriptComponent
{
override void OnPostInit(IEntity owner)
{
SetEventMask(owner, EntityEvent.FRAME);
}
override void EOnActivate(IEntity owner)
{
super.EOnActivate(owner);
SetEventMask(owner, EntityEvent.FRAME);
}
override void EOnDeactivate(IEntity owner)
{
super.EOnDeactivate(owner);
ClearEventMask(owner, EntityEvent.FRAME);
}
} Advanced example: class MyComponent : ScriptComponent
{
protected bool m_bCustomCondition = false;
void SetCustomCondition()
{
m_bCustomCondition = true;
SetEventMask(owner, EntityEvent.FRAME);
}
override void EOnActivate(IEntity owner)
{
super.EOnActivate(owner);
if (!m_bCustomCondition)
return;
SetEventMask(owner, EntityEvent.FRAME);
}
override void EOnDeactivate(IEntity owner)
{
super.EOnDeactivate(owner);
if (!m_bCustomCondition)
return;
ClearEventMask(owner, EntityEvent.FRAME);
}
} |