Skip to content

Commit

Permalink
BlankSceneIdentifier can now subscribe listeners
Browse files Browse the repository at this point in the history
  • Loading branch information
mackysoft committed Nov 4, 2023
1 parent 3f6dcae commit 8ed80b2
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 30 deletions.
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
using System;
using System.Collections.Generic;
using System.Threading;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.SceneManagement;

namespace MackySoft.Navigathena.SceneManagement.Tests
{
public sealed class BlankSceneIdentifier<T> : ISceneIdentifier where T : Component, ISceneEntryPoint
public sealed class BlankSceneIdentifier : ISceneIdentifier
{

readonly string m_SceneName;
readonly Action<T> m_OnCreate;
readonly Action<AnonymousSceneEntryPoint> m_OnCreate;
readonly List<ISceneEntryPointLifecycleListener> m_Listeners = new();

public BlankSceneIdentifier (string sceneName, Action<T> onCreate = null)
public BlankSceneIdentifier (string sceneName, Action<AnonymousSceneEntryPoint> onCreate = null)
{
if (string.IsNullOrEmpty(sceneName))
{
Expand All @@ -22,26 +24,40 @@ public BlankSceneIdentifier (string sceneName, Action<T> onCreate = null)
m_OnCreate = onCreate;
}

public BlankSceneIdentifier Subscribe (ISceneEntryPointLifecycleListener listener)
{
m_Listeners.Add(listener);
return this;
}

public BlankSceneIdentifier Subscribe (Func<BlankSceneIdentifier, ISceneEntryPointLifecycleListener> factory)
{
m_Listeners.Add(factory(this));
return this;
}

public ISceneHandle CreateHandle ()
{
return new BlankSceneHandle(m_SceneName, m_OnCreate);
return new BlankSceneHandle(m_SceneName, m_OnCreate, m_Listeners);
}

public override string ToString ()
{
return $"{m_SceneName} ({typeof(BlankSceneIdentifier<T>).Name})";
return $"{m_SceneName} {nameof(BlankSceneIdentifier)}";
}

sealed class BlankSceneHandle : ISceneHandle
{

readonly string m_SceneName;
readonly Action<T> m_OnCreate;
readonly Action<AnonymousSceneEntryPoint> m_OnCreate;
readonly List<ISceneEntryPointLifecycleListener> m_Listeners;

public BlankSceneHandle (string sceneName, Action<T> onCreate)
public BlankSceneHandle (string sceneName, Action<AnonymousSceneEntryPoint> onCreate, List<ISceneEntryPointLifecycleListener> listeners)
{
m_SceneName = sceneName;
m_OnCreate = onCreate;
m_Listeners = listeners;
}

public UniTask<Scene> Load (IProgress<float> progress = null, CancellationToken cancellationToken = default)
Expand All @@ -56,7 +72,12 @@ public UniTask<Scene> Load (IProgress<float> progress = null, CancellationToken

// Create entry point
GameObject entryPointGameObject = new GameObject("SceneEntryPoint");
var entryPoint = entryPointGameObject.AddComponent<T>();
var entryPoint = entryPointGameObject.AddComponent<AnonymousSceneEntryPoint>();
for (int i = 0; i < m_Listeners.Count; i++)
{
entryPoint.Register(m_Listeners[i]);
}

m_OnCreate?.Invoke(entryPoint);

SceneManager.MoveGameObjectToScene(entryPointGameObject, newScene);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,32 @@ public IEnumerator Throw_if_already_initialized () => UniTask.ToCoroutine(async
[UnityTest]
public IEnumerator Push_successfully () => UniTask.ToCoroutine(async () =>
{
SceneEntryPointLifecycleSequenceRecorder recorder = new();
SceneEntryPointCallbackFlagsStore flags = new();
var firstSceneIdentifier = new BlankSceneIdentifier<AnonymousSceneEntryPoint>("FirstScene", x => x.Register(flags));
var firstSceneIdentifier = new BlankSceneIdentifier("FirstScene")
.Subscribe(flags)
.Subscribe(x => recorder.With(x));

await m_Navigator.Initialize();

await m_Navigator.Push(firstSceneIdentifier);

Assert.AreEqual(1, m_Navigator.History.Count);
Assert.AreEqual(firstSceneIdentifier, m_Navigator.History.First().Scene);
Assert.AreEqual(SceneEntryPointCallbackFlags.OnInitialize | SceneEntryPointCallbackFlags.OnEnter, flags.Value);

recorder.Create()
.On(firstSceneIdentifier)
.Called(SceneEntryPointCallbackFlags.OnInitialize)
.Called(SceneEntryPointCallbackFlags.OnEnter)
.SequenceEqual();
});

[UnityTest]
public IEnumerator Push_canceled_if_interrupt_transition_OnEnter () => UniTask.ToCoroutine(async () =>
{
var interruptSceneIdentifier = new BlankSceneIdentifier<AnonymousSceneEntryPoint>("InterruptScene");
var firstSceneIdentifier = new BlankSceneIdentifier<AnonymousSceneEntryPoint>("FirstScene", entryPoint =>
var interruptSceneIdentifier = new BlankSceneIdentifier("InterruptScene");
var firstSceneIdentifier = new BlankSceneIdentifier("FirstScene", entryPoint =>
{
entryPoint.SetCallbacks(
onEnter: (reader, ct) => m_Navigator.Push(interruptSceneIdentifier)
Expand Down Expand Up @@ -90,15 +100,15 @@ public IEnumerator Push_canceled_if_interrupt_transition_OnEnter () => UniTask.T
[UnityTest]
public IEnumerator Push_canceled_and_OnExit_is_not_called_if_interrupt_transition_OnInitialize () => UniTask.ToCoroutine(async () =>
{
var interruptSceneIdentifier2 = new BlankSceneIdentifier<AnonymousSceneEntryPoint>("InterruptScene2");
var interruptSceneIdentifier1 = new BlankSceneIdentifier<AnonymousSceneEntryPoint>("InterruptScene1", entryPoint =>
var interruptSceneIdentifier2 = new BlankSceneIdentifier("InterruptScene2");
var interruptSceneIdentifier1 = new BlankSceneIdentifier("InterruptScene1", entryPoint =>
{
entryPoint.SetCallbacks(
onInitialize: (reader, progress, ct) => m_Navigator.Push(interruptSceneIdentifier2),
onExit: (writer, ct) => UniTask.FromException(new InvalidOperationException("OnExit is called."))
);
});
var firstSceneIdentifier = new BlankSceneIdentifier<AnonymousSceneEntryPoint>("FirstScene", entryPoint =>
var firstSceneIdentifier = new BlankSceneIdentifier("FirstScene", entryPoint =>
{
entryPoint.SetCallbacks(
onInitialize: (reader, progress, ct) => m_Navigator.Push(interruptSceneIdentifier1),
Expand Down Expand Up @@ -129,8 +139,8 @@ public IEnumerator Push_canceled_and_OnExit_is_not_called_if_interrupt_transitio
public IEnumerator Pop_successfully () => UniTask.ToCoroutine(async () =>
{
SceneEntryPointCallbackFlagsStore flags = new();
var firstSceneIdentifier = new BlankSceneIdentifier<AnonymousSceneEntryPoint>("FirstScene");
var secondSceneIdentifier = new BlankSceneIdentifier<AnonymousSceneEntryPoint>("SecondScene", x => x.Register(flags));
var firstSceneIdentifier = new BlankSceneIdentifier("FirstScene");
var secondSceneIdentifier = new BlankSceneIdentifier("SecondScene", x => x.Register(flags));

await m_Navigator.Initialize();

Expand Down Expand Up @@ -165,7 +175,7 @@ public IEnumerator Pop_throw_if_history_is_empty () => UniTask.ToCoroutine(async
[UnityTest]
public IEnumerator Pop_throw_if_history_is_single_entry () => UniTask.ToCoroutine(async () =>
{
var firstSceneIdentifier = new BlankSceneIdentifier<AnonymousSceneEntryPoint>("FirstScene");
var firstSceneIdentifier = new BlankSceneIdentifier("FirstScene");

await m_Navigator.Initialize();

Expand All @@ -187,9 +197,9 @@ public IEnumerator Pop_successfully_if_interrupt_pop () => UniTask.ToCoroutine(a
{
SceneEntryPointCallbackFlagsStore secondFlags = new();
SceneEntryPointCallbackFlagsStore thirdFlags = new();
var firstSceneIdentifier = new BlankSceneIdentifier<AnonymousSceneEntryPoint>("FirstScene");
var secondSceneIdentifier = new BlankSceneIdentifier<AnonymousSceneEntryPoint>("SecondScene", x => x.Register(secondFlags));
var thirdSceneIdentifier = new BlankSceneIdentifier<AnonymousSceneEntryPoint>("ThirdScene", x => x.Register(thirdFlags));
var firstSceneIdentifier = new BlankSceneIdentifier("FirstScene");
var secondSceneIdentifier = new BlankSceneIdentifier("SecondScene", x => x.Register(secondFlags));
var thirdSceneIdentifier = new BlankSceneIdentifier("ThirdScene", x => x.Register(thirdFlags));

await m_Navigator.Initialize();

Expand Down Expand Up @@ -220,8 +230,8 @@ await m_Navigator.Pop(interruptOperation: AsyncOperation.Create(async (progress,
public IEnumerator Change_successfully () => UniTask.ToCoroutine(async () =>
{
SceneEntryPointCallbackFlagsStore flags = new();
var firstSceneIdentifier = new BlankSceneIdentifier<AnonymousSceneEntryPoint>("FirstScene");
var secondSceneIdentifier = new BlankSceneIdentifier<AnonymousSceneEntryPoint>("SecondScene", x => x.Register(flags));
var firstSceneIdentifier = new BlankSceneIdentifier("FirstScene");
var secondSceneIdentifier = new BlankSceneIdentifier("SecondScene", x => x.Register(flags));

await m_Navigator.Initialize();

Expand All @@ -238,9 +248,9 @@ public IEnumerator Change_successfully () => UniTask.ToCoroutine(async () =>
public IEnumerator Change_successfully_if_interrupt_change () => UniTask.ToCoroutine(async () =>
{
SceneEntryPointCallbackFlagsStore secondFlags = new();
var firstSceneIdentifier = new BlankSceneIdentifier<AnonymousSceneEntryPoint>("FirstScene");
var secondSceneIdentifier = new BlankSceneIdentifier<AnonymousSceneEntryPoint>("SecondScene", x => x.Register(secondFlags));
var thirdSceneIdentifier = new BlankSceneIdentifier<AnonymousSceneEntryPoint>("ThirdScene");
var firstSceneIdentifier = new BlankSceneIdentifier("FirstScene");
var secondSceneIdentifier = new BlankSceneIdentifier("SecondScene", x => x.Register(secondFlags));
var thirdSceneIdentifier = new BlankSceneIdentifier("ThirdScene");

await m_Navigator.Initialize();

Expand All @@ -267,9 +277,9 @@ await m_Navigator.Change(secondSceneIdentifier, interruptOperation: AsyncOperati
[UnityTest]
public IEnumerator Replace_successfully () => UniTask.ToCoroutine(async () =>
{
var firstSceneIdentifier = new BlankSceneIdentifier<AnonymousSceneEntryPoint>("FirstScene");
var secondSceneIdentifier = new BlankSceneIdentifier<AnonymousSceneEntryPoint>("SecondScene");
var thirdSceneIdentifier = new BlankSceneIdentifier<AnonymousSceneEntryPoint>("ThirdScene");
var firstSceneIdentifier = new BlankSceneIdentifier("FirstScene");
var secondSceneIdentifier = new BlankSceneIdentifier("SecondScene");
var thirdSceneIdentifier = new BlankSceneIdentifier("ThirdScene");

await m_Navigator.Initialize();

Expand All @@ -288,7 +298,7 @@ public IEnumerator Replace_successfully () => UniTask.ToCoroutine(async () =>
[UnityTest]
public IEnumerator Replace_throw_if_history_is_empty () => UniTask.ToCoroutine(async () =>
{
var firstSceneIdentifier = new BlankSceneIdentifier<AnonymousSceneEntryPoint>("FirstScene");
var firstSceneIdentifier = new BlankSceneIdentifier("FirstScene");

await m_Navigator.Initialize();

Expand All @@ -308,7 +318,7 @@ public IEnumerator Reload_successfully () => UniTask.ToCoroutine(async () =>
{
int initializeCount = 0;
int finalizeCount = 0;
var firstSceneIdentifier = new BlankSceneIdentifier<AnonymousSceneEntryPoint>("FirstScene", x =>
var firstSceneIdentifier = new BlankSceneIdentifier("FirstScene", x =>
{
x.SetCallbacks(
onInitialize: (reader, progress, ct) =>
Expand Down

0 comments on commit 8ed80b2

Please sign in to comment.