Tanoda
AssetLoaderFilePicker.cs
Go to the documentation of this file.
1using System;
2using System.Collections;
3using System.Collections.Generic;
4using System.Linq;
5using TriLibCore.General;
7using TriLibCore.SFB;
8using TriLibCore.Utils;
9using UnityEngine;
10
11namespace TriLibCore
12{
14 public class AssetLoaderFilePicker : MonoBehaviour
15 {
16 private IList<ItemWithStream> _items;
17 private string _modelExtension;
18 private Action<AssetLoaderContext> _onLoad;
19 private Action<AssetLoaderContext> _onMaterialsLoad;
20 private Action<AssetLoaderContext, float> _onProgress;
21 private Action<IContextualizedError> _onError;
22 private Action<bool> _onBeginLoad;
23 private GameObject _wrapperGameObject;
24 private AssetLoaderOptions _assetLoaderOptions;
25
29 {
30 var gameObject = new GameObject("AssetLoaderFilePicker");
31 var assetLoaderFilePicker = gameObject.AddComponent<AssetLoaderFilePicker>();
32 return assetLoaderFilePicker;
33 }
34
44 public void LoadModelFromFilePickerAsync(string title, Action<AssetLoaderContext> onLoad,
45 Action<AssetLoaderContext> onMaterialsLoad, Action<AssetLoaderContext, float> onProgress,
46 Action<bool> onBeginLoad, Action<IContextualizedError> onError, GameObject wrapperGameObject,
47 AssetLoaderOptions assetLoaderOptions)
48 {
49 _onLoad = onLoad;
50 _onMaterialsLoad = onMaterialsLoad;
51 _onProgress = onProgress;
52 _onError = onError;
53 _onBeginLoad = onBeginLoad;
54 _wrapperGameObject = wrapperGameObject;
55 _assetLoaderOptions = assetLoaderOptions;
56 try
57 {
58 StandaloneFileBrowser.OpenFilePanelAsync(title, null, GetExtensions(), true, OnItemsWithStreamSelected);
59 }
60 catch (Exception)
61 {
62#if (UNITY_WSA || UNITY_ANDROID) && !UNITY_EDITOR
63 Dispatcher.InvokeAsync(new ContextualizedAction(DestroyMe));
64#else
65 DestroyMe();
66#endif
67 throw;
68 }
69 }
70
71 private void DestroyMe()
72 {
73 Destroy(gameObject);
74 }
75
76 private void HandleFileLoading()
77 {
78 StartCoroutine(DoHandleFileLoading());
79 }
80
81 private IEnumerator DoHandleFileLoading()
82 {
83 var hasFiles = _items != null && (_items.Count > 0 || _items.Count == 1 && _items[0].HasData);
84 if (_onBeginLoad != null) _onBeginLoad(hasFiles);
85 yield return new WaitForEndOfFrame();
86 yield return new WaitForEndOfFrame();
87 if (!hasFiles)
88 {
89 DestroyMe();
90 yield break;
91 }
92
93 var modelFileWithStream = FindModelFile();
94 var modelFilename = modelFileWithStream.Name;
95 var modelStream = modelFileWithStream.OpenStream();
96 if (_assetLoaderOptions == null) _assetLoaderOptions = AssetLoader.CreateDefaultLoaderOptions();
97 _assetLoaderOptions.TextureMapper = ScriptableObject.CreateInstance<FilePickerTextureMapper>();
98 _assetLoaderOptions.ExternalDataMapper = ScriptableObject.CreateInstance<FilePickerExternalDataMapper>();
99 _assetLoaderOptions.FixedAllocations.Add(_assetLoaderOptions.ExternalDataMapper);
100 _assetLoaderOptions.FixedAllocations.Add(_assetLoaderOptions.TextureMapper);
101 _modelExtension = modelFilename != null ? FileUtils.GetFileExtension(modelFilename, false) : null;
102 if (_modelExtension == "zip")
103 {
104 if (modelStream != null)
105 AssetLoaderZip.LoadModelFromZipStream(modelStream, _onLoad, _onMaterialsLoad, _onProgress, _onError,
106 _wrapperGameObject, _assetLoaderOptions, _items, null);
107 else
108 AssetLoaderZip.LoadModelFromZipFile(modelFilename, _onLoad, _onMaterialsLoad, _onProgress, _onError,
109 _wrapperGameObject, _assetLoaderOptions, _items, null);
110 }
111 else
112 {
113 if (modelStream != null)
114 AssetLoader.LoadModelFromStream(modelStream, modelFilename, _modelExtension, _onLoad,
115 _onMaterialsLoad, _onProgress, _onError, _wrapperGameObject, _assetLoaderOptions, _items);
116 else
117 AssetLoader.LoadModelFromFile(modelFilename, _onLoad, _onMaterialsLoad, _onProgress, _onError,
118 _wrapperGameObject, _assetLoaderOptions, _items);
119 }
120
121 DestroyMe();
122 }
123
124 private static ExtensionFilter[] GetExtensions()
125 {
126 var extensions = Readers.Extensions;
127 var extensionFilters = new List<ExtensionFilter>();
128 var subExtensions = new List<string>();
129 foreach (var extension in extensions)
130 {
131 extensionFilters.Add(new ExtensionFilter(null, extension));
132 subExtensions.Add(extension);
133 }
134
135 subExtensions.Add("zip");
136 extensionFilters.Add(new ExtensionFilter(null, "zip"));
137 extensionFilters.Add(new ExtensionFilter("All Files", "*"));
138 extensionFilters.Insert(0, new ExtensionFilter("Accepted Files", subExtensions.ToArray()));
139 return extensionFilters.ToArray();
140 }
141
142 private ItemWithStream FindModelFile()
143 {
144 if (_items.Count == 1) return _items.First();
145 var extensions = Readers.Extensions;
146 foreach (var item in _items)
147 {
148 if (item.Name == null) continue;
149 var extension = FileUtils.GetFileExtension(item.Name, false);
150 if (extensions.Contains(extension)) return item;
151 }
152
153 return null;
154 }
155
156 private void OnItemsWithStreamSelected(IList<ItemWithStream> itemsWithStream)
157 {
158 if (itemsWithStream != null)
159 {
160 _items = itemsWithStream;
161 Dispatcher.InvokeAsync(
162 new ContextualizedAction(HandleFileLoading)); //todo: no need for dispatcher on some platforms
163 }
164 else
165 {
166 DestroyMe();
167 }
168 }
169 }
170}
TriLibCore.AssetLoaderOptions AssetLoaderOptions
Definition: TriLibLoader.cs:9
Represents an Asset Loader which loads files using a platform-specific file picker.
static AssetLoaderFilePicker Create()
Creates the Asset Loader File Picker Singleton instance.
void LoadModelFromFilePickerAsync(string title, Action< AssetLoaderContext > onLoad, Action< AssetLoaderContext > onMaterialsLoad, Action< AssetLoaderContext, float > onProgress, Action< bool > onBeginLoad, Action< IContextualizedError > onError, GameObject wrapperGameObject, AssetLoaderOptions assetLoaderOptions)
Loads a Model from the OS file picker asynchronously, or synchronously when the OS doesn't support Th...
Represents a class used to load external data from a series of selected files.
Represents a class used to load Textures from a list of selected files.
Represents a platform-specific file with a Stream.
Represents a platform-specific file browser.
static void OpenFilePanelAsync(string title, string directory, string extension, bool multiselect, Action< IList< ItemWithStream > > cb)
Native open file dialog async
Represents a file picker extension filter.
string[] Extensions
Filter extensions.