-
-
Notifications
You must be signed in to change notification settings - Fork 495
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
636345b
commit 24f6d7b
Showing
13 changed files
with
477 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
28 changes: 28 additions & 0 deletions
28
Dependencies/Modules/Engines/Unity/Mono/Unity.Mono/MonoCoroutineInterop.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
using System.Collections; | ||
using UnityEngine; | ||
|
||
namespace MelonLoader.Engine.Unity.Mono | ||
{ | ||
internal class MonoCoroutineInterop : MelonCoroutineInterop | ||
{ | ||
private MonoSupportComponent Component; | ||
|
||
internal MonoCoroutineInterop(MonoSupportComponent component) | ||
=> Component = component; | ||
|
||
public override object Start(IEnumerator coroutine) | ||
{ | ||
if (Component != null) | ||
return Component.StartCoroutine(coroutine); | ||
return MelonCoroutines.Start(coroutine); | ||
} | ||
|
||
public override void Stop(object coroutineToken) | ||
{ | ||
if (Component != null) | ||
Component.StopCoroutine(coroutineToken as Coroutine); | ||
else | ||
MelonCoroutines.Stop(coroutineToken); | ||
} | ||
} | ||
} |
100 changes: 100 additions & 0 deletions
100
Dependencies/Modules/Engines/Unity/Mono/Unity.Mono/MonoSceneHandler.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
using System; | ||
using UnityEngine.SceneManagement; | ||
using System.Collections.Generic; | ||
|
||
namespace MelonLoader.Engine.Unity.Mono | ||
{ | ||
internal class MonoSceneHandler : IDisposable | ||
{ | ||
private MonoSupportModule SupportModule; | ||
|
||
internal class SceneInitEvent | ||
{ | ||
internal int buildIndex; | ||
internal string name; | ||
internal bool wasLoadedThisTick; | ||
} | ||
private Queue<SceneInitEvent> scenesLoaded = new Queue<SceneInitEvent>(); | ||
|
||
internal MonoSceneHandler(MonoSupportModule supportModule) | ||
{ | ||
SupportModule = supportModule; | ||
|
||
try | ||
{ | ||
SceneManager.sceneLoaded += OnSceneLoad; | ||
} | ||
catch (Exception ex) { MelonLogger.Error($"SceneManager.sceneLoaded override failed: {ex}"); } | ||
|
||
try | ||
{ | ||
SceneManager.sceneUnloaded += OnSceneUnload; | ||
} | ||
catch (Exception ex) { MelonLogger.Error($"SceneManager.sceneUnloaded override failed: {ex}"); } | ||
} | ||
|
||
~MonoSceneHandler() | ||
=> Dispose(); | ||
|
||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Reliability", "CA2013:Do not use ReferenceEquals with value types")] | ||
public void Dispose() | ||
{ | ||
try | ||
{ | ||
SceneManager.sceneLoaded -= OnSceneLoad; | ||
} | ||
catch (Exception ex) { MelonLogger.Error($"SceneManager.sceneLoaded override failed: {ex}"); } | ||
|
||
try | ||
{ | ||
SceneManager.sceneUnloaded -= OnSceneUnload; | ||
} | ||
catch (Exception ex) { MelonLogger.Error($"SceneManager.sceneUnloaded override failed: {ex}"); } | ||
} | ||
|
||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Reliability", "CA2013:Do not use ReferenceEquals with value types")] | ||
private void OnSceneLoad(Scene scene, LoadSceneMode mode) | ||
{ | ||
if (SupportModule.obj == null) | ||
SupportModule.CreateGameObject(); | ||
|
||
if (ReferenceEquals(scene, null)) | ||
return; | ||
|
||
MelonUnityEvents.OnSceneWasLoaded.Invoke(scene.buildIndex, scene.name); | ||
scenesLoaded.Enqueue(new SceneInitEvent { buildIndex = scene.buildIndex, name = scene.name }); | ||
} | ||
|
||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Reliability", "CA2013:Do not use ReferenceEquals with value types")] | ||
private void OnSceneUnload(Scene scene) | ||
{ | ||
if (ReferenceEquals(scene, null)) | ||
return; | ||
|
||
MelonUnityEvents.OnSceneWasUnloaded.Invoke(scene.buildIndex, scene.name); | ||
} | ||
|
||
internal void OnUpdate() | ||
{ | ||
if (scenesLoaded.Count > 0) | ||
{ | ||
Queue<SceneInitEvent> requeue = new Queue<SceneInitEvent>(); | ||
SceneInitEvent evt = null; | ||
while ((scenesLoaded.Count > 0) && ((evt = scenesLoaded.Dequeue()) != null)) | ||
{ | ||
if (evt.wasLoadedThisTick) | ||
{ | ||
MelonUnityEvents.OnSceneWasInitialized.Invoke(evt.buildIndex, evt.name); | ||
} | ||
else | ||
{ | ||
evt.wasLoadedThisTick = true; | ||
requeue.Enqueue(evt); | ||
} | ||
} | ||
while ((requeue.Count > 0) && ((evt = requeue.Dequeue()) != null)) | ||
scenesLoaded.Enqueue(evt); | ||
} | ||
} | ||
} | ||
} |
132 changes: 132 additions & 0 deletions
132
Dependencies/Modules/Engines/Unity/Mono/Unity.Mono/MonoSupportComponent.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
using System; | ||
using System.Reflection; | ||
using UnityEngine; | ||
using MelonLoader.Modules; | ||
|
||
namespace MelonLoader.Engine.Unity.Mono | ||
{ | ||
internal class MonoSupportComponent : MonoBehaviour | ||
{ | ||
private bool isQuitting; | ||
private bool hadError; | ||
|
||
private MethodInfo SetAsLastSiblingMethod; | ||
|
||
MonoSupportComponent() | ||
{ | ||
try | ||
{ | ||
SetAsLastSiblingMethod = typeof(Transform).GetMethod("SetAsLastSibling", BindingFlags.Public | BindingFlags.Instance); | ||
if (SetAsLastSiblingMethod == null) | ||
throw new Exception("Unable to find UnityEngine.Transform::SetAsLastSibling"); | ||
} | ||
catch (Exception ex) { LogError("Getting UnityEngine.Transform::SetAsLastSibling", ex); } | ||
} | ||
|
||
private void LogError(string cat, Exception ex) | ||
{ | ||
hadError = true; | ||
MelonLogger.Warning($"Exception while {cat}: {ex}"); | ||
MelonLogger.Warning("Melon Events might run before some MonoBehaviour Events"); | ||
} | ||
|
||
internal void SiblingFix() | ||
{ | ||
if (hadError) | ||
return; | ||
|
||
try | ||
{ | ||
gameObject.transform.SetAsLastSibling(); | ||
transform.SetAsLastSibling(); | ||
} | ||
catch (Exception ex) | ||
{ | ||
LogError("Invoking UnityEngine.Transform::SetAsLastSibling", ex); | ||
} | ||
} | ||
|
||
void Start() | ||
{ | ||
if ((ModuleInterop.Support == null) || (((MonoSupportModule)ModuleInterop.Support).component != this)) | ||
return; | ||
|
||
SiblingFix(); | ||
|
||
MelonUnityEvents.OnApplicationLateStart.Invoke(); | ||
} | ||
|
||
void Awake() | ||
{ | ||
if ((ModuleInterop.Support == null) || (((MonoSupportModule)ModuleInterop.Support).component != this)) | ||
return; | ||
|
||
MelonCoroutines.ProcessQueue(); | ||
} | ||
|
||
void Update() | ||
{ | ||
if ((ModuleInterop.Support == null) || (((MonoSupportModule)ModuleInterop.Support).component != this)) | ||
return; | ||
|
||
isQuitting = false; | ||
SiblingFix(); | ||
|
||
((MonoSupportModule)ModuleInterop.Support).sceneHandler.OnUpdate(); | ||
|
||
MelonUnityEvents.OnUpdate.Invoke(); | ||
} | ||
|
||
void OnDestroy() | ||
{ | ||
if ((ModuleInterop.Support == null) || (((MonoSupportModule)ModuleInterop.Support).component != this)) | ||
return; | ||
|
||
if (!isQuitting) | ||
{ | ||
((MonoSupportModule)ModuleInterop.Support).CreateGameObject(); | ||
return; | ||
} | ||
|
||
OnApplicationDefiniteQuit(); | ||
} | ||
|
||
void OnApplicationQuit() | ||
{ | ||
if ((ModuleInterop.Support == null) || (((MonoSupportModule)ModuleInterop.Support).component != this)) | ||
return; | ||
|
||
isQuitting = true; | ||
MelonUnityEvents.OnApplicationQuit.Invoke(); | ||
} | ||
|
||
void OnApplicationDefiniteQuit() | ||
{ | ||
MelonUnityEvents.OnApplicationDefiniteQuit.Invoke(); | ||
} | ||
|
||
void FixedUpdate() | ||
{ | ||
if ((ModuleInterop.Support == null) || (((MonoSupportModule)ModuleInterop.Support).component != this)) | ||
return; | ||
|
||
MelonUnityEvents.OnFixedUpdate.Invoke(); | ||
} | ||
|
||
void LateUpdate() | ||
{ | ||
if ((ModuleInterop.Support == null) || (((MonoSupportModule)ModuleInterop.Support).component != this)) | ||
return; | ||
|
||
MelonUnityEvents.OnLateUpdate.Invoke(); | ||
} | ||
|
||
void OnGUI() | ||
{ | ||
if ((ModuleInterop.Support == null) || (((MonoSupportModule)ModuleInterop.Support).component != this)) | ||
return; | ||
|
||
MelonUnityEvents.OnGUI.Invoke(); | ||
} | ||
} | ||
} |
Oops, something went wrong.