Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
AssetBrowserEnumerator.cs
Go to the documentation of this file.
1 using System;
2 using System.Collections.Generic;
3 using System.Collections.ObjectModel;
4 using System.IO;
5 using System.Linq;
6 using System.Text;
7 using System.Threading.Tasks;
8 
9 using SiliconStudio.Paradox;
10 using SiliconStudio.Paradox.Games.Collections;
11 using SiliconStudio.Paradox.Graphics;
12 using SiliconStudio.Paradox.Games.ViewModel;
13 using SiliconStudio.Paradox.Graphics.Data;
14 using SiliconStudio.Paradox.Games.Serialization.Packages;
15 using SiliconStudio.Paradox.Games.IO;
16 
17 namespace ScriptTest
18 {
20  {
21  public AssetBrowser(EngineContext engineContext)
22  {
23  //engineContext.VirtualFileSystem.CreateWatcher("/");
24  }
25  }
26 
28  {
29  public SortedSet<string> Files = new SortedSet<string>();
30 
31  public void Setup(string baseUrl)
32  {
33  VirtualFileSystem.ListFiles(baseUrl, "*.*", VirtualSearchOption.AllDirectories)
34  .ContinueWith(task =>
35  {
36  foreach (var url in task.Result)
37  {
38  if (IsExtensionSupported(url))
39  {
40  lock (Files)
41  {
42  Files.Add(url);
43  }
44  }
45  }
46 
47  var watcher = VirtualFileSystem.CreateWatcher(baseUrl, "*.*");
48  watcher.Changed += watcher_Changed;
49  watcher.Enable = true;
50  });
51  }
52 
53  void watcher_Changed(VirtualWatcherChangeTypes watcherChangeTypes, string url)
54  {
55  if (!IsExtensionSupported(url))
56  return;
57 
58  if ((watcherChangeTypes & VirtualWatcherChangeTypes.Created) != 0)
59  Files.Add(url);
60 
61  if ((watcherChangeTypes & VirtualWatcherChangeTypes.Deleted) != 0)
62  Files.Remove(url);
63 
64  //if ((watcherChangeTypes & WatcherChangeTypes.Renamed) != 0)
65  // Files.Remove(url);
66  }
67 
68  public static bool IsExtensionSupported(string url)
69  {
70  var urlAsLowerCase = url.ToLowerInvariant();
71  return (urlAsLowerCase.EndsWith(".png")
72  || urlAsLowerCase.EndsWith(".jpg")
73  //|| urlAsLowerCase.EndsWith(".fbx")
74  || urlAsLowerCase.EndsWith(".pdxsl"));
75  }
76  }
77 
79  {
80  private EngineContext engineContext;
81  private FileTracker fileTracker;
82  private string searchFilter = string.Empty;
83  private string searchRoot = string.Empty;
84  private Task<string[]> searchResults;
85 
86  public AssetBrowserEnumerator(EngineContext engineContext)
87  {
88  this.engineContext = engineContext;
89  }
90 
91  public void GenerateChildren(ViewModelContext context, IViewModelNode viewModelNode, ref bool handled)
92  {
93  if ((viewModelNode.NodeValue as string) == "Root")
94  {
95  viewModelNode.Children.Add(new ViewModelNode("SearchResults", new EnumerableViewModelContent<ViewModelReference>(() =>
96  searchResults != null && searchResults.IsCompleted ? searchResults.Result.Select(searchResult => new ViewModelReference(KeyValuePair.Create(UrlType.SearchResult, searchResult), true))
97  : new ViewModelReference[] { })));
98  viewModelNode.Children.Add(new ViewModelNode("SearchFilter",
99  new LambdaViewModelContent<string>(
100  () => searchFilter,
101  (newFilter) =>
102  {
103  searchFilter = newFilter;
104  StartSearch();
105  })));
106  viewModelNode.Children.Add(new ViewModelNode("Packages",
107  new EnumerableViewModelContent<ViewModelReference>(() => engineContext.PackageManager.Packages.Select(package => new ViewModelReference(package, true)))));
108 
109  fileTracker = new FileTracker();
110  fileTracker.Setup("/global_data");
111  fileTracker.Setup("/global_data2");
112  viewModelNode.Children.Add(new ViewModelNode("FileTracker", new RootViewModelContent(fileTracker)).GenerateChildren(context));
113  }
114  if (viewModelNode.Type == typeof(FileTracker))
115  {
116  viewModelNode.Content.SerializeFlags = ViewModelContentSerializeFlags.None;
117  viewModelNode.Children.Add(new ViewModelNode("RootFolder", KeyValuePair.Create(UrlType.FileTracker, "/")).GenerateChildren(context));
118  handled = true;
119  }
120  if (viewModelNode.NodeValue is Package)
121  {
122  viewModelNode.Children.Add(new ViewModelNode("Name", new PropertyInfoViewModelContent(new ParentNodeValueViewModelContent(), typeof(Package).GetProperty("Name"))));
123  handled = true;
124  }
125 
126  if (viewModelNode.NodeValue is Tuple<UrlType, string>)
127  {
128  var nodeValue = (Tuple<UrlType, string>)viewModelNode.NodeValue;
129  var url = nodeValue.Item2;
130 
131  if (nodeValue.Item1 == UrlType.SearchResult)
132  {
133  // Load thumbnail (not cached yet)
134  if (url.EndsWith(".png") || url.EndsWith(".jpg"))
135  {
136  //var textureData = engineContext.ContentManager.LoadAsync<Image>(url);
137  var thumbnail = new ViewModelNode("Thumbnail",
138  new AsyncViewModelContent<Image>(new NullViewModelContent(), operand => engineContext.AssetManager.Load<Image>(url)));
139  viewModelNode.Children.Add(thumbnail);
140  /*textureData.ContinueWith(task =>
141  {
142  thumbnail.Value = task.Result;
143  thumbnail.Content.Flags |= ViewModelFlags.Static;
144  });*/
145  }
146  /*else
147  {
148  throw new NotImplementedException();
149  }*/
150 
151  viewModelNode.Content = new RootViewModelContent(url);
152  viewModelNode.Content.SerializeFlags = ViewModelContentSerializeFlags.Serialize;
153  }
154  else if (nodeValue.Item1 == UrlType.FileTracker)
155  {
156  viewModelNode.Content = new RootViewModelContent(url);
157  viewModelNode.Content.SerializeFlags = ViewModelContentSerializeFlags.Serialize;
158 
159  viewModelNode.Children.Add(new ViewModelNode("SetAsSearchFilter", new RootViewModelContent((ExecuteCommand)((viewModel2, parameter) =>
160  {
161  searchRoot = url;
162  StartSearch();
163  }))));
164 
165  if (url.EndsWith("/"))
166  {
167  viewModelNode.Children.Add(new ViewModelNode("Folders", new EnumerableViewModelContent<ViewModelReference>(() =>
168  fileTracker.Files
169  .Where(file => file.StartsWith(url))
170  .GroupBy(file =>
171  {
172  var separatorIndex = file.IndexOf('/', url.Length + 1);
173  return file.Substring(url.Length, separatorIndex != -1 ? separatorIndex - url.Length + 1 : file.Length - url.Length);
174  })
175  .Where(x => x.Key.EndsWith("/") || x.Key.EndsWith(".dat") || x.Key.EndsWith(".pdxsl"))
176  .Select(x => new ViewModelReference(KeyValuePair.Create(UrlType.FileTracker, url + x.Key), this))
177  )));
178  }
179  }
180 
181  handled = true;
182  }
183  }
184 
185  public IEnumerable<string> EnumeratePackageObjects(Package package, string filter)
186  {
187  var packageUrl = package.Source.Url;
188  return package.ObjectHeaders
189  .Select(packageObject => packageUrl + "/" + packageObject.Name);
190  }
191 
192  public void StartSearch()
193  {
194  if (searchRoot.EndsWith("/"))
195  {
196  searchResults = VirtualFileSystem
197  .ListFiles(searchRoot, searchFilter + "*.*", VirtualSearchOption.AllDirectories)
198  .ContinueWith(task =>
199  {
200  return task.Result.Where(FileTracker.IsExtensionSupported)
201  .Concat(engineContext.PackageManager.Packages
202  .Where(x => x.Source.Url.StartsWith(searchRoot))
203  .SelectMany(x => EnumeratePackageObjects(x, searchFilter)))
204  .ToArray();
205  });
206  }
207  else
208  {
209  // User selected a file (must be a package since we list only directory and packages)
210  var package = engineContext.PackageManager.Packages.FirstOrDefault(x => x.Source.Url == searchRoot);
211  if (package != null)
212  {
213  searchResults = Task<string[]>.Factory.StartNew(() => EnumeratePackageObjects(package, searchFilter).ToArray());
214  }
215  }
216  }
217 
218  private enum UrlType
219  {
220  SearchResult = 0,
221  FileTracker = 1,
222  }
223  }
224 }
IEnumerable< string > EnumeratePackageObjects(Package package, string filter)
Provides method to instantiate an image 1D/2D/3D supporting TextureArray and mipmaps on the CPU or to...
Definition: Image.cs:88
void GenerateChildren(ViewModelContext context, IViewModelNode viewModelNode, ref bool handled)
AssetBrowser(EngineContext engineContext)
static bool IsExtensionSupported(string url)
void Setup(string baseUrl)
AssetBrowserEnumerator(EngineContext engineContext)