Refactor KeyframeMotion to use one timer class per scene

avinationmerge
Melanie 2013-02-11 23:07:04 +01:00
parent 8008938550
commit e31bc8dc96
1 changed files with 75 additions and 20 deletions

View File

@ -22,25 +22,36 @@ using log4net;
namespace OpenSim.Region.Framework.Scenes namespace OpenSim.Region.Framework.Scenes
{ {
public static class KeyframeTimer public class KeyframeTimer
{ {
private static Timer m_timer; private static Dictionary<Scene, KeyframeTimer>m_timers =
private static Dictionary<KeyframeMotion, object> m_motions = new Dictionary<KeyframeMotion, object>(); new Dictionary<Scene, KeyframeTimer>();
private static object m_lockObject = new object();
private static object m_timerLock = new object();
public const double timerInterval = 50.0;
static KeyframeTimer() private Timer m_timer;
private Dictionary<KeyframeMotion, object> m_motions = new Dictionary<KeyframeMotion, object>();
private object m_lockObject = new object();
private object m_timerLock = new object();
private const double m_tickDuration = 50.0;
private Scene m_scene;
public double TickDuration
{
get { return m_tickDuration; }
}
public KeyframeTimer(Scene scene)
{ {
m_timer = new Timer(); m_timer = new Timer();
m_timer.Interval = timerInterval; m_timer.Interval = TickDuration;
m_timer.AutoReset = true; m_timer.AutoReset = true;
m_timer.Elapsed += OnTimer; m_timer.Elapsed += OnTimer;
m_scene = scene;
m_timer.Start(); m_timer.Start();
} }
private static void OnTimer(object sender, ElapsedEventArgs ea) private void OnTimer(object sender, ElapsedEventArgs ea)
{ {
if (!Monitor.TryEnter(m_timerLock)) if (!Monitor.TryEnter(m_timerLock))
return; return;
@ -58,7 +69,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
try try
{ {
m.OnTimer(); m.OnTimer(TickDuration);
} }
catch (Exception inner) catch (Exception inner)
{ {
@ -78,17 +89,44 @@ namespace OpenSim.Region.Framework.Scenes
public static void Add(KeyframeMotion motion) public static void Add(KeyframeMotion motion)
{ {
lock (m_lockObject) KeyframeTimer timer;
if (motion.Scene == null)
return;
lock (m_timers)
{ {
m_motions[motion] = null; if (!m_timers.TryGetValue(motion.Scene, out timer))
{
timer = new KeyframeTimer(motion.Scene);
m_timers[motion.Scene] = timer;
}
}
lock (timer.m_lockObject)
{
timer.m_motions[motion] = null;
} }
} }
public static void Remove(KeyframeMotion motion) public static void Remove(KeyframeMotion motion)
{ {
lock (m_lockObject) KeyframeTimer timer;
if (motion.Scene == null)
return;
lock (m_timers)
{ {
m_motions.Remove(motion); if (!m_timers.TryGetValue(motion.Scene, out timer))
{
return;
}
}
lock (timer.m_lockObject)
{
timer.m_motions.Remove(motion);
} }
} }
} }
@ -156,6 +194,7 @@ namespace OpenSim.Region.Framework.Scenes
private DataFormat m_data = DataFormat.Translation | DataFormat.Rotation; private DataFormat m_data = DataFormat.Translation | DataFormat.Rotation;
private bool m_running = false; private bool m_running = false;
[NonSerialized()] [NonSerialized()]
private bool m_selected = false; private bool m_selected = false;
@ -163,6 +202,14 @@ namespace OpenSim.Region.Framework.Scenes
private int m_skipLoops = 0; private int m_skipLoops = 0;
[NonSerialized()]
private Scene m_scene;
public Scene Scene
{
get { return m_scene; }
}
public DataFormat Data public DataFormat Data
{ {
get { return m_data; } get { return m_data; }
@ -221,8 +268,12 @@ namespace OpenSim.Region.Framework.Scenes
newMotion.m_group = grp; newMotion.m_group = grp;
if (grp != null && grp.IsSelected) if (grp != null)
newMotion.m_selected = true; {
newMotion.m_scene = grp.Scene;
if (grp.IsSelected)
newMotion.m_selected = true;
}
newMotion.m_timerStopped = false; newMotion.m_timerStopped = false;
newMotion.m_isCrossing = false; newMotion.m_isCrossing = false;
@ -246,6 +297,8 @@ namespace OpenSim.Region.Framework.Scenes
return; return;
m_group = grp; m_group = grp;
m_scene = grp.Scene;
Vector3 grppos = grp.AbsolutePosition; Vector3 grppos = grp.AbsolutePosition;
Vector3 offset = grppos - m_serializedPosition; Vector3 offset = grppos - m_serializedPosition;
// avoid doing it more than once // avoid doing it more than once
@ -278,6 +331,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
m_basePosition = grp.AbsolutePosition; m_basePosition = grp.AbsolutePosition;
m_baseRotation = grp.GroupRotation; m_baseRotation = grp.GroupRotation;
m_scene = grp.Scene;
} }
m_timerStopped = true; m_timerStopped = true;
@ -297,6 +351,7 @@ namespace OpenSim.Region.Framework.Scenes
KeyframeMotion newmotion = new KeyframeMotion(null, m_mode, m_data); KeyframeMotion newmotion = new KeyframeMotion(null, m_mode, m_data);
newmotion.m_group = newgrp; newmotion.m_group = newgrp;
newmotion.m_scene = newgrp.Scene;
if (m_keyframes != null) if (m_keyframes != null)
{ {
@ -482,7 +537,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
public void OnTimer() public void OnTimer(double tickDuration)
{ {
if (m_skipLoops > 0) if (m_skipLoops > 0)
{ {
@ -546,16 +601,16 @@ namespace OpenSim.Region.Framework.Scenes
} }
m_currentFrame = m_frames[0]; m_currentFrame = m_frames[0];
m_currentFrame.TimeMS += (int)KeyframeTimer.timerInterval; m_currentFrame.TimeMS += (int)tickDuration;
//force a update on a keyframe transition //force a update on a keyframe transition
update = true; update = true;
} }
m_currentFrame.TimeMS -= (int)KeyframeTimer.timerInterval; m_currentFrame.TimeMS -= (int)tickDuration;
// Do the frame processing // Do the frame processing
double steps = (double)m_currentFrame.TimeMS / KeyframeTimer.timerInterval; double steps = (double)m_currentFrame.TimeMS / tickDuration;
if (steps <= 0.0) if (steps <= 0.0)
{ {