Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cleaning up life cycle code #1068

Merged
merged 5 commits into from
Apr 8, 2021
Merged
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
137 changes: 47 additions & 90 deletions TLM/TLM/LoadingExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,27 @@ namespace TrafficManager {
using UnityEngine.SceneManagement;
using Util;
using Object = UnityEngine.Object;
using System.Linq;

[UsedImplicitly]
public class LoadingExtension : LoadingExtensionBase {
static LoadingExtension() {
TranslationDatabase.LoadAllTranslations();
RegisterCustomManagers();
}

public LoadingExtension() {
}

internal static LoadingExtension Instance = null;
static FastList<ISimulationManager> GetSimManagers() =>
typeof(SimulationManager)
.GetField("m_managers", BindingFlags.Static | BindingFlags.NonPublic)
?.GetValue(null)
as FastList<ISimulationManager>
?? throw new Exception("could not get SimulationManager.m_managers");

FastList<ISimulationManager> simManager =>
typeof(SimulationManager).GetField("m_managers", BindingFlags.Static | BindingFlags.NonPublic)
?.GetValue(null) as FastList<ISimulationManager>;
internal static AppMode? AppMode => SimulationManager.instance.m_ManagersWrapper.loading.currentMode;

internal static AppMode? AppMode => Instance?.loadingManager?.currentMode;
public static SimulationManager.UpdateMode UpdateMode => SimulationManager.instance.m_metaData.m_updateMode;
public static LoadMode Mode => (LoadMode)UpdateMode;
public static string Scene => SceneManager.GetActiveScene().name;

/// <summary>
/// determines whether Game mode as oppose to edit mode (eg asset editor).
Expand All @@ -46,37 +50,15 @@ public LoadingExtension() {
/// </summary>
public static Translation TranslationDatabase = new Translation();

public static UITransportDemand TransportDemandUI { get; private set; }

public static List<ICustomManager> RegisteredManagers { get; private set; }

public static bool IsGameLoaded { get; private set; }

public static bool IsPathManagerReplaced {
get; private set;
}

public override void OnCreated(ILoading loading) {
Log._Debug("LoadingExtension.OnCreated() called");

// SelfDestruct.DestructOldInstances(this);
base.OnCreated(loading);
if (IsGameLoaded) {
// When another mod is detected, OnCreated is called again for god - or CS team - knows what reason!
Log._Debug("Hot reload of another mod detected. Skipping LoadingExtension.OnCreated() ...");
return;
}
InGameUtil.Instantiate();
public static bool IsPathManagerReplaced { get; private set; }

private static void RegisterCustomManagers() {
RegisteredManagers = new List<ICustomManager>();
CustomPathManager = new CustomPathManager();

RegisterCustomManagers();

Instance = this;
}

private void RegisterCustomManagers() {
// TODO represent data dependencies differently
RegisteredManagers.Add(ExtNodeManager.Instance);
RegisteredManagers.Add(ExtSegmentManager.Instance);
Expand Down Expand Up @@ -107,49 +89,32 @@ private void RegisterCustomManagers() {
RegisteredManagers.Add(JunctionRestrictionsManager.Instance);
}

public override void OnReleased() {
TrafficManagerMod.Instance.InGameHotReload = false;
Instance = null;
base.OnReleased();
}
public override void OnLevelUnloading() => Unload();

public override void OnLevelLoaded(LoadMode mode) => Load();

public static void Unload() {
Log.Info("LoadingExtension.Unload()");

public override void OnLevelUnloading() {
Log.Info("OnLevelUnloading");
base.OnLevelUnloading();
if (IsPathManagerReplaced) {
CustomPathManager._instance.WaitForAllPaths();
}

try {
var reverseManagers = new List<ICustomManager>(RegisteredManagers);
reverseManagers.Reverse();

foreach (ICustomManager manager in reverseManagers) {
foreach (ICustomManager manager in RegisteredManagers.AsEnumerable().Reverse()) {
Log.Info($"OnLevelUnloading: {manager.GetType().Name}");
manager.OnLevelUnloading();
}

Flags.OnLevelUnloading();
GlobalConfig.OnLevelUnloading();

var gameObject = UIView.GetAView().gameObject;

void Destroy<T>() where T : MonoBehaviour {
Object obj = (Object)gameObject.GetComponent<T>();
if (obj != null) {
Object.Destroy(obj);
}
}

Destroy<RoadSelectionPanels>();
Destroy<RemoveVehicleButtonExtender>();
Destroy<RemoveCitizenInstanceButtonExtender>();

//It's MonoBehaviour - comparing to null is wrong
if (TransportDemandUI) {
Object.Destroy(TransportDemandUI);
TransportDemandUI = null;
}
var uiviewGO = UIView.GetAView().gameObject;
Object.Destroy(uiviewGO.GetComponent<RoadSelectionPanels>());
Object.Destroy(uiviewGO.GetComponent<RemoveVehicleButtonExtender>());
Object.Destroy(uiviewGO.GetComponent<RemoveCitizenInstanceButtonExtender>());
Object.Destroy(uiviewGO.GetComponent<RemoveCitizenInstanceButtonExtender>());
Object.Destroy(uiviewGO.GetComponent<UITransportDemand>());

Log.Info("Removing Controls from UI.");
if (ModUI.Instance != null) {
Expand All @@ -164,18 +129,21 @@ void Destroy<T>() where T : MonoBehaviour {
// ignored - prevents collision with other mods
}

Patcher.Instance?.Uninstall();
Patcher.Uninstall();
IsGameLoaded = false;
TrafficManagerMod.InGameHotReload = false;
}

public override void OnLevelLoaded(LoadMode mode) {
SimulationManager.UpdateMode updateMode = SimulationManager.instance.m_metaData.m_updateMode;
string scene = SceneManager.GetActiveScene().name;
Log.Info($"OnLevelLoaded({mode}) called. updateMode={updateMode}, scene={scene}");
public static void Load() {
Log.Info($"LoadingExtension.Load() called. {Mode} called. updateMode={UpdateMode}, scene={Scene}");

if (scene == "ThemeEditor")
if(Scene == "ThemeEditor")
return;

InGameUtil.Instantiate();

RegisterCustomManagers();

IsGameLoaded = false;

if (BuildConfig.applicationVersion != BuildConfig.VersionToString(
Expand Down Expand Up @@ -247,7 +215,7 @@ public override void OnLevelLoaded(LoadMode mode) {
IsGameLoaded = true;

//it will replace stock PathManager or already Replaced before HotReload
if (!IsPathManagerReplaced || TrafficManagerMod.Instance.InGameHotReload) {
if (!IsPathManagerReplaced || TrafficManagerMod.InGameHotReload) {
try {
Log.Info("Pathfinder Compatible. Setting up CustomPathManager and SimManager.");
FieldInfo pathManagerInstance = typeof(Singleton<PathManager>).GetField(
Expand Down Expand Up @@ -278,17 +246,14 @@ public override void OnLevelLoaded(LoadMode mode) {

pathManagerInstance.SetValue(null, CustomPathManager);

Log._Debug("Getting Current SimulationManager");
var simManager = this.simManager;
if (simManager == null) {
throw new Exception("simManager is null");
}
Log._Debug("Getting Current SimulationManagers");
var simManagers = GetSimManagers();

Log._Debug("Removing Stock PathManager");
simManager.Remove(stockPathManager);
simManagers.Remove(stockPathManager);

Log._Debug("Adding Custom PathManager");
simManager.Add(CustomPathManager);
simManagers.Add(CustomPathManager);

Object.Destroy(stockPathManager, 10f);

Expand Down Expand Up @@ -318,22 +283,14 @@ public override void OnLevelLoaded(LoadMode mode) {

ModUI.OnLevelLoaded();
if (PlayMode) {
// Init transport demand UI
if (TransportDemandUI == null) {
UIView uiView = UIView.GetAView();
TransportDemandUI = (UITransportDemand)uiView.AddUIComponent(typeof(UITransportDemand));
}

// add "remove vehicle" button
UIView.GetAView().gameObject.AddComponent<RemoveVehicleButtonExtender>();

// add "remove citizen instance" button
UIView.GetAView().gameObject.AddComponent<RemoveCitizenInstanceButtonExtender>();

UIView.GetAView().gameObject.AddComponent<RoadSelectionPanels>();
UIView uiView = UIView.GetAView();
uiView.AddUIComponent(typeof(UITransportDemand));
uiView.gameObject.AddComponent<RemoveVehicleButtonExtender>();
uiView.gameObject.AddComponent<RemoveCitizenInstanceButtonExtender>();
uiView.gameObject.AddComponent<RoadSelectionPanels>();
}

Patcher.Create().Install();
Patcher.Install();

// Log.Info("Fixing non-created nodes with problems...");
// FixNonCreatedNodeProblems();
Expand Down
60 changes: 18 additions & 42 deletions TLM/TLM/Patcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,10 @@ namespace TrafficManager {
using TrafficManager.RedirectionFramework;
using TrafficManager.Util;

public class Patcher {
public static Patcher Instance { get; private set; }

public static Patcher Create() => Instance = new Patcher();

public static class Patcher {
private const string HARMONY_ID = "de.viathinksoft.tmpe";

private bool initialized_ = false;

public void Install() {
if (initialized_) {
return;
}

public static void Install() {
Log.Info("Init detours");
bool fail = false;

Expand All @@ -31,10 +21,8 @@ public void Install() {
Harmony.DEBUG = true;
#endif
// Harmony attribute-driven patching
Log.Info($"Performing Harmony attribute-driven patching");
var harmony = new Harmony(HARMONY_ID);
Shortcuts.Assert(harmony != null, "HarmonyInst!=null");
harmony.PatchAll();
Log.Info($"Performing Harmony attribute-driven patches");
new Harmony(HARMONY_ID).PatchAll();
Log.Info($"Harmony attribute-driven patching successfull!");
}
catch (Exception e) {
Expand All @@ -56,36 +44,24 @@ public void Install() {
}

if (fail) {
Log.Info("Detours failed");
Singleton<SimulationManager>.instance.m_ThreadingWrapper.QueueMainThread(
() => {
UIView.library
.ShowModal<ExceptionPanel>("ExceptionPanel")
.SetMessage(
"TM:PE failed to load",
"Traffic Manager: President Edition failed to load. You can " +
"continue playing but it's NOT recommended. Traffic Manager will " +
"not work as expected.",
true);
});
Log.Info("patcher failed");
UIView.library
.ShowModal<ExceptionPanel>("ExceptionPanel")
.SetMessage(
"TM:PE failed to load",
"Traffic Manager: President Edition failed to load. You can " +
"continue playing but it's NOT recommended. Traffic Manager will " +
"not work as expected.",
true);
} else {
Log.Info("Detours successful");
Log.Info("TMPE patches installed successfully");
}

initialized_ = true;
}

public void Uninstall() {
if (!initialized_) {
return;
}

var harmony = new Harmony(HARMONY_ID);
Shortcuts.Assert(harmony != null, "HarmonyInst!=null");
harmony.UnpatchAll(HARMONY_ID);

initialized_ = false;
Log.Info("Reverting detours finished.");
public static void Uninstall() {
new Harmony(HARMONY_ID).UnpatchAll(HARMONY_ID);
AssemblyRedirector.Revert();
Log.Info("TMPE patches uninstalled.");
}
}
}
2 changes: 1 addition & 1 deletion TLM/TLM/State/Options.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ internal static void RebuildMenu() {
}
}

public static void MakeSettings(UIHelperBase helper) {
public static void MakeSettings(UIHelper helper) {
ExtUITabstrip tabStrip = ExtUITabstrip.Create(helper);
OptionsGeneralTab.MakeSettings_General(tabStrip);
OptionsGameplayTab.MakeSettings_Gameplay(tabStrip);
Expand Down
Loading