* Allow archiver to save and load objects within other objects to arbitrary levels

* This currently has various bugs which are more to do with the way its been hacked together than the feature itself (e.g. on save-oar, ghost prims will appear of the saved 
contained items).  These will be found and eliminated in subsequent patches.
* Not yet ready for use
0.6.0-stable
Justin Clarke Casey 2008-06-16 21:59:39 +00:00
parent be79b56cc3
commit 4c2171ec82
3 changed files with 103 additions and 58 deletions

View File

@ -270,7 +270,6 @@ namespace OpenSim.Framework.Communications.Cache
// m_log.DebugFormat("[ASSET CACHE]: Adding request for {0} {1}", isTexture ? "texture" : "asset", assetId);
#endif
NewAssetRequest req = new NewAssetRequest(assetId, callback);
AssetRequestsList requestList;
@ -291,28 +290,6 @@ namespace OpenSim.Framework.Communications.Cache
m_assetServer.RequestAsset(assetId, isTexture);
}
}
/* Old code doesn't handle duplicate requests right
NewAssetRequest req = new NewAssetRequest(assetId, callback);
// Make sure we always have a request list to which to add the asset
AssetRequestsList requestList;
lock (RequestLists)
{
// m_log.Info("AssetCache: Lock taken on requestLists (GetAsset)");
if (!RequestLists.TryGetValue(assetId, out requestList))
{
requestList = new AssetRequestsList(assetId);
RequestLists.Add(assetId, requestList);
}
}
// m_log.Info("AssetCache: Lock released on requestLists (GetAsset)");
requestList.Requests.Add(req);
m_assetServer.RequestAsset(assetId, isTexture);
*/
}
}

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
@ -47,13 +47,111 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected Scene m_scene;
protected string m_savePath;
protected string m_savePath;
/// <summary>
/// Used as a temporary store of an asset which represents an object. This can be a null if no appropriate
/// asset was found by the asset service.
/// </summary>
protected AssetBase m_requestedObjectAsset;
/// <summary>
/// Signal whether we are currently waiting for the asset service to deliver an asset.
/// </summary>
protected bool m_waitingForObjectAsset;
/// <summary>
/// Constructor
/// </summary>
public ArchiveWriteRequestPreparation(Scene scene, string savePath)
{
m_scene = scene;
m_savePath = savePath;
}
/// <summary>
/// The callback made when we request the asset for an object from the asset service.
/// </summary>
public void AssetRequestCallback(LLUUID assetID, AssetBase asset)
{
lock (this)
{
m_requestedObjectAsset = asset;
m_waitingForObjectAsset = false;
Monitor.Pulse(this);
}
}
/// <summary>
/// Get all the asset uuids associated with a given object. This includes both those directly associated with
/// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
/// within this object).
/// </summary>
/// <param name="sceneObject"></param>
/// <param name="assetUuids"></param>
protected void GetSceneObjectAssetUuids(SceneObjectGroup sceneObject, IDictionary<LLUUID, int> assetUuids)
{
m_log.DebugFormat(
"[ARCHIVER]: Getting assets for object {0}, {1}", sceneObject.RootPart.Name, sceneObject.UUID);
foreach (SceneObjectPart part in sceneObject.GetParts())
{
m_log.DebugFormat(
"[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID);
// XXX: Not a great way to iterate through face textures, but there's no
// other way to tell how many faces there actually are
int i = 0;
foreach (LLObject.TextureEntryFace texture in part.Shape.Textures.FaceTextures)
{
if (texture != null)
{
m_log.DebugFormat("[ARCHIVER]: Got face {0}", i++);
assetUuids[texture.TextureID] = 1;
}
}
foreach (TaskInventoryItem tii in part.TaskInventory.Values)
{
if (!assetUuids.ContainsKey(tii.AssetID))
{
assetUuids[tii.AssetID] = 1;
if (tii.Type != (int)InventoryType.Object)
{
m_log.DebugFormat("[ARCHIVER]: Recording asset {0} in object {1}", tii.AssetID, part.UUID);
}
else
{
m_waitingForObjectAsset = true;
m_scene.AssetCache.GetAsset(tii.AssetID, AssetRequestCallback, true);
// The asset cache callback can either
//
// 1. Complete on the same thread (if the asset is already in the cache) or
// 2. Come in via a different thread (if we need to go fetch it).
//
// The code below handles both these alternatives.
lock (this)
{
if (m_waitingForObjectAsset)
{
Monitor.Wait(this);
m_waitingForObjectAsset = false;
}
}
if (null != m_requestedObjectAsset)
{
string xml = Helpers.FieldToUTF8String(m_requestedObjectAsset.Data);
SceneObjectGroup sog = new SceneObjectGroup(m_scene, m_scene.RegionInfo.RegionHandle, xml);
GetSceneObjectAssetUuids(sog, assetUuids);
}
}
}
}
}
}
public void ArchiveRegion()
{
@ -65,37 +163,7 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver
{
if (entity is SceneObjectGroup)
{
SceneObjectGroup sceneObject = (SceneObjectGroup)entity;
foreach (SceneObjectPart part in sceneObject.GetParts())
{
// XXX: Not a great way to iterate through face textures, but there's no
// other way to tell how many faces there actually are
//int i = 0;
foreach (LLObject.TextureEntryFace texture in part.Shape.Textures.FaceTextures)
{
if (texture != null)
{
//m_log.DebugFormat("[ARCHIVER]: Got face {0}", i++);
assetUuids[texture.TextureID] = 1;
}
}
foreach (TaskInventoryItem tit in part.TaskInventory.Values)
{
if (tit.Type != (int)InventoryType.Object)
{
m_log.DebugFormat("[ARCHIVER]: Recording asset {0} in object {1}", tit.AssetID, part.UUID);
assetUuids[tit.AssetID] = 1;
}
else
{
// TODO: Need to unpack every tit and go through its textures & items, recursively
// this will mean going through the 'assets' received multiple times so that we can
// unpack objects within objects before recursively requesting the inner assets
}
}
}
GetSceneObjectAssetUuids((SceneObjectGroup)entity, assetUuids);
}
}
@ -104,7 +172,7 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver
if (serializedEntities != null && serializedEntities.Length > 0)
{
m_log.DebugFormat("[ARCHIVER]: Successfully got serialization for {0} entities", entities.Count);
m_log.DebugFormat("[ARCHIVER]: Requiring save of {0} textures", assetUuids.Count);
m_log.DebugFormat("[ARCHIVER]: Requiring save of {0} assets", assetUuids.Count);
// Asynchronously request all the assets required to perform this archive operation
ArchiveWriteRequestExecution awre = new ArchiveWriteRequestExecution(serializedEntities, m_savePath);

View File

@ -1596,7 +1596,7 @@ namespace OpenSim.Region.Environment.Scenes
}
/// <summary>
///
/// Do everything required once a client completes its movement into a region
/// </summary>
public void SendInitialData()
{