Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion Editor/Editors/YarnProjectImporterEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ protected override void Apply()
localisationFieldsContainer?.Add(newBaseLanguageField);
}
}

#if UNITY_2022_2_OR_NEWER
public override void DiscardChanges()
{
localizationEntryFields.Clear();
Expand All @@ -250,7 +250,23 @@ public override void DiscardChanges()

inspectorRoot?.Add(CreateInspectorGUI());
}
#else
protected override void ResetValues()
{
localizationEntryFields.Clear();
sourceEntryFields.Clear();
LocalisationsAddedOrRemoved = false;
BaseLanguageNameModified = false;
SourceFilesAddedOrRemoved = false;

base.ResetValues();

var inspectorRoot = uiRoot?.parent;
uiRoot?.RemoveFromHierarchy();

inspectorRoot?.Add(CreateInspectorGUI());
}
#endif
public override VisualElement CreateInspectorGUI()
{
if (!(target is YarnProjectImporter yarnProjectImporter))
Expand Down
11 changes: 10 additions & 1 deletion Editor/Utility/AssetStoreSamplesInstaller.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 10 additions & 1 deletion Editor/Utility/DependencyInstallerUtilities.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 39 additions & 0 deletions Editor/Utility/EnsureInputModuleAvailableEditor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#nullable enable
using UnityEditor;
using UnityEngine;

namespace Yarn.Unity.Editor
{
[CustomEditor(typeof(EnsureInputModuleAvailable))]
public class EnsureInputModuleAvailableEditor : UnityEditor.Editor
{
public override void OnInspectorGUI()
{
const string message = "This component checks to see if a UI Input Module exists in the scene. If one isn't available, it creates an input module on this object that's compatible with your current input system.";

EditorGUILayout.HelpBox(message, MessageType.Info);

if (target is not EnsureInputModuleAvailable module)
{
return;
}

if (module.TryGetComponent<UnityEngine.EventSystems.BaseInputModule>(out var existingInputModule))
{
if ((existingInputModule.hideFlags & HideFlags.DontSaveInEditor) != 0)
{
EditorGUILayout.Space();

EditorGUILayout.HelpBox("The " + existingInputModule.GetType().Name + " on this object is marked as temporary, and won't be saved in the scene. Click the button below if you'd like to include it in the saved scene.", MessageType.Info);
if (GUILayout.Button("Save in Scene"))
{
existingInputModule.hideFlags &= ~HideFlags.DontSaveInEditor;
UnityEditor.EditorUtility.SetDirty(existingInputModule.gameObject);
var scene = existingInputModule.gameObject.scene;
UnityEditor.SceneManagement.EditorSceneManager.SaveScene(scene);
}
}
}
}
}
}
3 changes: 3 additions & 0 deletions Editor/Utility/EnsureInputModuleAvailableEditor.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 10 additions & 1 deletion Editor/Utility/ItchSamplesInstaller.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 10 additions & 1 deletion Editor/Utility/ManualSamplesInstaller.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 10 additions & 1 deletion Editor/Utility/UPMSamplesInstaller.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Runtime/DialogueRunner/DialogueRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -957,7 +957,8 @@ public void StartDialogue(string nodeName)

dialogueCompletionSource = new YarnTaskCompletionSource();

dialogueCancellationSource = CancellationTokenSource.CreateLinkedTokenSource(this.destroyCancellationToken);
dialogueCancellationSource = CancellationTokenSource.CreateLinkedTokenSource(this.GetDestroyCancellationToken());

LineProvider.YarnProject = yarnProject;

EnsureCommandDispatcherReady();
Expand Down
40 changes: 40 additions & 0 deletions Runtime/Utility/ApplicationExitCompat.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System.Threading;
using UnityEditor;
using UnityEngine;

namespace Yarn.Unity
{
public static class ApplicationExitCompat
{
private static CancellationTokenSource _exitCts;

public static CancellationToken ExitCancellationToken
{
get
{
_exitCts ??= new CancellationTokenSource();

return _exitCts.Token;
}
}

[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
private static void Init()
{
_exitCts ??= new CancellationTokenSource();

#if UNITY_EDITOR
EditorApplication.playModeStateChanged += state =>
{
if (state == PlayModeStateChange.ExitingPlayMode)
{
_exitCts.Cancel();
}
};
#endif

Application.quitting += () => { _exitCts.Cancel(); };
}
}

}
3 changes: 3 additions & 0 deletions Runtime/Utility/ApplicationExitCompat.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 0 additions & 40 deletions Runtime/Utility/EnsureInputModuleAvailable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,44 +95,4 @@ private bool IsInputModuleInScene
}
}
}

#if UNITY_EDITOR
namespace Editor
{
using UnityEditor;
[CustomEditor(typeof(EnsureInputModuleAvailable))]
public class EnsureInputModuleAvailableEditor : UnityEditor.Editor
{
public override void OnInspectorGUI()
{
const string message = "This component checks to see if a UI Input Module exists in the scene. If one isn't available, it creates an input module on this object that's compatible with your current input system.";

EditorGUILayout.HelpBox(message, MessageType.Info);

if (target is not EnsureInputModuleAvailable module)
{
return;
}

if (module.TryGetComponent<UnityEngine.EventSystems.BaseInputModule>(out var existingInputModule))
{
if ((existingInputModule.hideFlags & HideFlags.DontSaveInEditor) != 0)
{
EditorGUILayout.Space();

EditorGUILayout.HelpBox("The " + existingInputModule.GetType().Name + " on this object is marked as temporary, and won't be saved in the scene. Click the button below if you'd like to include it in the saved scene.", MessageType.Info);
if (GUILayout.Button("Save in Scene"))
{
existingInputModule.hideFlags &= ~HideFlags.DontSaveInEditor;
UnityEditor.EditorUtility.SetDirty(existingInputModule.gameObject);
var scene = existingInputModule.gameObject.scene;
UnityEditor.SceneManagement.EditorSceneManager.SaveScene(scene);
}
}
}
}
}
}
#endif

}
35 changes: 35 additions & 0 deletions Runtime/Utility/MonoBehaviourExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#nullable enable
using System.Threading;
using UnityEngine;

namespace Yarn.Unity
{
public static class MonoBehaviourExtensions
{
/// <summary>
/// Gets a CancellationToken that is cancelled when the MonoBehaviour's GameObject is destroyed.
/// </summary>
public static CancellationToken GetDestroyCancellationToken(this MonoBehaviour mb)
{
#if UNITY_2022_2_OR_NEWER
return mb.destroyCancellationToken;
#endif

DestroyTokenNotifier notifier = mb.gameObject.GetComponent<DestroyTokenNotifier>()
?? mb.gameObject.AddComponent<DestroyTokenNotifier>();

return notifier.Cts.Token;
}
}

internal class DestroyTokenNotifier : MonoBehaviour
{
public CancellationTokenSource Cts { get; } = new();

private void OnDestroy()
{
Cts.Cancel();
Cts.Dispose();
}
}
}
3 changes: 3 additions & 0 deletions Runtime/Utility/MonoBehaviourExtensions.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 13 additions & 5 deletions Runtime/Views/Legacy/DialogueViewBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ public override async YarnTask RunLineAsync(LocalizedLine line, LineCancellation
// 2. The line is cancelled.
while (phaseComplete == false
&& token.IsNextLineRequested == false
&& Application.exitCancellationToken.IsCancellationRequested == false)
&& GetExitCancellationToken().IsCancellationRequested == false)
{
await YarnTask.Yield();
}
Expand All @@ -396,7 +396,7 @@ public override async YarnTask RunLineAsync(LocalizedLine line, LineCancellation
phaseComplete = false;
this.InterruptLine(line, PhaseComplete);
while (phaseComplete == false
&& Application.exitCancellationToken.IsCancellationRequested == false)
&& GetExitCancellationToken().IsCancellationRequested == false)
{
await YarnTask.Yield();
}
Expand All @@ -408,7 +408,7 @@ public override async YarnTask RunLineAsync(LocalizedLine line, LineCancellation
this.DismissLine(PhaseComplete);

while (phaseComplete == false
&& Application.exitCancellationToken.IsCancellationRequested == false)
&& GetExitCancellationToken().IsCancellationRequested == false)
{
await YarnTask.Yield();
}
Expand All @@ -428,12 +428,12 @@ public override async YarnTask RunLineAsync(LocalizedLine line, LineCancellation
selectedOptionID = selectedID;
});

while (selectedOptionID == -1 && cancellationToken.IsCancellationRequested == false && Application.exitCancellationToken.IsCancellationRequested == false)
while (selectedOptionID == -1 && cancellationToken.IsCancellationRequested == false && GetExitCancellationToken().IsCancellationRequested == false)
{
await YarnTask.Yield();
}

if (cancellationToken.IsCancellationRequested || Application.exitCancellationToken.IsCancellationRequested)
if (cancellationToken.IsCancellationRequested || GetExitCancellationToken().IsCancellationRequested)
{
// We were cancelled or are exiting the game. Return null.
return null;
Expand All @@ -453,5 +453,13 @@ public override async YarnTask RunLineAsync(LocalizedLine line, LineCancellation
// an option that was valid. Throw an error.
throw new InvalidOperationException($"Option view selected an invalid option ID ({selectedOptionID})");
}

private static CancellationToken GetExitCancellationToken()
{
#if UNITY_2022_2_OR_NEWER
return Application.exitCancellationToken;
#endif
return ApplicationExitCompat.ExitCancellationToken;
}
}
}