diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs index 6b169bde33..dc4de8ef59 100644 --- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs +++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs @@ -1077,7 +1077,7 @@ namespace OpenSim.Client.MXP.ClientStack throw new System.NotImplementedException(); } - public void ReprioritizeUpdates(UpdatePriorityHandler handler) + public void ReprioritizeUpdates() { } diff --git a/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs b/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs index 181606bf4a..3f3166a461 100644 --- a/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs +++ b/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs @@ -618,7 +618,7 @@ namespace OpenSim.Client.Sirikata.ClientStack throw new System.NotImplementedException(); } - public void ReprioritizeUpdates(UpdatePriorityHandler handler) + public void ReprioritizeUpdates() { throw new System.NotImplementedException(); } diff --git a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs index febdd1b6f7..11eed0959d 100644 --- a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs +++ b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs @@ -624,7 +624,7 @@ namespace OpenSim.Client.VWoHTTP.ClientStack throw new System.NotImplementedException(); } - public void ReprioritizeUpdates(UpdatePriorityHandler handler) + public void ReprioritizeUpdates() { throw new System.NotImplementedException(); } diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 562d69e0c8..96223fff39 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -458,8 +458,6 @@ namespace OpenSim.Framework public delegate void PlacesQuery(UUID QueryID, UUID TransactionID, string QueryText, uint QueryFlags, byte Category, string SimName, IClientAPI client); public delegate void AgentFOV(IClientAPI client, float verticalAngle); - - public delegate double UpdatePriorityHandler(UpdatePriorityData data); public delegate void MuteListEntryUpdate(IClientAPI client, UUID MuteID, string Name, int Flags,UUID AgentID); @@ -571,17 +569,16 @@ namespace OpenSim.Framework public float dwell; } - public struct UpdatePriorityData { - private double m_priority; - private uint m_localID; + public class EntityUpdate + { + public ISceneEntity Entity; + public PrimUpdateFlags Flags; - public UpdatePriorityData(double priority, uint localID) { - this.m_priority = priority; - this.m_localID = localID; + public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags) + { + Entity = entity; + Flags = flags; } - - public double priority { get { return this.m_priority; } } - public uint localID { get { return this.m_localID; } } } /// @@ -1026,7 +1023,7 @@ namespace OpenSim.Framework void SendAvatarDataImmediate(ISceneEntity avatar); void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags); - void ReprioritizeUpdates(UpdatePriorityHandler handler); + void ReprioritizeUpdates(); void FlushPrimUpdates(); void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List items, diff --git a/OpenSim/Framework/ISceneEntity.cs b/OpenSim/Framework/ISceneEntity.cs index fa3c514667..5ac364f994 100644 --- a/OpenSim/Framework/ISceneEntity.cs +++ b/OpenSim/Framework/ISceneEntity.cs @@ -33,5 +33,6 @@ namespace OpenSim.Framework { UUID UUID { get; } uint LocalId { get; } + Vector3 AbsolutePosition { get; } } } diff --git a/OpenSim/Framework/Serialization/ArchiveConstants.cs b/OpenSim/Framework/Serialization/ArchiveConstants.cs index 1cd80db24d..475a9de0cb 100644 --- a/OpenSim/Framework/Serialization/ArchiveConstants.cs +++ b/OpenSim/Framework/Serialization/ArchiveConstants.cs @@ -25,6 +25,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System; using System.Collections.Generic; using OpenMetaverse; @@ -85,6 +86,11 @@ namespace OpenSim.Framework.Serialization /// public const string INVENTORY_NODE_NAME_COMPONENT_SEPARATOR = "__"; + /// + /// Template used for creating filenames in OpenSim Archives. + /// + public const string OAR_OBJECT_FILENAME_TEMPLATE = "{0}_{1:000}-{2:000}-{3:000}__{4}.xml"; + /// /// Extensions used for asset types in the archive /// @@ -139,5 +145,32 @@ namespace OpenSim.Framework.Serialization EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "texture.tga"] = (sbyte)AssetType.TextureTGA; EXTENSION_TO_ASSET_TYPE[ASSET_EXTENSION_SEPARATOR + "trashfolder.txt"] = (sbyte)AssetType.TrashFolder; } + + /// + /// Create the filename used to store an object in an OpenSim Archive. + /// + /// + /// + /// + /// + public static string CreateOarObjectFilename(string objectName, UUID uuid, Vector3 pos) + { + return string.Format( + OAR_OBJECT_FILENAME_TEMPLATE, objectName, + Math.Round(pos.X), Math.Round(pos.Y), Math.Round(pos.Z), + uuid); + } + + /// + /// Create the path used to store an object in an OpenSim Archives. + /// + /// + /// + /// + /// + public static string CreateOarObjectPath(string objectName, UUID uuid, Vector3 pos) + { + return OBJECTS_PATH + CreateOarObjectFilename(objectName, uuid, pos); + } } } diff --git a/OpenSim/Framework/Serialization/TarArchiveWriter.cs b/OpenSim/Framework/Serialization/TarArchiveWriter.cs index 0bd639ff3a..fca909f2d8 100644 --- a/OpenSim/Framework/Serialization/TarArchiveWriter.cs +++ b/OpenSim/Framework/Serialization/TarArchiveWriter.cs @@ -28,7 +28,9 @@ using System; using System.Collections.Generic; using System.IO; +using System.Reflection; using System.Text; +using log4net; namespace OpenSim.Framework.Serialization { @@ -37,7 +39,7 @@ namespace OpenSim.Framework.Serialization /// public class TarArchiveWriter { - //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); protected static ASCIIEncoding m_asciiEncoding = new ASCIIEncoding(); protected static UTF8Encoding m_utf8Encoding = new UTF8Encoding(); @@ -148,6 +150,9 @@ namespace OpenSim.Framework.Serialization /// protected void WriteEntry(string filePath, byte[] data, char fileType) { +// m_log.DebugFormat( +// "[TAR ARCHIVE WRITER]: Data for {0} is {1} bytes", filePath, (null == data ? "null" : data.Length.ToString())); + byte[] header = new byte[512]; // file path field (100) diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index b2a80bec29..3888a0b585 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -50,18 +50,6 @@ using Nini.Config; namespace OpenSim.Region.ClientStack.LindenUDP { - public class EntityUpdate - { - public ISceneEntity Entity; - public PrimUpdateFlags Flags; - - public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags) - { - Entity = entity; - Flags = flags; - } - } - public delegate bool PacketMethod(IClientAPI simClient, Packet packet); /// @@ -325,6 +313,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP private int m_cachedTextureSerial; private PriorityQueue m_entityUpdates; + private Prioritizer m_prioritizer; /// /// List used in construction of data blocks for an object update packet. This is to stop us having to @@ -465,6 +454,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_propertiesPacketTimer = new Timer(100); m_propertiesPacketTimer.Elapsed += ProcessObjectPropertiesPacket; + m_prioritizer = new Prioritizer(m_scene); + RegisterLocalPacketHandlers(); } @@ -3457,14 +3448,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) { - double priority; - - if (entity is SceneObjectPart) - priority = ((SceneObjectPart)entity).ParentGroup.GetUpdatePriority(this); - else if (entity is ScenePresence) - priority = ((ScenePresence)entity).GetUpdatePriority(this); - else - priority = 0.0d; + double priority = m_prioritizer.GetUpdatePriority(this, entity); lock (m_entityUpdates.SyncRoot) m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags), entity.LocalId); @@ -3613,19 +3597,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion Packet Sending } - public void ReprioritizeUpdates(UpdatePriorityHandler handler) + public void ReprioritizeUpdates() { //m_log.Debug("[CLIENT]: Reprioritizing prim updates for " + m_firstName + " " + m_lastName); - PriorityQueue.UpdatePriorityHandler update_priority_handler = - delegate(ref double priority, uint local_id) - { - priority = handler(new UpdatePriorityData(priority, local_id)); - return priority != double.NaN; - }; - lock (m_entityUpdates.SyncRoot) - m_entityUpdates.Reprioritize(update_priority_handler); + m_entityUpdates.Reprioritize(UpdatePriorityHandler); + } + + private bool UpdatePriorityHandler(ref double priority, uint localID) + { + EntityBase entity; + if (m_scene.Entities.TryGetValue(localID, out entity)) + { + priority = m_prioritizer.GetUpdatePriority(this, entity); + } + + return priority != double.NaN; } public void FlushPrimUpdates() diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveHelpers.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveHelpers.cs new file mode 100644 index 0000000000..880bd7cdd4 --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveHelpers.cs @@ -0,0 +1,64 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using OpenMetaverse; +using OpenSim.Framework.Serialization; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.CoreModules.World.Archiver +{ + /// + /// Helper methods for archive manipulation + /// + /// This is a separate class from ArchiveConstants because we need to bring in very OpenSim specific classes. + public static class ArchiveHelpers + { + /// + /// Create the filename used for objects in OpenSim Archives. + /// + /// + /// + /// + /// + public static string CreateObjectFilename(SceneObjectGroup sog) + { + return ArchiveConstants.CreateOarObjectFilename(sog.Name, sog.UUID, sog.AbsolutePosition); + } + + /// + /// Create the path used to store an object in an OpenSim Archive. + /// + /// + /// + /// + /// + public static string CreateObjectPath(SceneObjectGroup sog) + { + return ArchiveConstants.CreateOarObjectPath(sog.Name, sog.UUID, sog.AbsolutePosition); + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index b37beabfdf..9c8193add0 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs @@ -38,7 +38,6 @@ using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Serialization; using OpenSim.Framework.Serialization.External; - using OpenSim.Region.CoreModules.World.Terrain; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; @@ -244,7 +243,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver // to the same scene (when this is possible). sceneObject.ResetIDs(); - foreach (SceneObjectPart part in sceneObject.Children.Values) { if (!ResolveUserUuid(part.CreatorID)) diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs index 9fc6ec47c2..586d98e322 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs @@ -145,17 +145,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver { //m_log.DebugFormat("[ARCHIVER]: Saving {0} {1}, {2}", entity.Name, entity.UUID, entity.GetType()); - Vector3 position = sceneObject.AbsolutePosition; - string serializedObject = m_serialiser.SerializeGroupToXml2(sceneObject); - string filename - = string.Format( - "{0}{1}_{2:000}-{3:000}-{4:000}__{5}.xml", - ArchiveConstants.OBJECTS_PATH, sceneObject.Name, - Math.Round(position.X), Math.Round(position.Y), Math.Round(position.Z), - sceneObject.UUID); - - m_archiveWriter.WriteFile(filename, serializedObject); + m_archiveWriter.WriteFile(ArchiveHelpers.CreateObjectPath(sceneObject), serializedObject); } m_log.InfoFormat("[ARCHIVER]: Added scene objects to archive."); diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs index 4215f97343..a1451ce705 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs @@ -239,7 +239,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver if (asset != null) { -// m_log.DebugFormat("[ARCHIVER]: Recording asset {0} as found", id); +// m_log.DebugFormat("[ARCHIVER]: Writing asset {0}", id); m_foundAssetUuids.Add(asset.FullID); m_assetsArchiver.WriteAsset(asset); } diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs index 624dc22044..4d04af16e7 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs @@ -26,6 +26,7 @@ */ using System; +using System.Collections.Generic; using System.IO; using System.Reflection; using System.Threading; @@ -33,8 +34,8 @@ using log4net.Config; using NUnit.Framework; using NUnit.Framework.SyntaxHelpers; using OpenMetaverse; +using OpenMetaverse.Assets; using OpenSim.Framework; - using OpenSim.Framework.Serialization; using OpenSim.Framework.Serialization.External; using OpenSim.Region.CoreModules.World.Serialiser; @@ -44,6 +45,9 @@ using OpenSim.Region.Framework.Scenes.Serialization; using OpenSim.Tests.Common; using OpenSim.Tests.Common.Mock; using OpenSim.Tests.Common.Setup; +using ArchiveConstants = OpenSim.Framework.Serialization.ArchiveConstants; +using TarArchiveReader = OpenSim.Framework.Serialization.TarArchiveReader; +using TarArchiveWriter = OpenSim.Framework.Serialization.TarArchiveWriter; namespace OpenSim.Region.CoreModules.World.Archiver.Tests { @@ -55,6 +59,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests protected TestScene m_scene; protected ArchiverModule m_archiverModule; + + protected TaskInventoryItem m_soundItem; [SetUp] public void SetUp() @@ -124,10 +130,23 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests //log4net.Config.XmlConfigurator.Configure(); SceneObjectPart part1 = CreateSceneObjectPart1(); - m_scene.AddNewSceneObject(new SceneObjectGroup(part1), false); + SceneObjectGroup sog1 = new SceneObjectGroup(part1); + m_scene.AddNewSceneObject(sog1, false); SceneObjectPart part2 = CreateSceneObjectPart2(); - m_scene.AddNewSceneObject(new SceneObjectGroup(part2), false); + + AssetNotecard nc = new AssetNotecard("Hello World!"); + UUID ncAssetUuid = new UUID("00000000-0000-0000-1000-000000000000"); + UUID ncItemUuid = new UUID("00000000-0000-0000-1100-000000000000"); + AssetBase ncAsset + = AssetHelpers.CreateAsset(ncAssetUuid, AssetType.Notecard, nc.AssetData, UUID.Zero); + m_scene.AssetService.Store(ncAsset); + SceneObjectGroup sog2 = new SceneObjectGroup(part2); + TaskInventoryItem ncItem + = new TaskInventoryItem { Name = "ncItem", AssetID = ncAssetUuid, ItemID = ncItemUuid }; + part2.Inventory.AddInventoryItem(ncItem, true); + + m_scene.AddNewSceneObject(sog2, false); MemoryStream archiveWriteStream = new MemoryStream(); m_scene.EventManager.OnOarFileSaved += SaveCompleted; @@ -151,18 +170,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests TarArchiveReader tar = new TarArchiveReader(archiveReadStream); bool gotControlFile = false; - bool gotObject1File = false; - bool gotObject2File = false; - string expectedObject1FileName = string.Format( - "{0}_{1:000}-{2:000}-{3:000}__{4}.xml", - part1.Name, - Math.Round(part1.GroupPosition.X), Math.Round(part1.GroupPosition.Y), Math.Round(part1.GroupPosition.Z), - part1.UUID); - string expectedObject2FileName = string.Format( - "{0}_{1:000}-{2:000}-{3:000}__{4}.xml", - part2.Name, - Math.Round(part2.GroupPosition.X), Math.Round(part2.GroupPosition.Y), Math.Round(part2.GroupPosition.Z), - part2.UUID); + bool gotNcAssetFile = false; + + string expectedNcAssetFileName = string.Format("{0}_{1}", ncAssetUuid, "notecard.txt"); + + List foundPaths = new List(); + List expectedPaths = new List(); + expectedPaths.Add(ArchiveHelpers.CreateObjectPath(sog1)); + expectedPaths.Add(ArchiveHelpers.CreateObjectPath(sog2)); string filePath; TarArchiveReader.TarEntryType tarEntryType; @@ -173,26 +188,22 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests { gotControlFile = true; } + else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH)) + { + string fileName = filePath.Remove(0, ArchiveConstants.ASSETS_PATH.Length); + + Assert.That(fileName, Is.EqualTo(expectedNcAssetFileName)); + gotNcAssetFile = true; + } else if (filePath.StartsWith(ArchiveConstants.OBJECTS_PATH)) { - string fileName = filePath.Remove(0, ArchiveConstants.OBJECTS_PATH.Length); - - if (fileName.StartsWith(part1.Name)) - { - Assert.That(fileName, Is.EqualTo(expectedObject1FileName)); - gotObject1File = true; - } - else if (fileName.StartsWith(part2.Name)) - { - Assert.That(fileName, Is.EqualTo(expectedObject2FileName)); - gotObject2File = true; - } + foundPaths.Add(filePath); } } Assert.That(gotControlFile, Is.True, "No control file in archive"); - Assert.That(gotObject1File, Is.True, "No object1 file in archive"); - Assert.That(gotObject2File, Is.True, "No object2 file in archive"); + Assert.That(gotNcAssetFile, Is.True, "No notecard asset file in archive"); + Assert.That(foundPaths, Is.EquivalentTo(expectedPaths)); // TODO: Test presence of more files and contents of files. } diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index b6b25eaae2..4bbe9df5d2 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs @@ -548,7 +548,7 @@ namespace OpenSim.Region.Examples.SimpleModule { } - public void ReprioritizeUpdates(UpdatePriorityHandler handler) + public void ReprioritizeUpdates() { } diff --git a/OpenSim/Region/Framework/Scenes/EntityBase.cs b/OpenSim/Region/Framework/Scenes/EntityBase.cs index 1c76c546e5..4e25c468c0 100644 --- a/OpenSim/Region/Framework/Scenes/EntityBase.cs +++ b/OpenSim/Region/Framework/Scenes/EntityBase.cs @@ -28,11 +28,12 @@ using System; using System.Runtime.Serialization; using System.Security.Permissions; +using OpenSim.Framework; using OpenMetaverse; namespace OpenSim.Region.Framework.Scenes { - public abstract class EntityBase + public abstract class EntityBase : ISceneEntity { /// /// The scene to which this entity belongs diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs new file mode 100644 index 0000000000..1eb0c286e8 --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs @@ -0,0 +1,191 @@ +using System; +using System.Collections.Generic; +using log4net; +using Nini.Config; +using OpenSim.Framework; +using OpenMetaverse; +using OpenSim.Region.Physics.Manager; + +/* + * Steps to add a new prioritization policy: + * + * - Add a new value to the UpdatePrioritizationSchemes enum. + * - Specify this new value in the [InterestManagement] section of your + * OpenSim.ini. The name in the config file must match the enum value name + * (although it is not case sensitive). + * - Write a new GetPriorityBy*() method in this class. + * - Add a new entry to the switch statement in GetUpdatePriority() that calls + * your method. + */ + +namespace OpenSim.Region.Framework.Scenes +{ + public enum UpdatePrioritizationSchemes + { + Time = 0, + Distance = 1, + SimpleAngularDistance = 2, + FrontBack = 3, + BestAvatarResponsiveness = 4, + } + + public class Prioritizer + { + private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + private Scene m_scene; + + public Prioritizer(Scene scene) + { + m_scene = scene; + } + + public double GetUpdatePriority(IClientAPI client, ISceneEntity entity) + { + switch (m_scene.UpdatePrioritizationScheme) + { + case UpdatePrioritizationSchemes.Time: + return GetPriorityByTime(); + case UpdatePrioritizationSchemes.Distance: + return GetPriorityByDistance(client, entity); + case UpdatePrioritizationSchemes.SimpleAngularDistance: + return GetPriorityByDistance(client, entity); // TODO: Reimplement SimpleAngularDistance + case UpdatePrioritizationSchemes.FrontBack: + return GetPriorityByFrontBack(client, entity); + case UpdatePrioritizationSchemes.BestAvatarResponsiveness: + return GetPriorityByBestAvatarResponsiveness(client, entity); + default: + throw new InvalidOperationException("UpdatePrioritizationScheme not defined."); + } + } + + private double GetPriorityByTime() + { + return DateTime.UtcNow.ToOADate(); + } + + private double GetPriorityByDistance(IClientAPI client, ISceneEntity entity) + { + ScenePresence presence = m_scene.GetScenePresence(client.AgentId); + if (presence != null) + { + // If this is an update for our own avatar give it the highest priority + if (presence == entity) + return 0.0; + + // Use the camera position for local agents and avatar position for remote agents + Vector3 presencePos = (presence.IsChildAgent) ? + presence.AbsolutePosition : + presence.CameraPosition; + + // Use group position for child prims + Vector3 entityPos; + if (entity is SceneObjectPart) + entityPos = m_scene.GetGroupByPrim(entity.LocalId).AbsolutePosition; + else + entityPos = entity.AbsolutePosition; + + return Vector3.DistanceSquared(presencePos, entityPos); + } + + return double.NaN; + } + + private double GetPriorityByFrontBack(IClientAPI client, ISceneEntity entity) + { + ScenePresence presence = m_scene.GetScenePresence(client.AgentId); + if (presence != null) + { + // If this is an update for our own avatar give it the highest priority + if (presence == entity) + return 0.0; + + // Use group position for child prims + Vector3 entityPos = entity.AbsolutePosition; + if (entity is SceneObjectPart) + entityPos = m_scene.GetGroupByPrim(entity.LocalId).AbsolutePosition; + else + entityPos = entity.AbsolutePosition; + + if (!presence.IsChildAgent) + { + // Root agent. Use distance from camera and a priority decrease for objects behind us + Vector3 camPosition = presence.CameraPosition; + Vector3 camAtAxis = presence.CameraAtAxis; + + // Distance + double priority = Vector3.DistanceSquared(camPosition, entityPos); + + // Plane equation + float d = -Vector3.Dot(camPosition, camAtAxis); + float p = Vector3.Dot(camAtAxis, entityPos) + d; + if (p < 0.0f) priority *= 2.0; + + return priority; + } + else + { + // Child agent. Use the normal distance method + Vector3 presencePos = presence.AbsolutePosition; + + return Vector3.DistanceSquared(presencePos, entityPos); + } + } + + return double.NaN; + } + + private double GetPriorityByBestAvatarResponsiveness(IClientAPI client, ISceneEntity entity) + { + ScenePresence presence = m_scene.GetScenePresence(client.AgentId); + if (presence != null) + { + // If this is an update for our own avatar give it the highest priority + if (presence == entity) + return 0.0; + + // Use group position for child prims + Vector3 entityPos = entity.AbsolutePosition; + if (entity is SceneObjectPart) + entityPos = m_scene.GetGroupByPrim(entity.LocalId).AbsolutePosition; + else + entityPos = entity.AbsolutePosition; + + if (!presence.IsChildAgent) + { + if (entity is ScenePresence) + return 1.0; + + // Root agent. Use distance from camera and a priority decrease for objects behind us + Vector3 camPosition = presence.CameraPosition; + Vector3 camAtAxis = presence.CameraAtAxis; + + // Distance + double priority = Vector3.DistanceSquared(camPosition, entityPos); + + // Plane equation + float d = -Vector3.Dot(camPosition, camAtAxis); + float p = Vector3.Dot(camAtAxis, entityPos) + d; + if (p < 0.0f) priority *= 2.0; + + if (entity is SceneObjectPart) + { + PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor; + if (physActor == null || !physActor.IsPhysical) + priority+=100; + } + return priority; + } + else + { + // Child agent. Use the normal distance method + Vector3 presencePos = presence.AbsolutePosition; + + return Vector3.DistanceSquared(presencePos, entityPos); + } + } + + return double.NaN; + } + } +} diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 377abe3e85..3e20766838 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -58,13 +58,6 @@ namespace OpenSim.Region.Framework.Scenes public partial class Scene : SceneBase { - public enum UpdatePrioritizationSchemes { - Time = 0, - Distance = 1, - SimpleAngularDistance = 2, - FrontBack = 3, - } - public delegate void SynchronizeSceneHandler(Scene scene); public SynchronizeSceneHandler SynchronizeScene = null; @@ -402,12 +395,6 @@ namespace OpenSim.Region.Framework.Scenes private int m_lastUpdate; private bool m_firstHeartbeat = true; - private UpdatePrioritizationSchemes m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; - private bool m_reprioritization_enabled = true; - private double m_reprioritization_interval = 5000.0; - private double m_root_reprioritization_distance = 10.0; - private double m_child_reprioritization_distance = 20.0; - private object m_deleting_scene_object = new object(); // the minimum time that must elapse before a changed object will be considered for persisted @@ -415,15 +402,21 @@ namespace OpenSim.Region.Framework.Scenes // the maximum time that must elapse before a changed object will be considered for persisted public long m_persistAfter = DEFAULT_MAX_TIME_FOR_PERSISTENCE * 10000000L; + private UpdatePrioritizationSchemes m_priorityScheme = UpdatePrioritizationSchemes.Time; + private bool m_reprioritizationEnabled = true; + private double m_reprioritizationInterval = 5000.0; + private double m_rootReprioritizationDistance = 10.0; + private double m_childReprioritizationDistance = 20.0; + #endregion #region Properties - public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return this.m_update_prioritization_scheme; } } - public bool IsReprioritizationEnabled { get { return m_reprioritization_enabled; } } - public double ReprioritizationInterval { get { return m_reprioritization_interval; } } - public double RootReprioritizationDistance { get { return m_root_reprioritization_distance; } } - public double ChildReprioritizationDistance { get { return m_child_reprioritization_distance; } } + public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return m_priorityScheme; } } + public bool IsReprioritizationEnabled { get { return m_reprioritizationEnabled; } } + public double ReprioritizationInterval { get { return m_reprioritizationInterval; } } + public double RootReprioritizationDistance { get { return m_rootReprioritizationDistance; } } + public double ChildReprioritizationDistance { get { return m_childReprioritizationDistance; } } public AgentCircuitManager AuthenticateHandler { @@ -625,6 +618,8 @@ namespace OpenSim.Region.Framework.Scenes m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this); m_asyncSceneObjectDeleter.Enabled = true; + #region Region Settings + // Load region settings m_regInfo.RegionSettings = m_storageManager.DataStore.LoadRegionSettings(m_regInfo.RegionID); m_regInfo.WindlightSettings = m_storageManager.DataStore.LoadRegionWindlightSettings(m_regInfo.RegionID); @@ -673,6 +668,8 @@ namespace OpenSim.Region.Framework.Scenes } } + #endregion Region Settings + MainConsole.Instance.Commands.AddCommand("region", false, "reload estate", "reload estate", "Reload the estate data", HandleReloadEstate); @@ -717,6 +714,8 @@ namespace OpenSim.Region.Framework.Scenes m_simulatorVersion = simulatorVersion + " (" + Util.GetRuntimeInformation() + ")"; + #region Region Config + try { // Region config overrides global config @@ -770,38 +769,6 @@ namespace OpenSim.Region.Framework.Scenes m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); - IConfig interest_management_config = m_config.Configs["InterestManagement"]; - if (interest_management_config != null) - { - string update_prioritization_scheme = interest_management_config.GetString("UpdatePrioritizationScheme", "Time").Trim().ToLower(); - switch (update_prioritization_scheme) - { - case "time": - m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; - break; - case "distance": - m_update_prioritization_scheme = UpdatePrioritizationSchemes.Distance; - break; - case "simpleangulardistance": - m_update_prioritization_scheme = UpdatePrioritizationSchemes.SimpleAngularDistance; - break; - case "frontback": - m_update_prioritization_scheme = UpdatePrioritizationSchemes.FrontBack; - break; - default: - m_log.Warn("[SCENE]: UpdatePrioritizationScheme was not recognized, setting to default settomg of Time"); - m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; - break; - } - - m_reprioritization_enabled = interest_management_config.GetBoolean("ReprioritizationEnabled", true); - m_reprioritization_interval = interest_management_config.GetDouble("ReprioritizationInterval", 5000.0); - m_root_reprioritization_distance = interest_management_config.GetDouble("RootReprioritizationDistance", 10.0); - m_child_reprioritization_distance = interest_management_config.GetDouble("ChildReprioritizationDistance", 20.0); - } - - m_log.Info("[SCENE]: Using the " + m_update_prioritization_scheme + " prioritization scheme"); - #region BinaryStats try @@ -838,6 +805,38 @@ namespace OpenSim.Region.Framework.Scenes { m_log.Warn("[SCENE]: Failed to load StartupConfig"); } + + #endregion Region Config + + #region Interest Management + + if (m_config != null) + { + IConfig interestConfig = m_config.Configs["InterestManagement"]; + if (interestConfig != null) + { + string update_prioritization_scheme = interestConfig.GetString("UpdatePrioritizationScheme", "Time").Trim().ToLower(); + + try + { + m_priorityScheme = (UpdatePrioritizationSchemes)Enum.Parse(typeof(UpdatePrioritizationSchemes), update_prioritization_scheme, true); + } + catch (Exception) + { + m_log.Warn("[PRIORITIZER]: UpdatePrioritizationScheme was not recognized, setting to default prioritizer Time"); + m_priorityScheme = UpdatePrioritizationSchemes.Time; + } + + m_reprioritizationEnabled = interestConfig.GetBoolean("ReprioritizationEnabled", true); + m_reprioritizationInterval = interestConfig.GetDouble("ReprioritizationInterval", 5000.0); + m_rootReprioritizationDistance = interestConfig.GetDouble("RootReprioritizationDistance", 10.0); + m_childReprioritizationDistance = interestConfig.GetDouble("ChildReprioritizationDistance", 20.0); + } + } + + m_log.Info("[SCENE]: Using the " + m_priorityScheme + " prioritization scheme"); + + #endregion Interest Management } /// diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 3c2203c0a1..d4658ec873 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -307,61 +307,64 @@ namespace OpenSim.Region.Framework.Scenes if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero) return false; - bool alreadyExisted = false; - - if (m_parentScene.m_clampPrimSize) - { - foreach (SceneObjectPart part in sceneObject.Children.Values) - { - Vector3 scale = part.Shape.Scale; - - if (scale.X > m_parentScene.m_maxNonphys) - scale.X = m_parentScene.m_maxNonphys; - if (scale.Y > m_parentScene.m_maxNonphys) - scale.Y = m_parentScene.m_maxNonphys; - if (scale.Z > m_parentScene.m_maxNonphys) - scale.Z = m_parentScene.m_maxNonphys; - - part.Shape.Scale = scale; - } - } - - sceneObject.AttachToScene(m_parentScene); - - if (sendClientUpdates) - sceneObject.ScheduleGroupForFullUpdate(); - lock (sceneObject) - { - if (!Entities.ContainsKey(sceneObject.UUID)) + { + if (Entities.ContainsKey(sceneObject.UUID)) { - Entities.Add(sceneObject); - m_numPrim += sceneObject.Children.Count; - - if (attachToBackup) - sceneObject.AttachToBackup(); - - if (OnObjectCreate != null) - OnObjectCreate(sceneObject); - - lock (m_dictionary_lock) +// m_log.WarnFormat( +// "[SCENE GRAPH]: Scene object {0} {1} was already in region {2} on add request", +// sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName); + return false; + } + +// m_log.DebugFormat( +// "[SCENE GRAPH]: Adding object {0} {1} to region {2}", +// sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName); + + if (m_parentScene.m_clampPrimSize) + { + foreach (SceneObjectPart part in sceneObject.Children.Values) { - SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; - SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; - foreach (SceneObjectPart part in sceneObject.Children.Values) - { - SceneObjectGroupsByFullID[part.UUID] = sceneObject; - SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; - } + Vector3 scale = part.Shape.Scale; + + if (scale.X > m_parentScene.m_maxNonphys) + scale.X = m_parentScene.m_maxNonphys; + if (scale.Y > m_parentScene.m_maxNonphys) + scale.Y = m_parentScene.m_maxNonphys; + if (scale.Z > m_parentScene.m_maxNonphys) + scale.Z = m_parentScene.m_maxNonphys; + + part.Shape.Scale = scale; } } - else + + sceneObject.AttachToScene(m_parentScene); + + if (sendClientUpdates) + sceneObject.ScheduleGroupForFullUpdate(); + + Entities.Add(sceneObject); + m_numPrim += sceneObject.Children.Count; + + if (attachToBackup) + sceneObject.AttachToBackup(); + + if (OnObjectCreate != null) + OnObjectCreate(sceneObject); + + lock (m_dictionary_lock) { - alreadyExisted = true; + SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; + SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; + foreach (SceneObjectPart part in sceneObject.Children.Values) + { + SceneObjectGroupsByFullID[part.UUID] = sceneObject; + SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; + } } } - return alreadyExisted; + return true; } /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index a4b8944b13..cee2be3a87 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -3841,107 +3841,6 @@ namespace OpenSim.Region.Framework.Scenes SetFromItemID(uuid); } - #endregion - - public double GetUpdatePriority(IClientAPI client) - { - switch (Scene.UpdatePrioritizationScheme) - { - case Scene.UpdatePrioritizationSchemes.Time: - return GetPriorityByTime(); - case Scene.UpdatePrioritizationSchemes.Distance: - return GetPriorityByDistance(client); - case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance: - return GetPriorityBySimpleAngularDistance(client); - case Scenes.Scene.UpdatePrioritizationSchemes.FrontBack: - return GetPriorityByFrontBack(client); - default: - throw new InvalidOperationException("UpdatePrioritizationScheme not defined"); - } - } - - private double GetPriorityByTime() - { - return DateTime.Now.ToOADate(); - } - - private double GetPriorityByDistance(IClientAPI client) - { - ScenePresence presence = Scene.GetScenePresence(client.AgentId); - if (presence != null) - { - return GetPriorityByDistance((presence.IsChildAgent) ? - presence.AbsolutePosition : presence.CameraPosition); - } - return double.NaN; - } - - private double GetPriorityBySimpleAngularDistance(IClientAPI client) - { - ScenePresence presence = Scene.GetScenePresence(client.AgentId); - if (presence != null) - { - return GetPriorityBySimpleAngularDistance((presence.IsChildAgent) ? - presence.AbsolutePosition : presence.CameraPosition); - } - return double.NaN; - } - - private double GetPriorityByFrontBack(IClientAPI client) - { - ScenePresence presence = Scene.GetScenePresence(client.AgentId); - if (presence != null) - { - return GetPriorityByFrontBack(presence.CameraPosition, presence.CameraAtAxis); - } - return double.NaN; - } - - public double GetPriorityByDistance(Vector3 position) - { - return Vector3.Distance(AbsolutePosition, position); - } - - public double GetPriorityBySimpleAngularDistance(Vector3 position) - { - double distance = Vector3.Distance(position, AbsolutePosition); - if (distance >= double.Epsilon) - { - float height; - Vector3 box = GetAxisAlignedBoundingBox(out height); - - double angle = box.X / distance; - double max = angle; - - angle = box.Y / distance; - if (max < angle) - max = angle; - - angle = box.Z / distance; - if (max < angle) - max = angle; - - return -max; - } - else - return double.MinValue; - } - - public double GetPriorityByFrontBack(Vector3 camPosition, Vector3 camAtAxis) - { - // Distance - double priority = Vector3.Distance(camPosition, AbsolutePosition); - - // Scale - //priority -= GroupScale().Length(); - - // Plane equation - float d = -Vector3.Dot(camPosition, camAtAxis); - float p = Vector3.Dot(camAtAxis, AbsolutePosition) + d; - if (p < 0.0f) priority *= 2.0f; - - return priority; - } public void ResetOwnerChangeFlag() { @@ -3950,5 +3849,7 @@ namespace OpenSim.Region.Framework.Scenes part.ResetOwnerChangeFlag(); }); } + + #endregion } } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 179ecdc320..c45fc0ff34 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -4090,123 +4090,9 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos); } } - public double GetUpdatePriority(IClientAPI client) - { - switch (Scene.UpdatePrioritizationScheme) - { - case Scene.UpdatePrioritizationSchemes.Time: - return GetPriorityByTime(); - case Scene.UpdatePrioritizationSchemes.Distance: - return GetPriorityByDistance(client); - case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance: - return GetPriorityByDistance(client); - case Scenes.Scene.UpdatePrioritizationSchemes.FrontBack: - return GetPriorityByFrontBack(client); - default: - throw new InvalidOperationException("UpdatePrioritizationScheme not defined."); - } - } - - private double GetPriorityByTime() - { - return DateTime.Now.ToOADate(); - } - - private double GetPriorityByDistance(IClientAPI client) - { - ScenePresence presence = Scene.GetScenePresence(client.AgentId); - if (presence != null) - { - return GetPriorityByDistance((presence.IsChildAgent) ? - presence.AbsolutePosition : presence.CameraPosition); - } - return double.NaN; - } - - private double GetPriorityByFrontBack(IClientAPI client) - { - ScenePresence presence = Scene.GetScenePresence(client.AgentId); - if (presence != null) - { - return GetPriorityByFrontBack(presence.CameraPosition, presence.CameraAtAxis); - } - return double.NaN; - } - - private double GetPriorityByDistance(Vector3 position) - { - return Vector3.Distance(AbsolutePosition, position); - } - - private double GetPriorityByFrontBack(Vector3 camPosition, Vector3 camAtAxis) - { - // Distance - double priority = Vector3.Distance(camPosition, AbsolutePosition); - - // Plane equation - float d = -Vector3.Dot(camPosition, camAtAxis); - float p = Vector3.Dot(camAtAxis, AbsolutePosition) + d; - if (p < 0.0f) priority *= 2.0f; - - return priority; - } - - private double GetSOGUpdatePriority(SceneObjectGroup sog) - { - switch (Scene.UpdatePrioritizationScheme) - { - case Scene.UpdatePrioritizationSchemes.Time: - throw new InvalidOperationException("UpdatePrioritizationScheme for time not supported for reprioritization"); - case Scene.UpdatePrioritizationSchemes.Distance: - return sog.GetPriorityByDistance((IsChildAgent) ? AbsolutePosition : CameraPosition); - case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance: - return sog.GetPriorityBySimpleAngularDistance((IsChildAgent) ? AbsolutePosition : CameraPosition); - case Scenes.Scene.UpdatePrioritizationSchemes.FrontBack: - return sog.GetPriorityByFrontBack(CameraPosition, CameraAtAxis); - default: - throw new InvalidOperationException("UpdatePrioritizationScheme not defined"); - } - } - - private double UpdatePriority(UpdatePriorityData data) - { - EntityBase entity; - SceneObjectGroup group; - - if (Scene.Entities.TryGetValue(data.localID, out entity)) - { - group = entity as SceneObjectGroup; - if (group != null) - return GetSOGUpdatePriority(group); - - ScenePresence presence = entity as ScenePresence; - if (presence == null) - throw new InvalidOperationException("entity found is neither SceneObjectGroup nor ScenePresence"); - switch (Scene.UpdatePrioritizationScheme) - { - case Scene.UpdatePrioritizationSchemes.Time: - throw new InvalidOperationException("UpdatePrioritization for time not supported for reprioritization"); - case Scene.UpdatePrioritizationSchemes.Distance: - case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance: - return GetPriorityByDistance((IsChildAgent) ? AbsolutePosition : CameraPosition); - case Scenes.Scene.UpdatePrioritizationSchemes.FrontBack: - return GetPriorityByFrontBack(CameraPosition, CameraAtAxis); - default: - throw new InvalidOperationException("UpdatePrioritizationScheme not defined"); - } - } - else - { - group = Scene.GetGroupByPrim(data.localID); - if (group != null) - return GetSOGUpdatePriority(group); - } - return double.NaN; - } - private void ReprioritizeUpdates() { - if (Scene.IsReprioritizationEnabled && Scene.UpdatePrioritizationScheme != Scene.UpdatePrioritizationSchemes.Time) + if (Scene.IsReprioritizationEnabled && Scene.UpdatePrioritizationScheme != UpdatePrioritizationSchemes.Time) { lock (m_reprioritization_timer) { @@ -4220,7 +4106,7 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos); private void Reprioritize(object sender, ElapsedEventArgs e) { - m_controllingClient.ReprioritizeUpdates(UpdatePriority); + m_controllingClient.ReprioritizeUpdates(); lock (m_reprioritization_timer) { diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs index 78f2ae3aa1..4baa22c0fb 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs @@ -49,18 +49,62 @@ namespace OpenSim.Region.Framework.Scenes.Tests /// /// Test adding an object to a scene. /// - [Test, LongRunning] + [Test] public void TestAddSceneObject() { TestHelper.InMethod(); Scene scene = SceneSetupHelpers.SetupScene(); - SceneObjectPart part = SceneSetupHelpers.AddSceneObject(scene); - SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId); + + string objName = "obj1"; + UUID objUuid = new UUID("00000000-0000-0000-0000-000000000001"); + + SceneObjectPart part + = new SceneObjectPart(UUID.Zero, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero) + { Name = objName, UUID = objUuid }; + + Assert.That(scene.AddNewSceneObject(new SceneObjectGroup(part), false), Is.True); + + SceneObjectPart retrievedPart = scene.GetSceneObjectPart(objUuid); //m_log.Debug("retrievedPart : {0}", retrievedPart); // If the parts have the same UUID then we will consider them as one and the same - Assert.That(retrievedPart.UUID, Is.EqualTo(part.UUID)); + Assert.That(retrievedPart.Name, Is.EqualTo(objName)); + Assert.That(retrievedPart.UUID, Is.EqualTo(objUuid)); + } + + [Test] + /// + /// It shouldn't be possible to add a scene object if one with that uuid already exists in the scene. + /// + public void TestAddExistingSceneObjectUuid() + { + TestHelper.InMethod(); + + Scene scene = SceneSetupHelpers.SetupScene(); + + string obj1Name = "Alfred"; + string obj2Name = "Betty"; + UUID objUuid = new UUID("00000000-0000-0000-0000-000000000001"); + + SceneObjectPart part1 + = new SceneObjectPart(UUID.Zero, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero) + { Name = obj1Name, UUID = objUuid }; + + Assert.That(scene.AddNewSceneObject(new SceneObjectGroup(part1), false), Is.True); + + SceneObjectPart part2 + = new SceneObjectPart(UUID.Zero, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero) + { Name = obj2Name, UUID = objUuid }; + + Assert.That(scene.AddNewSceneObject(new SceneObjectGroup(part2), false), Is.False); + + SceneObjectPart retrievedPart = scene.GetSceneObjectPart(objUuid); + + //m_log.Debug("retrievedPart : {0}", retrievedPart); + // If the parts have the same UUID then we will consider them as one and the same + Assert.That(retrievedPart.Name, Is.EqualTo(obj1Name)); + Assert.That(retrievedPart.UUID, Is.EqualTo(objUuid)); } /// diff --git a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs index 8b80ebe3dc..5e6124b4f9 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs @@ -58,7 +58,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestHelper.InMethod(); UUID corruptAssetUuid = UUID.Parse("00000000-0000-0000-0000-000000000666"); - AssetBase corruptAsset = AssetHelpers.CreateAsset(corruptAssetUuid, "CORRUPT ASSET", UUID.Zero); + AssetBase corruptAsset + = AssetHelpers.CreateAsset(corruptAssetUuid, AssetType.Notecard, "CORRUPT ASSET", UUID.Zero); m_assetService.Store(corruptAsset); IDictionary foundAssetUuids = new Dictionary(); diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs index 0ec3cc3c73..e3965ce978 100644 --- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs +++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs @@ -123,8 +123,8 @@ namespace OpenSim.Region.Framework.Scenes foreach (SceneObjectPart part in sceneObject.GetParts()) { - //m_log.DebugFormat( - // "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID); +// m_log.DebugFormat( +// "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID); try { @@ -155,7 +155,9 @@ namespace OpenSim.Region.Framework.Scenes // Now analyze this prim's inventory items to preserve all the uuids that they reference foreach (TaskInventoryItem tii in taskDictionary.Values) { - //m_log.DebugFormat("[ARCHIVER]: Analysing item asset type {0}", tii.Type); +// m_log.DebugFormat( +// "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}", +// tii.Name, tii.Type, part.Name, part.UUID); if (!assetUuids.ContainsKey(tii.AssetID)) GatherAssetUuids(tii.AssetID, (AssetType)tii.Type, assetUuids); diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index fb8543b477..bb82fd4530 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -1074,7 +1074,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server } - public void ReprioritizeUpdates(UpdatePriorityHandler handler) + public void ReprioritizeUpdates() { } diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 3cbc538796..9f6a33aae0 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -638,7 +638,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC { } - public void ReprioritizeUpdates(UpdatePriorityHandler handler) + public void ReprioritizeUpdates() { } diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index c059969d69..49847757a0 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -641,7 +641,7 @@ namespace OpenSim.Tests.Common.Mock { } - public void ReprioritizeUpdates(UpdatePriorityHandler handler) + public void ReprioritizeUpdates() { } diff --git a/OpenSim/Tests/Common/Setup/AssetHelpers.cs b/OpenSim/Tests/Common/Setup/AssetHelpers.cs index 1fc3cb5455..6dc993f069 100644 --- a/OpenSim/Tests/Common/Setup/AssetHelpers.cs +++ b/OpenSim/Tests/Common/Setup/AssetHelpers.cs @@ -38,12 +38,20 @@ namespace OpenSim.Tests.Common /// /// Create an asset from the given data /// - public static AssetBase CreateAsset(UUID assetUuid, string data, UUID creatorID) + public static AssetBase CreateAsset(UUID assetUuid, AssetType assetType, byte[] data, UUID creatorID) { - AssetBase asset = new AssetBase(assetUuid, assetUuid.ToString(), (sbyte)AssetType.Object, creatorID.ToString()); - asset.Data = Encoding.ASCII.GetBytes(data); + AssetBase asset = new AssetBase(assetUuid, assetUuid.ToString(), (sbyte)assetType, creatorID.ToString()); + asset.Data = data; return asset; } + + /// + /// Create an asset from the given data + /// + public static AssetBase CreateAsset(UUID assetUuid, AssetType assetType, string data, UUID creatorID) + { + return CreateAsset(assetUuid, assetType, Encoding.ASCII.GetBytes(data), creatorID); + } /// /// Create an asset from the given scene object @@ -53,9 +61,11 @@ namespace OpenSim.Tests.Common /// public static AssetBase CreateAsset(UUID assetUuid, SceneObjectGroup sog) { - AssetBase asset = new AssetBase(assetUuid, assetUuid.ToString(), (sbyte)AssetType.Object, sog.OwnerID.ToString()); - asset.Data = Encoding.ASCII.GetBytes(SceneObjectSerializer.ToXml2Format(sog)); - return asset; + return CreateAsset( + assetUuid, + AssetType.Object, + Encoding.ASCII.GetBytes(SceneObjectSerializer.ToXml2Format(sog)), + sog.OwnerID); } } } diff --git a/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs b/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs index ef8ea50e64..91cf323fcb 100644 --- a/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs +++ b/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs @@ -32,7 +32,6 @@ using Nini.Config; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Communications; - using OpenSim.Framework.Console; using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; @@ -115,7 +114,6 @@ namespace OpenSim.Tests.Common.Setup return SetupScene(name, id, x, y,""); } - /// /// Set up a scene. If it's more then one scene, use the same CommunicationsManager to link regions /// or a different, to get a brand new scene with new shared region modules.