forked from mirrors/0ad
Dynamic message subscriptions.
Allow components to individually subscribe/unsubscribe to messages, instead of statically subscribing the entire component type. Use this for most Interpolate/RenderSubmit messages, to avoid the performance cost of passing those messages to a large number of components that will just ignore them anyway. On Azure Coast this reduces total time per frame by about 30% on a CPU-bound system. This was SVN commit r15400.
This commit is contained in:
@@ -44,7 +44,6 @@ public:
|
||||
static void ClassInit(CComponentManager& componentManager)
|
||||
{
|
||||
componentManager.SubscribeToMessageType(MT_TurnStart);
|
||||
componentManager.SubscribeToMessageType(MT_Interpolate);
|
||||
componentManager.SubscribeToMessageType(MT_TerrainChanged);
|
||||
componentManager.SubscribeToMessageType(MT_WaterChanged);
|
||||
componentManager.SubscribeToMessageType(MT_Deserialized);
|
||||
@@ -97,6 +96,8 @@ public:
|
||||
float m_LastInterpolatedRotX, m_LastInterpolatedRotZ;
|
||||
bool m_ActorFloating;
|
||||
|
||||
bool m_EnabledMessageInterpolate;
|
||||
|
||||
static std::string GetSchema()
|
||||
{
|
||||
return
|
||||
@@ -156,6 +157,8 @@ public:
|
||||
m_TurretPosition = CFixedVector3D();
|
||||
|
||||
m_ActorFloating = false;
|
||||
|
||||
m_EnabledMessageInterpolate = false;
|
||||
}
|
||||
|
||||
virtual void Deinit()
|
||||
@@ -252,6 +255,8 @@ public:
|
||||
|
||||
if (m_InWorld)
|
||||
UpdateXZRotation();
|
||||
|
||||
UpdateMessageSubscriptions();
|
||||
}
|
||||
|
||||
void Deserialized()
|
||||
@@ -528,6 +533,7 @@ public:
|
||||
m_RotY = y;
|
||||
|
||||
AdvertisePositionChanges();
|
||||
UpdateMessageSubscriptions();
|
||||
}
|
||||
|
||||
virtual void SetYRotation(entity_angle_t y)
|
||||
@@ -550,6 +556,7 @@ public:
|
||||
}
|
||||
|
||||
AdvertisePositionChanges();
|
||||
UpdateMessageSubscriptions();
|
||||
}
|
||||
|
||||
virtual void SetXZRotation(entity_angle_t x, entity_angle_t z)
|
||||
@@ -751,6 +758,8 @@ public:
|
||||
{
|
||||
case MT_Interpolate:
|
||||
{
|
||||
PROFILE3("Position::Interpolate");
|
||||
|
||||
const CMessageInterpolate& msgData = static_cast<const CMessageInterpolate&> (msg);
|
||||
|
||||
float rotY = m_RotY.ToFloat();
|
||||
@@ -776,6 +785,8 @@ public:
|
||||
|
||||
UpdateXZRotation();
|
||||
}
|
||||
|
||||
UpdateMessageSubscriptions();
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -837,6 +848,25 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
/*
|
||||
* Must be called whenever m_RotY or m_InterpolatedRotY change,
|
||||
* to determine whether we need to call Interpolate to make the unit rotate.
|
||||
*/
|
||||
void UpdateMessageSubscriptions()
|
||||
{
|
||||
bool needInterpolate = false;
|
||||
|
||||
float rotY = m_RotY.ToFloat();
|
||||
if (rotY != m_InterpolatedRotY)
|
||||
needInterpolate = true;
|
||||
|
||||
if (needInterpolate != m_EnabledMessageInterpolate)
|
||||
{
|
||||
GetSimContext().GetComponentManager().DynamicSubscriptionNonsync(MT_Interpolate, this, needInterpolate);
|
||||
m_EnabledMessageInterpolate = needInterpolate;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This must be called after changing anything that will affect the
|
||||
* return value of GetPosition2D() or GetRotation().Y:
|
||||
|
||||
Reference in New Issue
Block a user