Skip to content

Commit c60119a

Browse files
[Assets] Made asset database loading async and save a cache as a binary file for faster loading in the editor;
[Jobs] Add Failure call for when a job fails due to an exception; [Jobs] Add JobHandle Complete static method for lists of job handles; [Editor] Make project meta file processing be async; [Editor] Support showing background progress manually; [Baker] Fix crash on invalid assimp scene loading;
1 parent 55db393 commit c60119a

22 files changed

+1941
-1278
lines changed

Engine/Core/Assets/AssetDatabase.cs

Lines changed: 563 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace Staple.Internal;
2+
3+
public interface IAssetDatabaseObserver
4+
{
5+
void AssetDatabaseSetProgress(float progress, string message);
6+
}

Engine/Core/Jobs/ActionJob.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,19 @@
22

33
namespace Staple.Jobs;
44

5-
public class ActionJob(Action action) : IJob
5+
public class ActionJob(Action action, Action<Exception> exception = null) : IJob
66
{
77
public Action action = action;
8+
9+
public Action<Exception> exception = exception;
810

911
public void Execute()
1012
{
1113
action();
1214
}
15+
16+
public void Failure(Exception e)
17+
{
18+
exception?.Invoke(e);
19+
}
1320
}

Engine/Core/Jobs/IJob.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace Staple.Jobs;
1+
using System;
2+
3+
namespace Staple.Jobs;
24

35
/// <summary>
46
/// Job interface
@@ -9,4 +11,10 @@ public interface IJob
911
/// Called to execute the job
1012
/// </summary>
1113
void Execute();
14+
15+
/// <summary>
16+
/// Called when there's a failure with a job due to an exception
17+
/// </summary>
18+
/// <param name="e">The exception</param>
19+
void Failure(Exception e);
1220
}

Engine/Core/Jobs/JobHandle.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
24
using System.Threading.Tasks;
35

46
namespace Staple.Jobs;
@@ -38,6 +40,18 @@ public readonly void Complete()
3840
task.Wait();
3941
}
4042

43+
/// <summary>
44+
/// Waits for a set of jobs to complete
45+
/// </summary>
46+
/// <param name="jobs">The jobs to wawit</param>
47+
public static void Complete(IEnumerable<JobHandle> jobs)
48+
{
49+
foreach(var job in jobs)
50+
{
51+
job.Complete();
52+
}
53+
}
54+
4155
public override readonly bool Equals(object obj)
4256
{
4357
return obj is JobHandle handle && Equals(handle);

Engine/Core/Jobs/JobSheduler.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,15 @@ public static JobHandle Schedule(IJob job)
5555
catch(Exception e)
5656
{
5757
Log.Debug($"[JobScheduler] Failed to execute job {job.GetType().FullName}: {e}");
58+
59+
try
60+
{
61+
job.Failure(e);
62+
}
63+
catch(Exception e2)
64+
{
65+
Log.Debug($"[JobScheduler] Failed to execute failure handler for job {job.GetType().FullName}: {e2}");
66+
}
5867
}
5968
});
6069

Engine/Core/MessagePackGenerated/MessagePackGenerated.cs

Lines changed: 397 additions & 229 deletions
Large diffs are not rendered by default.

Engine/Core/Player/AppPlayer.cs

Lines changed: 110 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ internal class AppPlayer
1616

1717
internal const bool printTypeCacheTypes = false;
1818

19+
private bool initialized = false;
20+
1921
public AppPlayer(string[] args, bool shouldConsoleLog)
2022
{
2123
instance = this;
@@ -86,157 +88,170 @@ public void Create()
8688

8789
renderWindow.OnInit = () =>
8890
{
89-
AssetDatabase.Reload();
90-
91-
try
91+
AssetDatabase.Reload(null, () =>
9292
{
93-
var data = ResourceManager.instance.LoadFile("StapleAppIcon.png");
94-
95-
if(data != null)
93+
try
9694
{
97-
var rawInfo = Texture.LoadStandard(data, StandardTextureColorComponents.RGBA);
95+
var data = ResourceManager.instance.LoadFile("StapleAppIcon.png");
9896

99-
if(rawInfo != null)
97+
if (data != null)
10098
{
101-
var width = 256;
102-
var height = (int)(rawInfo.height / (float)rawInfo.width * 256);
99+
var rawInfo = Texture.LoadStandard(data, StandardTextureColorComponents.RGBA);
103100

104-
if(rawInfo.Resize(width, height))
101+
if (rawInfo != null)
105102
{
106-
renderWindow.window.SetIcon(rawInfo);
103+
var width = 256;
104+
var height = (int)(rawInfo.height / (float)rawInfo.width * 256);
105+
106+
if (rawInfo.Resize(width, height))
107+
{
108+
renderWindow.window.SetIcon(rawInfo);
109+
}
107110
}
108111
}
109112
}
110-
}
111-
catch(Exception)
112-
{
113-
}
113+
catch (Exception)
114+
{
115+
}
114116

115-
Time.fixedDeltaTime = 1 / (float)AppSettings.Current.fixedTimeFrameRate;
116-
Physics3D.PhysicsDeltaTime = 1 / (float)AppSettings.Current.physicsFrameRate;
117+
Time.fixedDeltaTime = 1 / (float)AppSettings.Current.fixedTimeFrameRate;
118+
Physics3D.PhysicsDeltaTime = 1 / (float)AppSettings.Current.physicsFrameRate;
117119

118-
bool hasFocus = renderWindow.window.IsFocused;
120+
bool hasFocus = renderWindow.window.IsFocused;
119121

120-
if (AppSettings.Current.runInBackground == false && hasFocus == false)
121-
{
122-
ResetRendering(hasFocus);
123-
}
122+
if (AppSettings.Current.runInBackground == false && hasFocus == false)
123+
{
124+
ResetRendering(hasFocus);
125+
}
124126

125-
Scene.sceneList = ResourceManager.instance.LoadSceneList();
127+
Scene.sceneList = ResourceManager.instance.LoadSceneList();
126128

127-
if (Scene.sceneList == null || Scene.sceneList.Count == 0)
128-
{
129-
Log.Error($"Failed to load scene list");
129+
if (Scene.sceneList == null || Scene.sceneList.Count == 0)
130+
{
131+
Log.Error($"Failed to load scene list");
130132

131-
renderWindow.shouldStop = true;
133+
renderWindow.shouldStop = true;
132134

133-
throw new Exception("Failed to load scene list");
134-
}
135+
throw new Exception("Failed to load scene list");
136+
}
135137

136-
Log.Info("Loaded scene list");
138+
Log.Info("Loaded scene list");
137139

138-
if(Physics3D.ImplType != null && Physics3D.ImplType.IsAssignableTo(typeof(IPhysics3D)) == false)
139-
{
140-
Log.Error($"Failed to initialize physics: {Physics3D.ImplType.FullName} doesn't implement IPhysics3D");
140+
if (Physics3D.ImplType != null && Physics3D.ImplType.IsAssignableTo(typeof(IPhysics3D)) == false)
141+
{
142+
Log.Error($"Failed to initialize physics: {Physics3D.ImplType.FullName} doesn't implement IPhysics3D");
141143

142-
renderWindow.shouldStop = true;
144+
renderWindow.shouldStop = true;
143145

144-
throw new Exception("Failed to initialize physics");
145-
}
146+
throw new Exception("Failed to initialize physics");
147+
}
146148

147-
var physicsInstance = Physics3D.ImplType != null ? ObjectCreation.CreateObject<IPhysics3D>(Physics3D.ImplType) : null;
149+
var physicsInstance = Physics3D.ImplType != null ? ObjectCreation.CreateObject<IPhysics3D>(Physics3D.ImplType) : null;
148150

149-
try
150-
{
151-
Physics3D.Instance = new Physics3D(physicsInstance);
152-
}
153-
catch (Exception e)
154-
{
155-
Log.Error(e.ToString());
151+
try
152+
{
153+
Physics3D.Instance = new Physics3D(physicsInstance);
154+
}
155+
catch (Exception e)
156+
{
157+
Log.Error(e.ToString());
156158

157-
renderWindow.shouldStop = true;
159+
renderWindow.shouldStop = true;
158160

159-
throw new Exception("Failed to initialize physics");
160-
}
161+
throw new Exception("Failed to initialize physics");
162+
}
161163

162-
SubsystemManager.instance.RegisterSubsystem(RenderSystem.Instance, RenderSystem.Priority);
163-
SubsystemManager.instance.RegisterSubsystem(EntitySystemManager.Instance, EntitySystemManager.Priority);
164-
SubsystemManager.instance.RegisterSubsystem(AudioSystem.Instance, AudioSystem.Priority);
164+
SubsystemManager.instance.RegisterSubsystem(RenderSystem.Instance, RenderSystem.Priority);
165+
SubsystemManager.instance.RegisterSubsystem(EntitySystemManager.Instance, EntitySystemManager.Priority);
166+
SubsystemManager.instance.RegisterSubsystem(AudioSystem.Instance, AudioSystem.Priority);
165167

166-
if (Physics3D.Instance != null)
167-
{
168-
SubsystemManager.instance.RegisterSubsystem(Physics3D.Instance, Physics3D.Priority);
169-
}
168+
if (Physics3D.Instance != null)
169+
{
170+
SubsystemManager.instance.RegisterSubsystem(Physics3D.Instance, Physics3D.Priority);
171+
}
170172

171-
void HandleTypes<T>(string caption, Func<Type, bool> check, Action<T> callback)
172-
{
173-
var types = TypeCache.AllTypes()
174-
.Where(x => check(x))
175-
.ToArray();
173+
void HandleTypes<T>(string caption, Func<Type, bool> check, Action<T> callback)
174+
{
175+
var types = TypeCache.AllTypes()
176+
.Where(x => check(x))
177+
.ToArray();
176178

177-
Log.Info($"Loading {types.Length} {caption}s");
179+
Log.Info($"Loading {types.Length} {caption}s");
178180

179-
foreach(var type in types)
180-
{
181-
try
181+
foreach (var type in types)
182182
{
183-
var instance = (T)Activator.CreateInstance(type);
184-
185-
if (instance != null)
183+
try
186184
{
187-
callback(instance);
188-
189-
Log.Info($"Created {caption} {type.FullName}");
185+
var instance = (T)Activator.CreateInstance(type);
186+
187+
if (instance != null)
188+
{
189+
callback(instance);
190+
191+
Log.Info($"Created {caption} {type.FullName}");
192+
}
193+
else
194+
{
195+
Log.Info($"Failed to create {caption} {type.FullName}");
196+
}
190197
}
191-
else
198+
catch (Exception e)
192199
{
193-
Log.Info($"Failed to create {caption} {type.FullName}");
200+
Log.Warning($"Player: Failed to load {caption} {type.FullName}: {e}");
194201
}
195202
}
196-
catch (Exception e)
197-
{
198-
Log.Warning($"Player: Failed to load {caption} {type.FullName}: {e}");
199-
}
200203
}
201-
}
202204

203-
HandleTypes<IRenderSystem>("render system",
204-
(x => typeof(IRenderSystem).IsAssignableFrom(x) && x != typeof(IRenderSystem)),
205-
(instance => RenderSystem.Instance.RegisterSystem(instance)));
205+
HandleTypes<IRenderSystem>("render system",
206+
(x => typeof(IRenderSystem).IsAssignableFrom(x) && x != typeof(IRenderSystem)),
207+
(instance => RenderSystem.Instance.RegisterSystem(instance)));
206208

207-
HandleTypes<object>("entity system",
208-
(x => (typeof(IEntitySystemUpdate).IsAssignableFrom(x) && x != typeof(IEntitySystemUpdate)) ||
209-
(typeof(IEntitySystemFixedUpdate).IsAssignableFrom(x) && x != typeof(IEntitySystemFixedUpdate))),
210-
(instance => EntitySystemManager.Instance.RegisterSystem(instance)));
209+
HandleTypes<object>("entity system",
210+
(x => (typeof(IEntitySystemUpdate).IsAssignableFrom(x) && x != typeof(IEntitySystemUpdate)) ||
211+
(typeof(IEntitySystemFixedUpdate).IsAssignableFrom(x) && x != typeof(IEntitySystemFixedUpdate))),
212+
(instance => EntitySystemManager.Instance.RegisterSystem(instance)));
211213

212-
var scene = ResourceManager.instance.LoadScene(Scene.sceneList[0]);
214+
var scene = ResourceManager.instance.LoadScene(Scene.sceneList[0]);
213215

214-
if (scene == null)
215-
{
216-
Log.Error($"Failed to load main scene");
216+
if (scene == null)
217+
{
218+
Log.Error($"Failed to load main scene");
217219

218-
renderWindow.shouldStop = true;
220+
renderWindow.shouldStop = true;
219221

220-
throw new Exception("Failed to load main scene");
221-
}
222+
throw new Exception("Failed to load main scene");
223+
}
224+
225+
Scene.SetActiveScene(scene);
222226

223-
Scene.SetActiveScene(scene);
227+
Log.Info("Loaded first scene");
224228

225-
Log.Info("Loaded first scene");
229+
Log.Info("Finished initializing");
226230

227-
Log.Info("Finished initializing");
231+
initialized = true;
232+
});
228233
};
229234

230235
renderWindow.OnFixedUpdate = () =>
231236
{
237+
if(initialized == false)
238+
{
239+
return;
240+
}
241+
232242
SubsystemManager.instance.Update(SubsystemType.FixedUpdate);
233243

234244
EntitySystemManager.Instance.UpdateFixed();
235245
};
236246

237247
renderWindow.OnUpdate = () =>
238248
{
239-
if((AppSettings.Current?.allowFullscreenSwitch ?? true) && Input.GetKey(KeyCode.LeftAlt) && Input.GetKeyDown(KeyCode.Enter))
249+
if (initialized == false)
250+
{
251+
return;
252+
}
253+
254+
if ((AppSettings.Current?.allowFullscreenSwitch ?? true) && Input.GetKey(KeyCode.LeftAlt) && Input.GetKeyDown(KeyCode.Enter))
240255
{
241256
Screen.SetResolution(Screen.Width, Screen.Height, Screen.WindowMode == WindowMode.Windowed ? WindowMode.BorderlessFullscreen : WindowMode.Windowed);
242257
}

0 commit comments

Comments
 (0)