Skip to content

Commit c74369d

Browse files
author
DYLAN-PC\Dylan
committed
Merge branch 'feature/SPScenes' into develop
2 parents 21b42ea + 6fecc10 commit c74369d

File tree

10 files changed

+231
-182
lines changed

10 files changed

+231
-182
lines changed

SPScenes/SPScenes.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
<Compile Include="Properties\AssemblyInfo.cs" />
4848
<Compile Include="Scenes\Enums.cs" />
4949
<Compile Include="Scenes\Events\i_LoadScene.cs" />
50+
<Compile Include="Scenes\ISceneLoadedMessageReceiver.cs" />
5051
<Compile Include="Scenes\LoadSceneAsyncWaitHandle.cs" />
5152
<Compile Include="Scenes\SPSceneManager.cs" />
5253
<Compile Include="Scenes\SceneManagerEventArgs.cs" />

SPScenes/Scenes/Events/i_LoadScene.cs

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ public class i_LoadScene : AutoTriggerable
2020
[SerializeField]
2121
private LoadSceneBehaviour _behaviour;
2222

23+
[SerializeField]
24+
[Tooltip("A token used to persist data across scenes.")]
25+
VariantReference _persistentToken;
26+
2327
#endregion
2428

2529
#region Methods
@@ -30,6 +34,7 @@ public override bool Trigger(object sender, object arg)
3034
if (string.IsNullOrEmpty(_sceneName)) return false;
3135

3236
var nm = _sceneName;
37+
LoadSceneWaitHandle handle;
3338
if (nm.StartsWith("#"))
3439
{
3540
nm = nm.Substring(1);
@@ -39,27 +44,16 @@ public override bool Trigger(object sender, object arg)
3944
if (index < 0 || index >= SceneManager.sceneCountInBuildSettings)
4045
return false;
4146

42-
var manager = Services.Get<ISceneManager>();
43-
if (manager != null)
44-
{
45-
manager.LoadScene(index, _mode, _behaviour);
46-
}
47-
else
48-
{
49-
SceneManagerUtils.LoadScene(index, _mode, _behaviour);
50-
}
47+
handle = SceneManagerUtils.LoadScene(index, _mode, _behaviour);
5148
}
5249
else
5350
{
54-
var manager = Services.Get<ISceneManager>();
55-
if (manager != null)
56-
{
57-
manager.LoadScene(_sceneName, _mode, _behaviour);
58-
}
59-
else
60-
{
61-
SceneManagerUtils.LoadScene(_sceneName, _mode, _behaviour);
62-
}
51+
handle = SceneManagerUtils.LoadScene(_sceneName, _mode, _behaviour);
52+
}
53+
54+
if (handle != null)
55+
{
56+
handle.PersistentToken = com.spacepuppy.Utils.ObjUtil.ReduceIfProxy(_persistentToken.Value);
6357
}
6458

6559
return true;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System;
2+
3+
namespace com.spacepuppy.Scenes
4+
{
5+
6+
public interface ISceneLoadedMessageReceiver
7+
{
8+
9+
void OnSceneLoaded(LoadSceneWaitHandle handle);
10+
11+
}
12+
13+
}

SPScenes/Scenes/LoadSceneAsyncWaitHandle.cs

Lines changed: 62 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
namespace com.spacepuppy.Scenes
66
{
77

8-
public class LoadSceneWaitHandle : System.EventArgs, IProgressingYieldInstruction
8+
public class LoadSceneWaitHandle : System.EventArgs, IProgressingYieldInstruction, ISPDisposable
99
{
1010

1111
#region Fields
@@ -34,13 +34,29 @@ public LoadSceneWaitHandle(string sceneName, LoadSceneMode mode, LoadSceneBehavi
3434

3535
public void Init(Scene sc, AsyncOperation op)
3636
{
37+
if (_disposed) throw new System.InvalidOperationException("LoadSceneAsyncWaitHandle was disposed.");
38+
if (_initialized) throw new System.InvalidOperationException("LoadSceneAsyncWaitHandle has already been initialized.");
3739
_initialized = true;
3840
_scene = sc;
3941
_op = op;
40-
if(_behaviour == LoadSceneBehaviour.AsyncAndWait && _op != null && !_op.isDone)
42+
if (_behaviour == LoadSceneBehaviour.AsyncAndWait && _op != null && !_op.isDone)
4143
{
4244
_op.allowSceneActivation = false;
4345
}
46+
SceneManager.sceneLoaded += this.OnSceneLoaded;
47+
}
48+
49+
/// <summary>
50+
/// Initialize the handle after load for use as an EventArgs.
51+
/// </summary>
52+
/// <param name="sc"></param>
53+
public void FalseInit(Scene sc)
54+
{
55+
if (_disposed) throw new System.InvalidOperationException("LoadSceneAsyncWaitHandle was disposed.");
56+
if (_initialized) throw new System.InvalidOperationException("LoadSceneAsyncWaitHandle has already been initialized.");
57+
_initialized = true;
58+
_scene = sc;
59+
_op = null;
4460
}
4561

4662
#endregion
@@ -72,16 +88,27 @@ public bool ReadyAndWaitingToActivate
7288
get { return !object.ReferenceEquals(_op, null) && _op.progress >= 0.9f && !_op.isDone; }
7389
}
7490

91+
/// <summary>
92+
/// Use this to pass some token between scenes.
93+
/// Anything that handles the ISceneLoadedMessageReceiver will receiver a reference to this handle, and therefore this token.
94+
/// The token should not be something that is destroyed by the load process.
95+
/// </summary>
96+
public object PersistentToken
97+
{
98+
get;
99+
set;
100+
}
101+
75102
#endregion
76103

77104
#region Methods
78-
105+
79106
public void WaitToActivate()
80107
{
81-
if(_behaviour >= LoadSceneBehaviour.Async)
108+
if (_behaviour >= LoadSceneBehaviour.Async)
82109
{
83110
_behaviour = LoadSceneBehaviour.AsyncAndWait;
84-
if(_op != null && !_op.isDone)
111+
if (_op != null && !_op.isDone)
85112
{
86113
_op.allowSceneActivation = false;
87114
}
@@ -93,6 +120,16 @@ public void ActivateScene()
93120
if (_op != null) _op.allowSceneActivation = true;
94121
}
95122

123+
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
124+
{
125+
//note Scene == Scene compares the handle and works just fine
126+
if (_scene == scene)
127+
{
128+
SceneManager.sceneLoaded -= this.OnSceneLoaded;
129+
com.spacepuppy.Utils.Messaging.FindAndBroadcast<ISceneLoadedMessageReceiver>((o) => o.OnSceneLoaded(this));
130+
}
131+
}
132+
96133
#endregion
97134

98135
#region IProgressingAsyncOperation Interface
@@ -101,7 +138,7 @@ public float Progress
101138
{
102139
get
103140
{
104-
switch(_behaviour)
141+
switch (_behaviour)
105142
{
106143
case LoadSceneBehaviour.Standard:
107144
return _initialized ? 0f : 1f;
@@ -139,16 +176,16 @@ public bool IsComplete
139176

140177
bool IRadicalYieldInstruction.Tick(out object yieldObject)
141178
{
142-
if(!_initialized)
179+
if (!_initialized)
143180
{
144181
yieldObject = null;
145182
return false;
146183
}
147184

148-
switch(_behaviour)
185+
switch (_behaviour)
149186
{
150187
case LoadSceneBehaviour.Standard:
151-
if(_initialized)
188+
if (_initialized)
152189
{
153190
yieldObject = null;
154191
return false;
@@ -170,12 +207,12 @@ bool IRadicalYieldInstruction.Tick(out object yieldObject)
170207
return true;
171208
}
172209
case LoadSceneBehaviour.AsyncAndWait:
173-
if(object.ReferenceEquals(_op, null))
210+
if (object.ReferenceEquals(_op, null))
174211
{
175212
yieldObject = null;
176213
return false;
177214
}
178-
else if(_op.isDone || this.ReadyAndWaitingToActivate)
215+
else if (_op.isDone || this.ReadyAndWaitingToActivate)
179216
{
180217
yieldObject = null;
181218
return false;
@@ -193,91 +230,34 @@ bool IRadicalYieldInstruction.Tick(out object yieldObject)
193230

194231
#endregion
195232

196-
}
197-
198-
199-
public class LoadSceneAsyncWaitHandle : IProgressingYieldInstruction
200-
{
201-
202-
#region Fields
203-
204-
private AsyncOperation _op;
205-
private Scene _scene;
206-
private bool _waitingForHandle;
207-
208-
#endregion
209-
210-
#region CONSTRUCTOR
211-
212-
public LoadSceneAsyncWaitHandle(AsyncOperation op, Scene scene)
213-
{
214-
//if (op == null) throw new System.ArgumentNullException("op");
215-
_op = op;
216-
_scene = scene;
217-
}
218-
219-
internal LoadSceneAsyncWaitHandle()
220-
{
221-
_waitingForHandle = true;
222-
}
223-
internal void Init(AsyncOperation op, Scene scene)
224-
{
225-
//if (op == null) throw new System.ArgumentNullException("op");
226-
_op = op;
227-
_scene = scene;
228-
_waitingForHandle = false;
229-
}
230-
231-
#endregion
232-
233-
#region Properties
233+
#region IDisposable Interface
234234

235-
public Scene Scene
235+
private bool _disposed;
236+
public bool IsDisposed
236237
{
237-
get { return _scene; }
238+
get { return _disposed; }
238239
}
239240

240-
#endregion
241-
242-
#region IProgressingAsyncOperation Interface
243-
244-
public float Progress
241+
public void Dispose()
245242
{
246-
get
243+
if (!_disposed)
247244
{
248-
if (_waitingForHandle)
249-
return 0f;
250-
else
251-
return _op.progress;
245+
_sceneName = null;
246+
_op = null;
247+
SceneManager.sceneLoaded -= this.OnSceneLoaded;
252248
}
253-
}
254249

255-
public bool IsComplete
256-
{
257-
get
258-
{
259-
if (_waitingForHandle)
260-
return false;
261-
else
262-
return _op.isDone;
263-
}
250+
_disposed = true;
264251
}
265252

266-
bool IRadicalYieldInstruction.Tick(out object yieldObject)
253+
~LoadSceneWaitHandle()
267254
{
268-
if (!_waitingForHandle && _op.isDone)
269-
{
270-
yieldObject = null;
271-
return false;
272-
}
273-
else
274-
{
275-
yieldObject = _op;
276-
return true;
277-
}
255+
//make sure we clean ourselves up
256+
this.Dispose();
278257
}
279258

280259
#endregion
281260

282261
}
262+
283263
}

0 commit comments

Comments
 (0)