Skip to content

Commit af86f89

Browse files
author
jKnepel
committed
feat: handle exceptions better, support multiple input types
1 parent c163faf commit af86f89

File tree

13 files changed

+102
-49
lines changed

13 files changed

+102
-49
lines changed

Assets/UnityFileExplorer/Runtime/Scripts/Datastructure/EmptyNode.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public override void Unload()
4747
GameObject.Destroy(UIInstance);
4848
}
4949

50-
public override void MissingPermissions()
50+
public override void OnFailedToLoad(ENodeFailedToLoad reason)
5151
{
5252
}
5353
}

Assets/UnityFileExplorer/Runtime/Scripts/Datastructure/FileNode.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace CENTIS.UnityFileExplorer.Datastructure
55
{
66
internal class FileNode : TreeNode, IEquatable<FileNode>
77
{
8-
public UINode UIInstance { get; private set; }
8+
public UINode UIInstance { get; }
99

1010
public FileNode(ExplorerConfiguration config, NodeInformation info, VirtualFolderNode parent)
1111
: base(config, info, parent)
@@ -48,9 +48,9 @@ public override void Unload()
4848
GameObject.Destroy(UIInstance.gameObject);
4949
}
5050

51-
public override void MissingPermissions()
51+
public override void OnFailedToLoad(ENodeFailedToLoad reason)
5252
{
53-
UIInstance.MissingPermissions();
53+
UIInstance.OnFailedToLoad(reason);
5454
}
5555
}
5656
}

Assets/UnityFileExplorer/Runtime/Scripts/Datastructure/FolderNode.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace CENTIS.UnityFileExplorer.Datastructure
66
{
77
internal class FolderNode : VirtualFolderNode, IEquatable<FolderNode>
88
{
9-
public UINode UIInstance { get; private set; }
9+
public UINode UIInstance { get; }
1010

1111
public FolderNode(ExplorerConfiguration config, NodeInformation info, VirtualFolderNode parent, List<TreeNode> children = null)
1212
: base(config, info, parent, children)
@@ -52,9 +52,9 @@ public override void Unload()
5252
}
5353
}
5454

55-
public override void MissingPermissions()
55+
public override void OnFailedToLoad(ENodeFailedToLoad reason)
5656
{
57-
UIInstance.MissingPermissions();
57+
UIInstance.OnFailedToLoad(reason);
5858
}
5959
}
6060
}

Assets/UnityFileExplorer/Runtime/Scripts/Datastructure/TreeNode.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public bool Equals(TreeNode other)
4242
public abstract void Show();
4343
public abstract void Hide();
4444
public abstract void Unload();
45-
public abstract void MissingPermissions();
45+
public abstract void OnFailedToLoad(ENodeFailedToLoad reason);
4646

4747
protected void Select(TreeNode node) => OnSelected?.Invoke(node);
4848
protected void Deselect(TreeNode node) => OnDeselected?.Invoke(node);

Assets/UnityFileExplorer/Runtime/Scripts/Datastructure/VirtualFolderNode.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public override void Unload()
4040
}
4141
}
4242

43-
public override void MissingPermissions()
43+
public override void OnFailedToLoad(ENodeFailedToLoad reason)
4444
{
4545
}
4646

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
namespace CENTIS.UnityFileExplorer
2+
{
3+
public enum ENodeFailedToLoad
4+
{
5+
/// <summary>
6+
/// If the caller has insufficient permissions to load the node
7+
/// </summary>
8+
MissingPermissions,
9+
/// <summary>
10+
/// If the node's path is too long
11+
/// </summary>
12+
PathTooLong,
13+
/// <summary>
14+
/// If the node is of an invalid type or failed to load for unknown reasons
15+
/// </summary>
16+
InvalidNode
17+
}
18+
}

Assets/UnityFileExplorer/Runtime/Scripts/ENodeFailedToLoad.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/UnityFileExplorer/Runtime/Scripts/ExplorerManager.cs

Lines changed: 57 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System;
44
using System.Collections.Generic;
55
using System.IO;
6+
using System.Security;
67

78
namespace CENTIS.UnityFileExplorer
89
{
@@ -17,6 +18,8 @@ public ExplorerConfiguration ExplorerConfiguration
1718
set => _config = value;
1819
}
1920

21+
public event Action FolderPathUpdated;
22+
2023
private VirtualFolderNode _root; // a virtual folder above the disks
2124
private VirtualFolderNode _currentFolder;
2225
private TreeNode _selectedNode;
@@ -30,8 +33,7 @@ public ExplorerConfiguration ExplorerConfiguration
3033

3134
private Action<string> _fileFoundCallback;
3235

33-
private string _fileExtension;
34-
private bool _certainFilesOnly = false;
36+
private string[] _fileExtensions;
3537

3638
#endregion
3739

@@ -40,22 +42,19 @@ public ExplorerConfiguration ExplorerConfiguration
4042
public virtual void FindFile(
4143
Action<string> onFilePathFound = null,
4244
Environment.SpecialFolder? startFolder = null,
43-
string fileExtension = null
45+
string[] fileExtensions = null
4446
){
4547
InitFileExplorer();
46-
if (!string.IsNullOrEmpty(fileExtension))
47-
{
48-
_fileExtension = fileExtension;
49-
_certainFilesOnly = true;
50-
}
48+
if (fileExtensions != null)
49+
_fileExtensions = fileExtensions;
5150

5251
_fileFoundCallback = onFilePathFound;
5352
_currentFolder = _root = new VirtualFolderNode(_config, new() { Name = "This PC" }, null);
5453
_hashedNodes.Add(_root.ToString(), _root);
5554

5655
// create drive folders beneath virtual root
57-
DriveInfo[] drives = DriveInfo.GetDrives();
58-
foreach (DriveInfo drive in drives)
56+
var drives = DriveInfo.GetDrives();
57+
foreach (var drive in drives)
5958
{
6059
FolderNode diskNode = new(_config, drive.GetNodeInformation(), _root);
6160
diskNode.OnSelected += SelectNode;
@@ -73,7 +72,7 @@ public virtual void FindFile(
7372
}
7473

7574
// used to navigate to the given startFolder and create all nodes, that are visited during the navigation
76-
string startFolderPath = Environment.GetFolderPath((Environment.SpecialFolder)startFolder);
75+
var startFolderPath = Environment.GetFolderPath((Environment.SpecialFolder)startFolder);
7776
DirectoryInfo startDir = new(startFolderPath);
7877
VirtualFolderNode startParent = FindParentRecursive(startDir);
7978
FolderNode startNode = new(_config, startDir.GetNodeInformation(), startParent);
@@ -94,11 +93,10 @@ public virtual void CancelFindFile()
9493
_hashedNodes.Clear();
9594
_lastVisitedNodes.Clear();
9695
_lastReturnedFromNodes.Clear();
97-
foreach (PathNode node in _pathNodes)
98-
GameObject.Destroy(node.UIInstance.gameObject);
96+
foreach (var node in _pathNodes)
97+
Destroy(node.UIInstance.gameObject);
9998
_pathNodes.Clear();
100-
_fileExtension = string.Empty;
101-
_certainFilesOnly = false;
99+
_fileExtensions = null;
102100
}
103101

104102
#endregion
@@ -171,9 +169,8 @@ private void ActivateNode(TreeNode node)
171169
case FileNode fileNode:
172170
ChooseFile(fileNode);
173171
break;
174-
case EmptyNode:
175172
default:
176-
throw new Exception("How did this happen?");
173+
throw new("How did this happen?");
177174
}
178175
}
179176

@@ -193,26 +190,28 @@ private void UpdatePath()
193190
{
194191
if (_config.PathContainer == null) return;
195192

196-
foreach (PathNode node in _pathNodes)
197-
GameObject.Destroy(node.UIInstance.gameObject);
193+
foreach (var node in _pathNodes)
194+
DestroyImmediate(node.UIInstance.gameObject);
198195
_pathNodes.Clear();
199196

200-
VirtualFolderNode folderNode = _currentFolder;
197+
var folderNode = _currentFolder;
201198
while (folderNode != null)
202199
{
203-
string name = folderNode.Info.Name.Replace("\\", "").Replace("/", "");
204-
_pathNodes.Add(new() { FolderNode = folderNode, Name = name });
200+
var nodeName = folderNode.Info.Name.Replace("\\", "").Replace("/", "");
201+
_pathNodes.Add(new() { FolderNode = folderNode, Name = nodeName });
205202
folderNode = folderNode.Parent;
206203
}
207204

208-
for (int i = _pathNodes.Count - 1; i >= 0; i--)
205+
for (var i = _pathNodes.Count - 1; i >= 0; i--)
209206
{
210-
PathNode node = _pathNodes[i];
211-
UIPathFolder uiInstance = Instantiate(_config.PathFolderPrefab, _config.PathContainer.transform);
207+
var node = _pathNodes[i];
208+
var uiInstance = Instantiate(_config.PathFolderPrefab, _config.PathContainer.transform);
212209
uiInstance.Initialize(node.Name);
213210
uiInstance.OnActivated += () => ActivateNode(node.FolderNode);
214211
node.UIInstance = uiInstance;
215212
}
213+
214+
FolderPathUpdated?.Invoke();
216215
}
217216

218217
private void GoBack()
@@ -268,9 +267,23 @@ private void NavigateToNode(VirtualFolderNode node)
268267
node.AddChild(emptyNode);
269268
}
270269
}
271-
} catch (UnauthorizedAccessException) {
272-
node.MissingPermissions();
273-
return;
270+
} catch (Exception e) {
271+
switch (e)
272+
{
273+
case SecurityException:
274+
case UnauthorizedAccessException:
275+
node.OnFailedToLoad(ENodeFailedToLoad.MissingPermissions);
276+
return;
277+
case PathTooLongException:
278+
node.OnFailedToLoad(ENodeFailedToLoad.PathTooLong);
279+
return;
280+
case IOException:
281+
node.OnFailedToLoad(ENodeFailedToLoad.InvalidNode);
282+
return;
283+
default:
284+
Console.WriteLine(e);
285+
throw;
286+
}
274287
}
275288

276289
_lastVisitedNodes.Add(_currentFolder);
@@ -289,9 +302,9 @@ private void NavigateToNode(VirtualFolderNode node)
289302

290303
private void AddDirectories(VirtualFolderNode folder)
291304
{
292-
string folderPath = folder.ToString();
305+
var folderPath = folder.ToString();
293306
IEnumerable<DirectoryInfo> containedDir = new DirectoryInfo(folderPath).GetDirectories();
294-
foreach (DirectoryInfo dir in containedDir)
307+
foreach (var dir in containedDir)
295308
{
296309
FolderNode folderNode = new(_config, dir.GetNodeInformation(), folder);
297310
folderNode.OnSelected += SelectNode;
@@ -304,12 +317,22 @@ private void AddDirectories(VirtualFolderNode folder)
304317

305318
private void AddFiles(VirtualFolderNode folder)
306319
{
307-
string folderPath = folder.ToString();
320+
var folderPath = folder.ToString();
308321
IEnumerable<FileInfo> containedFiles = new DirectoryInfo(folderPath).GetFiles();
309-
foreach (FileInfo file in containedFiles)
322+
foreach (var file in containedFiles)
310323
{
311-
if (_certainFilesOnly && !file.Name.EndsWith(_fileExtension)) continue;
312-
324+
var isCorrectType = false;
325+
if (_fileExtensions != null)
326+
{
327+
foreach (var extension in _fileExtensions)
328+
{
329+
if (!file.Name.EndsWith(extension)) continue;
330+
isCorrectType = true;
331+
break;
332+
}
333+
}
334+
if (!isCorrectType && _fileExtensions != null) continue;
335+
313336
FileNode fileNode = new(_config, file.GetNodeInformation(), folder);
314337
fileNode.OnSelected += SelectNode;
315338
fileNode.OnDeselected += DeselectNode;

Assets/UnityFileExplorer/Runtime/Scripts/UINode.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public abstract class UINode : MonoBehaviour
1010
public event Action OnActivated;
1111

1212
public abstract void Initialize(NodeInformation nodeInformation);
13-
public abstract void MissingPermissions();
13+
public abstract void OnFailedToLoad(ENodeFailedToLoad reason);
1414

1515
public void Select() => OnSelected?.Invoke();
1616
public void Deselect() => OnDeselected?.Invoke();

Assets/UnityFileExplorer/Samples/ExampleUI/Scripts/Node.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ public override void Initialize(NodeInformation info)
1111
_name.text = gameObject.name = info.Name;
1212
}
1313

14-
public override void MissingPermissions()
14+
public override void OnFailedToLoad(ENodeFailedToLoad reason)
1515
{
16-
Debug.LogError("Unauthorized Access!");
16+
Debug.LogError($"Failed to load node because: {reason}");
1717
}
1818
}

0 commit comments

Comments
 (0)