void fetchinventory(object x) { recursion++; invthreaddata itd = (invthreaddata)x; UUID start=itd.key; TreeIter iter = itd.iter; bool cache = itd.cacheonly; bool alreadyseen=true; bool recurse = itd.recurse; List<InventoryBase> myObjects; List <invthreaddata> runners= new List<invthreaddata>(); System.Threading.AutoResetEvent prefetch=new AutoResetEvent(false); TreePath path=null; Gtk.Application.Invoke(delegate { path = inventory.GetPath(iter); if (path == null) { Logger.Log("*!*!*!*! WTF? we got a NULL path in the fetchinventory()",Helpers.LogLevel.Debug); return; } path.Down(); if (MainClass.client == null) { recursion--; return; } InventoryNode node = MainClass.client.Inventory.Store.GetNodeFor(start); if (node.NeedsUpdate == true) { alreadyseen = false; } //Check for a waiting here, we need to use this to decide which fetcher to use in a moment if (cache == false) { TreeIter childiter; inventory.GetIter(out childiter, path); if ("Waiting..." == (string)inventory.GetValue(childiter, 1)) { alreadyseen = false; } } prefetch.Set(); }); prefetch.WaitOne(); // Use an approprate fetcher based on various flags if(cache==true || alreadyseen==true) myObjects = MainClass.client.Inventory.Store.GetContents(start); else myObjects = MainClass.client.Inventory.FolderContents(start, MainClass.client.Self.AgentID, true, true, InventorySortOrder.ByDate, 30000); //Logger.Log("Got objects # "+myObjects.Count.ToString(),Helpers.LogLevel.Debug); AutoResetEvent postfetch = new AutoResetEvent(false); Gtk.Application.Invoke(delegate { if (myObjects == null || myObjects.Count==0) { recursion--; postfetch.Set(); return; } //Logger.Log("Possible refilter",Helpers.LogLevel.Debug); if(filteractive==true) { filter.Refilter(); filter.Refilter(); //*sigh* } this.label_fetched.Text="fetched "+this.no_items.ToString()+" items"; List<InventoryBase> folders = new List<InventoryBase>(); foreach (InventoryBase item in myObjects) { if(item.Name=="Trash" && item is InventoryFolder && trash_folder==UUID.Zero) { trash_folder=item.UUID; } if (assetmap.ContainsKey(item.UUID)) { TreeIter iterx = assetmap[item.UUID]; InventoryBase itemx = (InventoryBase)inventory.GetValue(iterx,3); if (itemx is InventoryFolder) { invthreaddata itd2 = new invthreaddata(item.UUID, path.ToString(), iterx,cache,true); runners.Add(itd2); //fetchinventory((object)itd2); } continue; } this.no_items++; Gdk.Pixbuf buf = getprettyicon(item); global_thread_tree = inventory.AppendValues(iter, buf, item.Name, item.UUID, item); if (!assetmap.ContainsKey(item.UUID)) assetmap.Add(item.UUID, global_thread_tree); Gtk.TreeIter iter2=global_thread_tree; if (item is InventoryFolder) { inventory.AppendValues(iter2, item_object, "Waiting...", item.UUID, null); invthreaddata itd2 = new invthreaddata(((InventoryFolder)item).UUID, "", iter2,cache,true); runners.Add(itd2); if (abortfetch == true) { postfetch.Set(); return; } } } //We should preserve Waiting... messages for folders we don't yet have the children for //or else the user can't open them as there is no + to click on. But we need to get rid // of them for folders we have just got the data for! if (cache == false || (cache == true && myObjects.Count > 0)) { TreeIter childiter; inventory.GetIter(out childiter, path); if ("Waiting..." == (string)inventory.GetValue(childiter, 1)) { inventory.Remove(ref childiter); alreadyseen = false; } } postfetch.Set(); }); postfetch.WaitOne(); if (abortfetch == true) return; if (myObjects == null || myObjects.Count == 0) return; if (recurse) { foreach (invthreaddata itdn in runners) { if (abortfetch == true) return; fetchinventory((object)itdn); } } recursion--; if (recursion == 0) { fetcherrunning = false; if(cache==false && recurse==true) { fetchrun=true; Logger.Log("Fetch Complete",Helpers.LogLevel.Debug); Gtk.Application.Invoke(delegate{ this.label_fetched.Text="fetched "+this.no_items.ToString()+" items (Finished)"; }); } } return; }
protected virtual void OnEntrySearchChanged(object sender, System.EventArgs e) { lock(inventory) { if(fetchrun==false && fetcherrunning==false) { Logger.Log("Starting Inventory Fetch all",Helpers.LogLevel.Info); fetcherrunning = true; Thread invRunner = new Thread(new ParameterizedThreadStart(fetchinventory)); invthreaddata itd = new invthreaddata(MainClass.client.Inventory.Store.RootFolder.UUID, "0:0", TLI,false,true); invRunner.Start(itd); } filteractive = true; filter.ClearCache(); filtered.Clear(); //*sigh* if (this.entry_search.Text == "") { filteractive = false; filter.Refilter(); return; } //Becuase we use our own filter we have to do two passes at the data to first find matches, then to find parents of matches filter.Refilter(); filter.Refilter(); //*sigh* treeview_inv.ExpandAll(); } }
void populate_top_level_inv() { lock (inventory) { if (MainClass.client.Inventory.Store.Items != null) { foreach (KeyValuePair<UUID, InventoryNode> kvp in MainClass.client.Inventory.Store.Items) { if (kvp.Value.Data != null) { if (kvp.Value.Data.ParentUUID == UUID.Zero) { if (!assetmap.ContainsKey(MainClass.client.Inventory.Store.RootFolder.UUID)) { InventoryFolder fdr = new InventoryFolder(MainClass.client.Inventory.Store.RootFolder.UUID); fdr.Name = "My Inventory"; Gtk.TreeIter iterx = inventory.AppendValues(folder_closed, kvp.Value.Data.Name, kvp.Value.Data.UUID, fdr); Console.Write("Creating top level folder " + kvp.Value.Data.Name + " : " + MainClass.client.Inventory.Store.Items[kvp.Value.Data.UUID].ToString()); assetmap.Add(MainClass.client.Inventory.Store.RootFolder.UUID, iterx); inventory.AppendValues(iterx, folder_closed, "Waiting...", kvp.Value.Data.UUID, null); if (kvp.Value.Data.Name == "My Inventory") TLI = iterx; } } Console.Write(kvp.Value.Data.ParentUUID.ToString() + " : "); } } this.no_items = 0; MainClass.client.Inventory.Store.RestoreFromDisk(MainClass.client.Settings.ASSET_CACHE_DIR + System.IO.Path.DirectorySeparatorChar + MainClass.client.Inventory.Store.RootFolder.UUID.ToString() + ".osl"); fetcherrunning = true; Thread invRunner = new Thread(new ParameterizedThreadStart(fetchinventory)); invthreaddata itd = new invthreaddata(MainClass.client.Inventory.Store.RootFolder.UUID, "0", TLI, true, true); invRunner.Start(itd); } } }
protected virtual void OnButtonFetchAllInvClicked(object sender, System.EventArgs e) { if (fetcherrunning == false) { fetcherrunning = true; Thread invRunner = new Thread(new ParameterizedThreadStart(fetchinventory)); invthreaddata itd = new invthreaddata(MainClass.client.Inventory.Store.RootFolder.UUID, "0:0", TLI,false,true); invRunner.Start(itd); } }
void onRowExpanded(object o,Gtk.RowExpandedArgs args) { lock (inventory) { // Avoid updaing rows in the middle of a filter operation if (filteractive == true) return; //We can't do this or it confuses the hell out of stuff //if (fetcherrunning == true) // return; try { TreeIter iter = filter.ConvertIterToChildIter(args.Iter); UUID key = (UUID)this.inventory.GetValue(iter, 2); if (inventory.GetValue(iter, 0) == folder_closed) inventory.SetValue(iter, 0, folder_open); TreePath path = inventory.GetPath(iter); path.Down(); TreeIter iter2; inventory.GetIter(out iter2, path); string Name = inventory.GetValue(iter2, 1).ToString(); //if (Name == "Waiting...") { Thread invRunner = new Thread(new ParameterizedThreadStart(fetchinventory)); invthreaddata itd = new invthreaddata(key, filter.ConvertPathToChildPath(args.Path).ToString(), iter, false, false); invRunner.Start(itd); } } catch { } } }