diff options
author | Justin Clark-Casey (justincc) | 2010-09-07 00:34:06 +0100 |
---|---|---|
committer | Melanie | 2010-09-07 01:43:20 +0100 |
commit | 3d033520fafa1431c52086d741d1f3c7409bc6eb (patch) | |
tree | f16956aa3d2cac3ae325ffda621f2bd79b40310e /OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs | |
parent | Add test that checks correct persistence when an unlink is quickly followed b... (diff) | |
download | opensim-SC-3d033520fafa1431c52086d741d1f3c7409bc6eb.zip opensim-SC-3d033520fafa1431c52086d741d1f3c7409bc6eb.tar.gz opensim-SC-3d033520fafa1431c52086d741d1f3c7409bc6eb.tar.bz2 opensim-SC-3d033520fafa1431c52086d741d1f3c7409bc6eb.tar.xz |
Fix deletion persistence when freshly delinked prims are removed
Previously, Scene.Inventory.DeRezObjects() forced the persistence of prims before deletion.
This is necessary so that freshly delinked prims can be deleted (otherwise they remain as parts of their old group and reappear on server restart).
However, DeRezObjects() deleted to user inventory, which is not required by llDie() or direct region module unlink and deletion.
Therefore, forced persistence has been pushed down into Scene.UnlinkSceneObject() to be more general, this is still on the DeRezObjects() path.
Uncommented TestDelinkPersistence() since this now passes.
Tests required considerable elaboration of MockRegionDataPlugin to reflect underlying storing of parts.
Diffstat (limited to 'OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs')
-rw-r--r-- | OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs | 80 |
1 files changed, 67 insertions, 13 deletions
diff --git a/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs b/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs index 1c139c5..2a055cc 100644 --- a/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs +++ b/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs | |||
@@ -44,7 +44,7 @@ namespace OpenSim.Data.Null | |||
44 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 44 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
45 | 45 | ||
46 | protected Dictionary<UUID, RegionSettings> m_regionSettings = new Dictionary<UUID, RegionSettings>(); | 46 | protected Dictionary<UUID, RegionSettings> m_regionSettings = new Dictionary<UUID, RegionSettings>(); |
47 | protected Dictionary<UUID, SceneObjectGroup> m_sceneObjects = new Dictionary<UUID, SceneObjectGroup>(); | 47 | protected Dictionary<UUID, SceneObjectPart> m_sceneObjectParts = new Dictionary<UUID, SceneObjectPart>(); |
48 | protected Dictionary<UUID, ICollection<TaskInventoryItem>> m_primItems | 48 | protected Dictionary<UUID, ICollection<TaskInventoryItem>> m_primItems |
49 | = new Dictionary<UUID, ICollection<TaskInventoryItem>>(); | 49 | = new Dictionary<UUID, ICollection<TaskInventoryItem>>(); |
50 | protected Dictionary<UUID, double[,]> m_terrains = new Dictionary<UUID, double[,]>(); | 50 | protected Dictionary<UUID, double[,]> m_terrains = new Dictionary<UUID, double[,]>(); |
@@ -85,18 +85,33 @@ namespace OpenSim.Data.Null | |||
85 | 85 | ||
86 | public void StoreObject(SceneObjectGroup obj, UUID regionUUID) | 86 | public void StoreObject(SceneObjectGroup obj, UUID regionUUID) |
87 | { | 87 | { |
88 | m_log.DebugFormat( | 88 | // We can't simply store groups here because on delinking, OpenSim will not update the original group |
89 | "[MOCK REGION DATA PLUGIN]: Storing object {0} {1} in {2}", obj.Name, obj.UUID, regionUUID); | 89 | // directly. Rather, the newly delinked parts will be updated to be in their own scene object group |
90 | m_sceneObjects[obj.UUID] = obj; | 90 | // Therefore, we need to store parts rather than groups. |
91 | foreach (SceneObjectPart prim in obj.Children.Values) | ||
92 | { | ||
93 | m_log.DebugFormat( | ||
94 | "[MOCK REGION DATA PLUGIN]: Storing part {0} {1} in object {2} {3} in region {4}", | ||
95 | prim.Name, prim.UUID, obj.Name, obj.UUID, regionUUID); | ||
96 | |||
97 | m_sceneObjectParts[prim.UUID] = prim; | ||
98 | } | ||
91 | } | 99 | } |
92 | 100 | ||
93 | public void RemoveObject(UUID obj, UUID regionUUID) | 101 | public void RemoveObject(UUID obj, UUID regionUUID) |
94 | { | 102 | { |
95 | m_log.DebugFormat( | 103 | // All parts belonging to the object with the uuid are removed. |
96 | "[MOCK REGION DATA PLUGIN]: Removing object {0} from {1}", obj, regionUUID); | 104 | List<SceneObjectPart> parts = new List<SceneObjectPart>(m_sceneObjectParts.Values); |
97 | 105 | foreach (SceneObjectPart part in parts) | |
98 | if (m_sceneObjects.ContainsKey(obj)) | 106 | { |
99 | m_sceneObjects.Remove(obj); | 107 | if (part.ParentGroup.UUID == obj) |
108 | { | ||
109 | m_log.DebugFormat( | ||
110 | "[MOCK REGION DATA PLUGIN]: Removing part {0} {1} as part of object {2} from {3}", | ||
111 | part.Name, part.UUID, obj, regionUUID); | ||
112 | m_sceneObjectParts.Remove(part.UUID); | ||
113 | } | ||
114 | } | ||
100 | } | 115 | } |
101 | 116 | ||
102 | // see IRegionDatastore | 117 | // see IRegionDatastore |
@@ -107,10 +122,49 @@ namespace OpenSim.Data.Null | |||
107 | 122 | ||
108 | public List<SceneObjectGroup> LoadObjects(UUID regionUUID) | 123 | public List<SceneObjectGroup> LoadObjects(UUID regionUUID) |
109 | { | 124 | { |
110 | m_log.DebugFormat( | 125 | Dictionary<UUID, SceneObjectGroup> objects = new Dictionary<UUID, SceneObjectGroup>(); |
111 | "[MOCK REGION DATA PLUGIN]: Loading objects from {0}", regionUUID); | 126 | |
127 | // Create all of the SOGs from the root prims first | ||
128 | foreach (SceneObjectPart prim in m_sceneObjectParts.Values) | ||
129 | { | ||
130 | if (prim.IsRoot) | ||
131 | { | ||
132 | m_log.DebugFormat( | ||
133 | "[MOCK REGION DATA PLUGIN]: Loading root part {0} {1} in {2}", prim.Name, prim.UUID, regionUUID); | ||
134 | objects[prim.UUID] = new SceneObjectGroup(prim); | ||
135 | } | ||
136 | } | ||
137 | |||
138 | // Add all of the children objects to the SOGs | ||
139 | foreach (SceneObjectPart prim in m_sceneObjectParts.Values) | ||
140 | { | ||
141 | SceneObjectGroup sog; | ||
142 | if (prim.UUID != prim.ParentUUID) | ||
143 | { | ||
144 | if (objects.TryGetValue(prim.ParentUUID, out sog)) | ||
145 | { | ||
146 | int originalLinkNum = prim.LinkNum; | ||
147 | |||
148 | sog.AddPart(prim); | ||
149 | |||
150 | // SceneObjectGroup.AddPart() tries to be smart and automatically set the LinkNum. | ||
151 | // We override that here | ||
152 | if (originalLinkNum != 0) | ||
153 | prim.LinkNum = originalLinkNum; | ||
154 | } | ||
155 | else | ||
156 | { | ||
157 | m_log.WarnFormat( | ||
158 | "[MOCK REGION DATA PLUGIN]: Database contains an orphan child prim {0} {1} in region {2} pointing to missing parent {3}. This prim will not be loaded.", | ||
159 | prim.Name, prim.UUID, regionUUID, prim.ParentUUID); | ||
160 | } | ||
161 | } | ||
162 | } | ||
163 | |||
164 | // TODO: Load items. This is assymetric - we store items as a separate method but don't retrieve them that | ||
165 | // way! | ||
112 | 166 | ||
113 | return new List<SceneObjectGroup>(m_sceneObjects.Values); | 167 | return new List<SceneObjectGroup>(objects.Values); |
114 | } | 168 | } |
115 | 169 | ||
116 | public void StoreTerrain(double[,] ter, UUID regionID) | 170 | public void StoreTerrain(double[,] ter, UUID regionID) |