aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestPreparation.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestPreparation.cs')
-rw-r--r--OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestPreparation.cs130
1 files changed, 99 insertions, 31 deletions
diff --git a/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestPreparation.cs
index a93e58d..1b78f4c 100644
--- a/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestPreparation.cs
+++ b/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestPreparation.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -47,64 +47,132 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver
47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48 48
49 protected Scene m_scene; 49 protected Scene m_scene;
50 protected string m_savePath; 50 protected string m_savePath;
51
52 /// <summary>
53 /// Used as a temporary store of an asset which represents an object. This can be a null if no appropriate
54 /// asset was found by the asset service.
55 /// </summary>
56 protected AssetBase m_requestedObjectAsset;
57
58 /// <summary>
59 /// Signal whether we are currently waiting for the asset service to deliver an asset.
60 /// </summary>
61 protected bool m_waitingForObjectAsset;
51 62
63 /// <summary>
64 /// Constructor
65 /// </summary>
52 public ArchiveWriteRequestPreparation(Scene scene, string savePath) 66 public ArchiveWriteRequestPreparation(Scene scene, string savePath)
53 { 67 {
54 m_scene = scene; 68 m_scene = scene;
55 m_savePath = savePath; 69 m_savePath = savePath;
56 } 70 }
57 71
58 public void ArchiveRegion() 72 /// <summary>
73 /// The callback made when we request the asset for an object from the asset service.
74 /// </summary>
75 public void AssetRequestCallback(LLUUID assetID, AssetBase asset)
59 { 76 {
60 Dictionary<LLUUID, int> assetUuids = new Dictionary<LLUUID, int>(); 77 lock (this)
61
62 List<EntityBase> entities = m_scene.GetEntities();
63
64 foreach (EntityBase entity in entities)
65 { 78 {
66 if (entity is SceneObjectGroup) 79 m_requestedObjectAsset = asset;
80 m_waitingForObjectAsset = false;
81 Monitor.Pulse(this);
82 }
83 }
84
85 /// <summary>
86 /// Get all the asset uuids associated with a given object. This includes both those directly associated with
87 /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
88 /// within this object).
89 /// </summary>
90 /// <param name="sceneObject"></param>
91 /// <param name="assetUuids"></param>
92 protected void GetSceneObjectAssetUuids(SceneObjectGroup sceneObject, IDictionary<LLUUID, int> assetUuids)
93 {
94 m_log.DebugFormat(
95 "[ARCHIVER]: Getting assets for object {0}, {1}", sceneObject.RootPart.Name, sceneObject.UUID);
96
97 foreach (SceneObjectPart part in sceneObject.GetParts())
98 {
99 m_log.DebugFormat(
100 "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID);
101
102 // XXX: Not a great way to iterate through face textures, but there's no
103 // other way to tell how many faces there actually are
104 int i = 0;
105 foreach (LLObject.TextureEntryFace texture in part.Shape.Textures.FaceTextures)
67 { 106 {
68 SceneObjectGroup sceneObject = (SceneObjectGroup)entity; 107 if (texture != null)
108 {
109 m_log.DebugFormat("[ARCHIVER]: Got face {0}", i++);
110 assetUuids[texture.TextureID] = 1;
111 }
112 }
69 113
70 foreach (SceneObjectPart part in sceneObject.GetParts()) 114 foreach (TaskInventoryItem tii in part.TaskInventory.Values)
115 {
116 if (!assetUuids.ContainsKey(tii.AssetID))
71 { 117 {
72 // XXX: Not a great way to iterate through face textures, but there's no 118 assetUuids[tii.AssetID] = 1;
73 // other way to tell how many faces there actually are 119
74 //int i = 0; 120 if (tii.Type != (int)InventoryType.Object)
75 foreach (LLObject.TextureEntryFace texture in part.Shape.Textures.FaceTextures)
76 { 121 {
77 if (texture != null) 122 m_log.DebugFormat("[ARCHIVER]: Recording asset {0} in object {1}", tii.AssetID, part.UUID);
78 {
79 //m_log.DebugFormat("[ARCHIVER]: Got face {0}", i++);
80 assetUuids[texture.TextureID] = 1;
81 }
82 } 123 }
83 124 else
84 foreach (TaskInventoryItem tit in part.TaskInventory.Values)
85 { 125 {
86 if (tit.Type != (int)InventoryType.Object) 126 m_waitingForObjectAsset = true;
127 m_scene.AssetCache.GetAsset(tii.AssetID, AssetRequestCallback, true);
128
129 // The asset cache callback can either
130 //
131 // 1. Complete on the same thread (if the asset is already in the cache) or
132 // 2. Come in via a different thread (if we need to go fetch it).
133 //
134 // The code below handles both these alternatives.
135 lock (this)
87 { 136 {
88 m_log.DebugFormat("[ARCHIVER]: Recording asset {0} in object {1}", tit.AssetID, part.UUID); 137 if (m_waitingForObjectAsset)
89 assetUuids[tit.AssetID] = 1; 138 {
139 Monitor.Wait(this);
140 m_waitingForObjectAsset = false;
141 }
90 } 142 }
91 else 143
144 if (null != m_requestedObjectAsset)
92 { 145 {
93 // TODO: Need to unpack every tit and go through its textures & items, recursively 146 string xml = Helpers.FieldToUTF8String(m_requestedObjectAsset.Data);
94 // this will mean going through the 'assets' received multiple times so that we can 147 SceneObjectGroup sog = new SceneObjectGroup(m_scene, m_scene.RegionInfo.RegionHandle, xml);
95 // unpack objects within objects before recursively requesting the inner assets 148 GetSceneObjectAssetUuids(sog, assetUuids);
96 } 149 }
97 } 150 }
98 } 151 }
99 } 152 }
100 } 153 }
154 }
155
156 public void ArchiveRegion()
157 {
158 Dictionary<LLUUID, int> assetUuids = new Dictionary<LLUUID, int>();
159
160 List<EntityBase> entities = m_scene.GetEntities();
161
162 foreach (EntityBase entity in entities)
163 {
164 if (entity is SceneObjectGroup)
165 {
166 GetSceneObjectAssetUuids((SceneObjectGroup)entity, assetUuids);
167 }
168 }
101 169
102 string serializedEntities = SerializeObjects(entities); 170 string serializedEntities = SerializeObjects(entities);
103 171
104 if (serializedEntities != null && serializedEntities.Length > 0) 172 if (serializedEntities != null && serializedEntities.Length > 0)
105 { 173 {
106 m_log.DebugFormat("[ARCHIVER]: Successfully got serialization for {0} entities", entities.Count); 174 m_log.DebugFormat("[ARCHIVER]: Successfully got serialization for {0} entities", entities.Count);
107 m_log.DebugFormat("[ARCHIVER]: Requiring save of {0} textures", assetUuids.Count); 175 m_log.DebugFormat("[ARCHIVER]: Requiring save of {0} assets", assetUuids.Count);
108 176
109 // Asynchronously request all the assets required to perform this archive operation 177 // Asynchronously request all the assets required to perform this archive operation
110 ArchiveWriteRequestExecution awre = new ArchiveWriteRequestExecution(serializedEntities, m_savePath); 178 ArchiveWriteRequestExecution awre = new ArchiveWriteRequestExecution(serializedEntities, m_savePath);