diff --git a/libsecondlife-cs/AssetSystem/AppearanceManager.cs b/libsecondlife-cs/AssetSystem/AppearanceManager.cs
index 8d459a8f..3c2be5c0 100644
--- a/libsecondlife-cs/AssetSystem/AppearanceManager.cs
+++ b/libsecondlife-cs/AssetSystem/AppearanceManager.cs
@@ -122,7 +122,7 @@ namespace libsecondlife.AssetSystem
public void WearOutfit(InventoryFolder outfitFolder, int TimeOut, bool removeExistingAttachments)
{
// Refresh download of outfit folder
- if (!outfitFolder.RequestDownloadContents(false, false, true, true).RequestComplete.WaitOne(TimeOut, false))
+ if (!outfitFolder.RequestDownloadContents(false, false, true).RequestComplete.WaitOne(TimeOut, false))
{
Console.WriteLine("An error occured while downloads the folder contents of : " + outfitFolder.Name);
}
diff --git a/libsecondlife-cs/InventorySystem/InventoryFolder.cs b/libsecondlife-cs/InventorySystem/InventoryFolder.cs
index 57d2d6a5..b3a3de38 100644
--- a/libsecondlife-cs/InventorySystem/InventoryFolder.cs
+++ b/libsecondlife-cs/InventorySystem/InventoryFolder.cs
@@ -82,11 +82,18 @@ namespace libsecondlife.InventorySystem
/// Indicate if item data should be downloaded too (true), or only folders(false)
/// Indicate if item data should be downloaded too (true), or only folders(false)
/// The Request object for this download
+ public DownloadRequest_Folder RequestDownloadContents(bool recurse, bool folders, bool items)
+ {
+ return RequestDownloadContents(recurse, folders, items, 0);
+ }
+
+ [Obsolete("Clearing is no longer an option when requesting a download, you should use another version of this method", false)]
public DownloadRequest_Folder RequestDownloadContents(bool recurse, bool folders, bool items, bool clear)
{
- return RequestDownloadContents(recurse, folders, items, clear, 0);
+ return RequestDownloadContents(recurse, folders, items, 0);
}
+
///
/// Request a download of this folder's content information. Block until done, or timeout is reached
///
@@ -96,20 +103,21 @@ namespace libsecondlife.InventorySystem
/// Delete locale cache information for the this folder and it's children, before downloading
/// Milliseconds to wait before timing out, or -1 to wait indefinately.
/// The Request object for this download
- public DownloadRequest_Folder RequestDownloadContents(bool recurse, bool folders, bool items, bool clear, int timeout)
+ public DownloadRequest_Folder RequestDownloadContents(bool recurse, bool folders, bool items, int timeout)
{
- if (clear)
- {
- iManager.FolderClearContents(this, folders, items);
- }
-
DownloadRequest_Folder dr = new DownloadRequest_Folder(FolderID, recurse, true, items);
- iManager.RequestFolder(dr);
+ iManager.FolderRequestAppend(dr);
dr.RequestComplete.WaitOne(timeout, false);
return dr;
}
+ [Obsolete("Clearing is no longer an option when requesting a download, you should use another version of this method", false)]
+ public DownloadRequest_Folder RequestDownloadContents(bool recurse, bool folders, bool items, bool clear, int timeout)
+ {
+ return RequestDownloadContents(recurse, folders, items, timeout);
+ }
+
///
/// Request that a sub-folder be created
///
@@ -121,7 +129,7 @@ namespace libsecondlife.InventorySystem
LLUUID requestedFolderUUID = iManager.FolderCreate(name, FolderID);
// Refresh child folders, to find created folder.
- if (RequestDownloadContents(false, true, false, false).RequestComplete.WaitOne(30000, false) == false)
+ if (RequestDownloadContents(false, true, false).RequestComplete.WaitOne(30000, false) == false)
{
// Should probably note the timeout somewhere...
}
diff --git a/libsecondlife-cs/InventorySystem/InventoryManager.cs b/libsecondlife-cs/InventorySystem/InventoryManager.cs
index 8387744e..43d6e0fe 100644
--- a/libsecondlife-cs/InventorySystem/InventoryManager.cs
+++ b/libsecondlife-cs/InventorySystem/InventoryManager.cs
@@ -63,8 +63,11 @@ namespace libsecondlife.InventorySystem
private Dictionary FoldersByUUID = new Dictionary();
// Setup a dictionary to track download progress
- private Dictionary FolderDownloadStatus = new Dictionary();
- private Queue FolderRequestQueue = new Queue();
+// protected Dictionary FolderDownloadStatus = new Dictionary();
+ protected List FolderRequests = new List();
+ protected bool CurrentlyDownloadingAFolder = false;
+ protected DownloadRequest_Folder CurrentlyDownloadingRequest = null;
+ private Mutex CurrentlyDownloadingMutex = new Mutex();
protected Dictionary FolderByType = new Dictionary();
@@ -89,6 +92,7 @@ namespace libsecondlife.InventorySystem
Object = 6,
Notecard = 7,
Category = 8,
+ Folder = 8,
RootCategory = 0,
LSL = 10,
[Obsolete]
@@ -120,6 +124,9 @@ namespace libsecondlife.InventorySystem
public delegate void On_InventoryItemReceived(LLUUID fromAgentID, string fromAgentName, uint parentEstateID, LLUUID regionID, LLVector3 position, DateTime timestamp, InventoryItem item);
public event On_InventoryItemReceived OnInventoryItemReceived;
+ public delegate void On_InventoryFolderReceived(LLUUID fromAgentID, string fromAgentName, uint parentEstateID, LLUUID regionID, LLVector3 position, DateTime timestamp, InventoryFolder folder);
+ public event On_InventoryFolderReceived OnInventoryFolderReceived;
+
///
/// Primary constructor
///
@@ -172,14 +179,10 @@ namespace libsecondlife.InventorySystem
private void ClearState()
{
FoldersByUUID.Clear();
- lock (FolderDownloadStatus)
- {
- FolderDownloadStatus.Clear();
- }
- lock (FolderRequestQueue)
+ lock (FolderRequests)
{
- FolderRequestQueue.Clear();
+ FolderRequests.Clear();
}
if (slClient.Self.InventoryRootFolderUUID != null)
@@ -291,7 +294,7 @@ namespace libsecondlife.InventorySystem
}
// Try updating the current level's child folders, then look again
- if (ifRoot.RequestDownloadContents(false, true, false, false).RequestComplete.WaitOne(1000, false))
+ if (ifRoot.RequestDownloadContents(false, true, false).RequestComplete.WaitOne(1000, false))
{
foreach (InventoryBase ibFolder in ifRoot._Contents)
{
@@ -410,7 +413,7 @@ namespace libsecondlife.InventorySystem
///
/// Clear Folders
/// Clear Items
- internal void FolderClearContents(InventoryFolder iFolder, bool Folders, bool Items)
+ public void FolderClearContents(InventoryFolder iFolder, bool Folders, bool Items)
{
// Need to recursively do this...
while( iFolder._Contents.Count > 0 )
@@ -682,22 +685,64 @@ namespace libsecondlife.InventorySystem
}
///
- /// Request the download of a folder's contents
+ /// Append a request to the end of the queue.
///
///
- internal void RequestFolder(DownloadRequest_Folder dr)
+ internal void FolderRequestAppend(DownloadRequest_Folder dr)
{
- lock (FolderDownloadStatus)
+ // Add new request to the end of the queue
+ lock (FolderRequests)
{
- FolderDownloadStatus[dr.FolderID] = dr;
+ FolderRequests.Add(dr);
}
- Packet packet = InvPacketHelper.FetchInventoryDescendents(
- dr.FolderID
- , dr.FetchFolders
- , dr.FetchItems);
+ FolderRequestBegin();
+ }
- slClient.Network.SendPacket(packet);
+ ///
+ /// If not currently downloading a request, dequeue the next request and start it.
+ ///
+ internal void FolderRequestBegin()
+ {
+ // Wait until it's safe to be modifying what is currently downloading.
+ CurrentlyDownloadingMutex.WaitOne();
+
+ // If we not already downloading stuff, then lets start
+ if (CurrentlyDownloadingAFolder == false)
+ {
+ // Dequeue the first thing in the queue
+ lock (FolderRequests)
+ {
+ if (FolderRequests.Count > 0)
+ {
+ CurrentlyDownloadingRequest = FolderRequests[0];
+ FolderRequests.RemoveAt(0);
+ }
+ else
+ {
+ // Nothing to do
+
+ // Release so that we can let other things look at and modify what is currently downloading.
+ CurrentlyDownloadingMutex.ReleaseMutex();
+
+ return;
+ }
+ }
+
+ // Mark that we're currently downloading
+ CurrentlyDownloadingAFolder = true;
+
+ // Download!
+ Packet packet = InvPacketHelper.FetchInventoryDescendents(
+ CurrentlyDownloadingRequest.FolderID
+ , CurrentlyDownloadingRequest.FetchFolders
+ , CurrentlyDownloadingRequest.FetchItems);
+
+ slClient.Network.SendPacket(packet);
+ }
+
+ // Release so that we can let other things look at and modify what is currently downloading.
+ CurrentlyDownloadingMutex.ReleaseMutex();
}
///
@@ -738,16 +783,48 @@ namespace libsecondlife.InventorySystem
LLUUID imSessionID, DateTime timestamp, string message, MainAvatar.InstantMessageOnline offline,
byte[] binaryBucket)
{
- if ((dialog == MainAvatar.InstantMessageDialog.InventoryOffered) && (OnInventoryItemReceived != null))
+ Console.WriteLine(Helpers.FieldToHexString(binaryBucket, ""));
+
+ if ((dialog == MainAvatar.InstantMessageDialog.InventoryOffered) && ((OnInventoryItemReceived != null) || (OnInventoryFolderReceived !=null)))
{
sbyte IncomingItemType = (sbyte)binaryBucket[0];
- LLUUID IncomingItemID = new LLUUID(binaryBucket, 1);
+ LLUUID IncomingUUID = new LLUUID(binaryBucket, 1);
// Update root folders
InventoryFolder root = GetRootFolder();
if (root.GetContents().Count == 0)
{
- root.RequestDownloadContents(false, true, false, false).RequestComplete.WaitOne(3000, false);
+ root.RequestDownloadContents(false, true, false).RequestComplete.WaitOne(3000, false);
+ }
+
+ // Handle the case of the incoming inventory folder
+ if (IncomingItemType == (sbyte)InventoryManager.InventoryType.Folder)
+ {
+ InventoryFolder iFolder = null;
+ int numAttempts = 2;
+ while( numAttempts-- > 0 )
+ {
+ foreach( InventoryBase ib in root.GetContents() )
+ {
+ if (ib is InventoryFolder)
+ {
+ InventoryFolder tiFolder = (InventoryFolder)ib;
+ if (tiFolder.FolderID == IncomingUUID)
+ {
+ iFolder = tiFolder;
+ break;
+ }
+ }
+ }
+ if (iFolder != null)
+ {
+ OnInventoryFolderReceived(fromAgentID, fromAgentName, parentEstateID, regionID, position, timestamp, iFolder);
+ return;
+ } else {
+ Thread.Sleep(500);
+ root.RequestDownloadContents(false, true, false).RequestComplete.WaitOne(3000, false);
+ }
+ }
}
// Make sure we have a folder lookup by type table ready.
@@ -776,37 +853,43 @@ namespace libsecondlife.InventorySystem
InventoryFolder incomingFolder = FolderByType[IncomingItemType];
InventoryItem incomingItem = null;
- // lock just incade another item comes into the same directory while processing this one.
+ // lock just incase another item comes into the same directory while processing this one.
lock (incomingFolder)
{
// Refresh contents of receiving folder
- incomingFolder.RequestDownloadContents(false, false, true, false).RequestComplete.WaitOne(3000, false);
+ incomingFolder.RequestDownloadContents(false, false, true).RequestComplete.WaitOne(3000, false);
- // Search folder for incoming item
- foreach (InventoryBase ib2 in incomingFolder.GetContents())
+ int numAttempts = 2;
+ while( numAttempts-- > 0 )
{
- if (ib2 is InventoryItem)
+ // Search folder for incoming item
+ foreach (InventoryBase ib2 in incomingFolder.GetContents())
{
- InventoryItem iItem = (InventoryItem)ib2;
-
- if (iItem.ItemID == IncomingItemID)
+ if (ib2 is InventoryItem)
{
- incomingItem = iItem;
- break;
+ InventoryItem tiItem = (InventoryItem)ib2;
+
+ if (tiItem.ItemID == IncomingUUID)
+ {
+ incomingItem = tiItem;
+ break;
+ }
}
}
+ // If found, send out notification
+ if (incomingItem != null)
+ {
+ OnInventoryItemReceived(fromAgentID, fromAgentName, parentEstateID, regionID, position, timestamp, incomingItem);
+ return;
+ }
+ else
+ {
+ incomingFolder.RequestDownloadContents(false, false, true).RequestComplete.WaitOne(3000, false);
+ }
}
}
+ slClient.Log("Incoming item/folder [" + IncomingUUID.ToStringHyphenated() + "] not found in inventory.", Helpers.LogLevel.Error);
- // If found, send out notification
- if (incomingItem != null)
- {
- OnInventoryItemReceived(fromAgentID, fromAgentName, parentEstateID, regionID, position, timestamp, incomingItem);
- }
- else
- {
- slClient.Log("Incoming item not found in inventory.", Helpers.LogLevel.Error);
- }
}
}
@@ -877,18 +960,20 @@ namespace libsecondlife.InventorySystem
// The UUID of this folder.
LLUUID uuidFolderID = reply.AgentData.FolderID;
- // Get the original Descendent Request for this Packet
- DownloadRequest_Folder dr = null;
- lock (FolderDownloadStatus)
+ // Wait until it's safe to be looking at what is currently downloading.
+ CurrentlyDownloadingMutex.WaitOne();
+
+ // Make sure this request matches the one we believe is the currently downloading request
+ if( CurrentlyDownloadingRequest.FolderID != uuidFolderID )
{
- if (FolderDownloadStatus.ContainsKey(uuidFolderID))
- {
- dr = (DownloadRequest_Folder)FolderDownloadStatus[uuidFolderID];
- }
- else
- {
- slClient.Log("Received an inventory descendent packet for a folder (" + uuidFolderID.ToStringHyphenated() + ") that was not in FolderDownloadStatus.", Helpers.LogLevel.Info);
- }
+ // Release so that we can let other things look at and modify what is currently downloading.
+ CurrentlyDownloadingMutex.ReleaseMutex();
+
+ // Log problem
+ slClient.Log("Received an inventory descendent packet for a folder (" + uuidFolderID.ToStringHyphenated() + ") that is not the currently downloading request.", Helpers.LogLevel.Info);
+
+ // Just discard this packet...
+ return;
}
// Get the Inventory folder that we'll be updating
@@ -901,191 +986,181 @@ namespace libsecondlife.InventorySystem
int iDescendentsExpected = reply.AgentData.Descendents;
int iDescendentsReceivedThisBlock = 0;
- lock (slClient.Inventory)
+ #region Handle Child Items
+ foreach (InventoryDescendentsPacket.ItemDataBlock itemBlock in reply.ItemData)
{
-
- #region Handle Child Items
- foreach (InventoryDescendentsPacket.ItemDataBlock itemBlock in reply.ItemData)
+ // There is always an item block, even if there isn't any items
+ // the "filler" block will not have a name
+ if (itemBlock.Name.Length != 0)
{
- // There is always an item block, even if there isn't any items
- // the "filler" block will not have a name
- if (itemBlock.Name.Length != 0)
+ iDescendentsReceivedThisBlock++;
+
+ if (itemBlock.ItemID == LLUUID.Zero)
{
- iDescendentsReceivedThisBlock++;
-
- if (itemBlock.ItemID == LLUUID.Zero)
- {
- // this shouldn't ever happen, unless you've uploaded an invalid item
- // to yourself while developping inventory code :-(
- }
- else
- {
- InventoryItem TempInvItem = new InventoryItem(this, itemBlock);
-
- if (InvFolderUpdating._Contents.Contains(TempInvItem) == false)
- {
- if ((TempInvItem.InvType == 7) && (TempInvItem.Type == (sbyte)Asset.AssetType.Notecard))
- {
- InventoryItem temp = new InventoryNotecard(this, TempInvItem);
- TempInvItem = temp;
- }
-
- if ((TempInvItem.InvType == 0) && (TempInvItem.Type == (sbyte)Asset.AssetType.Texture))
- {
- InventoryItem temp = new InventoryImage(this, TempInvItem);
- TempInvItem = temp;
- }
-
- if ((TempInvItem.InvType == 10) && (TempInvItem.Type == (sbyte)Asset.AssetType.LSLText))
- {
- InventoryItem temp = new InventoryScript(this, TempInvItem);
- TempInvItem = temp;
- }
-
- if ((TempInvItem.InvType == 18) &&
- (
- (TempInvItem.Type == (sbyte)Asset.AssetType.Bodypart)
- || (TempInvItem.Type == (sbyte)Asset.AssetType.Clothing)
- )
- )
- {
- InventoryItem temp = new InventoryWearable(this, TempInvItem);
- TempInvItem = temp;
- }
-
- InvFolderUpdating._Contents.Add(TempInvItem);
- }
- }
+ // this shouldn't ever happen, unless you've uploaded an invalid item
+ // to yourself while developping inventory code :-(
}
- }
- #endregion
-
- #region Handle Child Folders
- foreach (InventoryDescendentsPacket.FolderDataBlock folderBlock in reply.FolderData)
- {
- String IncomingName = System.Text.Encoding.UTF8.GetString(folderBlock.Name).Trim().Replace("\0", "");
- LLUUID IncomingFolderID = folderBlock.FolderID;
- LLUUID IncomingParentID = folderBlock.ParentID;
- sbyte IncomingType = folderBlock.Type;
-
- // There is always an folder block, even if there isn't any folders
- // the "filler" block will not have a name
- if (folderBlock.Name.Length != 0)
+ else
{
- iDescendentsReceivedThisBlock++;
+ InventoryItem TempInvItem = new InventoryItem(this, itemBlock);
- // See if the Incoming Folder already exists locally
- if (FoldersByUUID.ContainsKey(IncomingFolderID))
+ if (InvFolderUpdating._Contents.Contains(TempInvItem) == false)
{
- InventoryFolder existingFolder = FoldersByUUID[IncomingFolderID];
- existingFolder._Name = IncomingName;
- existingFolder._Type = IncomingType;
-
- // Check if parent of existing is the same as the incoming
- if (!existingFolder.ParentID.Equals(IncomingParentID))
+ #region Create an instance of the appriopriate Inventory class
+ if ((TempInvItem.InvType == 7) && (TempInvItem.Type == (sbyte)Asset.AssetType.Notecard))
{
- // Remove existing from old parent
- if (FoldersByUUID.ContainsKey(existingFolder.ParentID))
- {
- InventoryFolder ExistingParent = FoldersByUUID[existingFolder.ParentID];
- if (ExistingParent._Contents.Contains(existingFolder))
- {
- ExistingParent._Contents.Remove(existingFolder);
- }
- }
-
- // Set existings parent to new
- existingFolder._ParentID = IncomingParentID;
-
- // Connect existing folder to parent specified in new
- if (FoldersByUUID.ContainsKey(IncomingParentID))
- {
- InventoryFolder ExistingParent = FoldersByUUID[IncomingParentID];
- if (!ExistingParent._Contents.Contains(existingFolder))
- {
- ExistingParent._Contents.Add(existingFolder);
- }
- }
- }
- }
- else
- {
- InventoryFolder TempInvFolder = new InventoryFolder(this, IncomingName, IncomingFolderID, IncomingParentID, IncomingType);
-
- // Add folder to Parent
- if (InvFolderUpdating._Contents.Contains(TempInvFolder) == false)
- {
- InvFolderUpdating._Contents.Add(TempInvFolder);
+ InventoryItem temp = new InventoryNotecard(this, TempInvItem);
+ TempInvItem = temp;
}
- // Add folder to local cache lookup
- FoldersByUUID[TempInvFolder.FolderID] = TempInvFolder;
-
- }
-
-
- // Do we recurse?
- if (dr.Recurse)
- {
- // It's not the root, should be safe to "recurse"
- if (!IncomingFolderID.Equals(slClient.Self.InventoryRootFolderUUID))
+ if ((TempInvItem.InvType == 0) && (TempInvItem.Type == (sbyte)Asset.AssetType.Texture))
{
- // Check if a download for this folder is already queued
- bool alreadyQueued = false;
- lock (FolderRequestQueue)
- {
- foreach (DownloadRequest_Folder adr in FolderRequestQueue)
- {
- if (adr.FolderID == IncomingFolderID)
- {
- alreadyQueued = true;
- break;
- }
- }
- // If not, then queue the stucker
- if (!alreadyQueued)
- {
- FolderRequestQueue.Enqueue(new DownloadRequest_Folder(IncomingFolderID, dr.Recurse, dr.FetchFolders, dr.FetchItems));
- }
- }
+ InventoryItem temp = new InventoryImage(this, TempInvItem);
+ TempInvItem = temp;
}
- }
- }
- }
- #endregion
- // Update total number of descendants expected , and update the total downloaded
- dr.Expected = iDescendentsExpected;
- dr.Received += iDescendentsReceivedThisBlock;
- dr.LastReceivedAtTick = Environment.TickCount;
+ if ((TempInvItem.InvType == 10) && (TempInvItem.Type == (sbyte)Asset.AssetType.LSLText))
+ {
+ InventoryItem temp = new InventoryScript(this, TempInvItem);
+ TempInvItem = temp;
+ }
- // Check if we're finished
- if (dr.Received >= dr.Expected)
- {
- // Looks like after updating, we have all the descendents,
- // remove from folder status.
- lock (FolderDownloadStatus)
- {
- FolderDownloadStatus.Remove(uuidFolderID);
- }
- dr.RequestComplete.Set();
- if (OnRequestDownloadFinishedEvent != null)
- {
- DownloadRequest_EventArgs e = new DownloadRequest_EventArgs();
- e.DownloadRequest = dr;
- FireRequestDownloadFinishedEvent(InvFolderUpdating, e);
- }
+ if ((TempInvItem.InvType == 18) &&
+ (
+ (TempInvItem.Type == (sbyte)Asset.AssetType.Bodypart)
+ || (TempInvItem.Type == (sbyte)Asset.AssetType.Clothing)
+ )
+ )
+ {
+ InventoryItem temp = new InventoryWearable(this, TempInvItem);
+ TempInvItem = temp;
+ }
+ #endregion
- // If there's any more download requests queued, grab one, and go
- lock (FolderRequestQueue)
- {
- if (FolderRequestQueue.Count > 0)
- {
- RequestFolder(FolderRequestQueue.Dequeue());
+ InvFolderUpdating._Contents.Add(TempInvItem);
}
}
}
}
+ #endregion
+
+ #region Handle Child Folders
+ foreach (InventoryDescendentsPacket.FolderDataBlock folderBlock in reply.FolderData)
+ {
+ String IncomingName = System.Text.Encoding.UTF8.GetString(folderBlock.Name).Trim().Replace("\0", "");
+ LLUUID IncomingFolderID = folderBlock.FolderID;
+ LLUUID IncomingParentID = folderBlock.ParentID;
+ sbyte IncomingType = folderBlock.Type;
+
+ // There is always an folder block, even if there isn't any folders
+ // the "filler" block will not have a name
+ if (folderBlock.Name.Length != 0)
+ {
+ iDescendentsReceivedThisBlock++;
+
+ // See if the Incoming Folder already exists locally
+ if (FoldersByUUID.ContainsKey(IncomingFolderID))
+ {
+ InventoryFolder existingFolder = FoldersByUUID[IncomingFolderID];
+ existingFolder._Name = IncomingName;
+ existingFolder._Type = IncomingType;
+
+ // Check if parent of existing is the same as the incoming
+ if (!existingFolder.ParentID.Equals(IncomingParentID))
+ {
+ // Remove existing from old parent
+ if (FoldersByUUID.ContainsKey(existingFolder.ParentID))
+ {
+ InventoryFolder ExistingParent = FoldersByUUID[existingFolder.ParentID];
+ if (ExistingParent._Contents.Contains(existingFolder))
+ {
+ ExistingParent._Contents.Remove(existingFolder);
+ }
+ }
+
+ // Set existings parent to new
+ existingFolder._ParentID = IncomingParentID;
+
+ // Connect existing folder to parent specified in new
+ if (FoldersByUUID.ContainsKey(IncomingParentID))
+ {
+ InventoryFolder ExistingParent = FoldersByUUID[IncomingParentID];
+ if (!ExistingParent._Contents.Contains(existingFolder))
+ {
+ ExistingParent._Contents.Add(existingFolder);
+ }
+ }
+ }
+ }
+ else
+ {
+ InventoryFolder TempInvFolder = new InventoryFolder(this, IncomingName, IncomingFolderID, IncomingParentID, IncomingType);
+
+ // Add folder to Parent
+ if (InvFolderUpdating._Contents.Contains(TempInvFolder) == false)
+ {
+ InvFolderUpdating._Contents.Add(TempInvFolder);
+ }
+
+ // Add folder to local cache lookup
+ FoldersByUUID[TempInvFolder.FolderID] = TempInvFolder;
+
+ }
+
+
+ // Do we recurse?
+ if (CurrentlyDownloadingRequest.Recurse)
+ {
+ // It's not the root, should be safe to "recurse"
+ if (!IncomingFolderID.Equals(slClient.Self.InventoryRootFolderUUID))
+ {
+ lock (FolderRequests)
+ {
+ FolderRequests.Insert(0, new DownloadRequest_Folder(IncomingFolderID, CurrentlyDownloadingRequest.Recurse, CurrentlyDownloadingRequest.FetchFolders, CurrentlyDownloadingRequest.FetchItems));
+ }
+ }
+ }
+ }
+ }
+ #endregion
+
+ // Update total number of descendants expected , and update the total downloaded
+ CurrentlyDownloadingRequest.Expected = iDescendentsExpected;
+ CurrentlyDownloadingRequest.Received += iDescendentsReceivedThisBlock;
+ CurrentlyDownloadingRequest.LastReceivedAtTick = Environment.TickCount;
+
+ // Check if we're finished
+ if (CurrentlyDownloadingRequest.Received >= CurrentlyDownloadingRequest.Expected)
+ {
+ // Looks like after updating, we have all the immeadiate descendents for the current request,
+ // remove from folder status.
+ lock (FolderRequests)
+ {
+ FolderRequests.Remove(CurrentlyDownloadingRequest);
+ }
+
+ // Singal anyone that was waiting for this request to finish
+ CurrentlyDownloadingRequest.RequestComplete.Set();
+
+ // Raise an event for anyone that cares to listen for downloaded folder events
+ if (OnRequestDownloadFinishedEvent != null)
+ {
+ DownloadRequest_EventArgs e = new DownloadRequest_EventArgs();
+ e.DownloadRequest = CurrentlyDownloadingRequest;
+ FireRequestDownloadFinishedEvent(InvFolderUpdating, e);
+ }
+
+ // Set Inventory Manager state to reflect that we're done with the current download
+ CurrentlyDownloadingAFolder = false;
+ CurrentlyDownloadingRequest = null;
+ }
+
+ // Release so that we can let other things look at and modify what is currently downloading.
+ CurrentlyDownloadingMutex.ReleaseMutex();
+
+
+ // If there's any more download requests queued, grab one, and go
+ FolderRequestBegin();
}
#endregion
}