diff options
Diffstat (limited to 'OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestPreparation.cs')
-rw-r--r-- | OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestPreparation.cs | 130 |
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); |