From f7c5eca978717c0adc16ad28b30b02678ba75892 Mon Sep 17 00:00:00 2001 From: Adam Frisby Date: Fri, 21 Aug 2009 15:12:50 +1000 Subject: * Moves NPC Creation across AppDomains to prevent a major perfomance issue. --- .../Region/OptionalModules/World/NPC/NPCModule.cs | 86 +++++++++++++++++----- .../Shared/Api/Implementation/OSSL_Api.cs | 2 + 2 files changed, 70 insertions(+), 18 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index eeb74d9..c710723 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -26,12 +26,14 @@ */ using System.Collections.Generic; +using System.Threading; using OpenMetaverse; using Nini.Config; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.CoreModules.Avatar.NPC; using OpenSim.Framework; +using Timer=System.Timers.Timer; namespace OpenSim.Region.OptionalModules.World.NPC { @@ -39,10 +41,25 @@ namespace OpenSim.Region.OptionalModules.World.NPC { // private const bool m_enabled = false; + private Mutex m_createMutex = new Mutex(false); + + private Timer m_timer = new Timer(500); + private Dictionary m_avatars = new Dictionary(); private Dictionary m_appearanceCache = new Dictionary(); + // Timer vars. + private bool p_inUse = false; + private readonly object p_lock = new object(); + // Private Temporary Variables. + private string p_firstname; + private string p_lastname; + private Vector3 p_position; + private Scene p_scene; + private UUID p_cloneAppearanceFrom; + private UUID p_returnUuid; + private AvatarAppearance GetAppearance(UUID target, Scene scene) { if (m_appearanceCache.ContainsKey(target)) @@ -57,29 +74,23 @@ namespace OpenSim.Region.OptionalModules.World.NPC public UUID CreateNPC(string firstname, string lastname,Vector3 position, Scene scene, UUID cloneAppearanceFrom) { - NPCAvatar npcAvatar = new NPCAvatar(firstname, lastname, position, scene); - npcAvatar.CircuitCode = (uint) Util.RandomClass.Next(0, int.MaxValue); - - scene.ClientManager.Add(npcAvatar.CircuitCode, npcAvatar); - scene.AddNewClient(npcAvatar); + // Block. + m_createMutex.WaitOne(); - ScenePresence sp; - if(scene.TryGetAvatar(npcAvatar.AgentId, out sp)) + // Copy Temp Variables for Timer to pick up. + lock (p_lock) { - AvatarAppearance x = GetAppearance(cloneAppearanceFrom, scene); - - List wearbyte = new List(); - for (int i = 0; i < x.VisualParams.Length; i++) - { - wearbyte.Add(x.VisualParams[i]); - } - - sp.SetAppearance(x.Texture.GetBytes(), wearbyte); + p_firstname = firstname; + p_lastname = lastname; + p_position = position; + p_scene = scene; + p_cloneAppearanceFrom = cloneAppearanceFrom; + p_inUse = true; } - m_avatars.Add(npcAvatar.AgentId, npcAvatar); + m_createMutex.ReleaseMutex(); - return npcAvatar.AgentId; + return p_returnUuid; } public void Autopilot(UUID agentID, Scene scene, Vector3 pos) @@ -116,6 +127,45 @@ namespace OpenSim.Region.OptionalModules.World.NPC public void Initialise(Scene scene, IConfigSource source) { scene.RegisterModuleInterface(this); + + m_timer.Elapsed += m_timer_Elapsed; + m_timer.Start(); + } + + void m_timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) + { + lock (p_lock) + { + if (p_inUse) + { + p_inUse = false; + + + NPCAvatar npcAvatar = new NPCAvatar(p_firstname, p_lastname, p_position, p_scene); + npcAvatar.CircuitCode = (uint) Util.RandomClass.Next(0, int.MaxValue); + + p_scene.ClientManager.Add(npcAvatar.CircuitCode, npcAvatar); + p_scene.AddNewClient(npcAvatar); + + ScenePresence sp; + if (p_scene.TryGetAvatar(npcAvatar.AgentId, out sp)) + { + AvatarAppearance x = GetAppearance(p_cloneAppearanceFrom, p_scene); + + List wearbyte = new List(); + for (int i = 0; i < x.VisualParams.Length; i++) + { + wearbyte.Add(x.VisualParams[i]); + } + + sp.SetAppearance(x.Texture.GetBytes(), wearbyte); + } + + m_avatars.Add(npcAvatar.AgentId, npcAvatar); + + p_returnUuid = npcAvatar.AgentId; + } + } } public void PostInitialise() diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index fcfa9fc..6190349 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -31,6 +31,7 @@ using System.Collections.Generic; using System.Runtime.Remoting.Lifetime; using System.Text; using System.Net; +using System.Threading; using OpenMetaverse; using Nini.Config; using OpenSim; @@ -1766,6 +1767,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, LSL_Key cloneFrom) { CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); + //QueueUserWorkItem INPCModule module = World.RequestModuleInterface(); if (module != null) -- cgit v1.1 From bd7757de22ee07b344b470eadbf55264dfb8ec1b Mon Sep 17 00:00:00 2001 From: Adam Frisby Date: Fri, 21 Aug 2009 15:15:15 +1000 Subject: * oops. Mistake with value return. --- OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index c710723..a43a5f5 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -86,6 +86,12 @@ namespace OpenSim.Region.OptionalModules.World.NPC p_scene = scene; p_cloneAppearanceFrom = cloneAppearanceFrom; p_inUse = true; + p_returnUuid = UUID.Zero; + } + + while(p_returnUuid == UUID.Zero) + { + Thread.Sleep(250); } m_createMutex.ReleaseMutex(); -- cgit v1.1