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

Lifecycle part 1 - IUserMod #773

Closed
wants to merge 2 commits into from
Closed
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
112 changes: 112 additions & 0 deletions TLM/TLM/Lifecycle.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
namespace TrafficManager {
using CSUtil.Commons;
using ICities;
using TrafficManager.State;
using TrafficManager.UI;

/// <summary>
/// This class manages the lifecycle of TMPE mod.
///
/// It also serves as an initial design draft for HarmonyLifecycle mod.
/// Code commenting is verbose; that would get moved to docs somwhere.
/// </summary>
public class Lifecycle { // : ILifecycle

/// <summary>
/// The Lifecycle instance; may be <c>null</c>.
/// </summary>
private static Lifecycle instance_;

/// <summary>
/// Gets the <see cref="Lifecycle"/> instance (creates one if necessary).
/// </summary>
public static Lifecycle Instance => instance_ ?? (instance_ = new Lifecycle());

/// <summary>
/// Called when the mod is enabled in one of the following ways:
///
/// * Manually in Content Manager > Mods
/// * Already enabled when Cities.exe starts
/// * Auto-enabled upon subscription, by the Mod Autoenabler mod
/// * Hot reload of a dev build.
/// </summary>
///
/// <param name="hotLoad">If <c>true</c>, the mod was enabled due to hot reload.</param>
public void OnEnabled(bool hotLoad) {
if (hotLoad) {
Log.Info("HOT RELOAD");
} else {
Temp.LogEnvironmentDetails();
}
}

/// <summary>
/// Called when locale needs updating:
///
/// * Before OnSettings(), if not already called
/// * When user changes game language.
///
/// Note that lanauge mods often use non-standard language codes such as:
///
/// * jaex --> ja
/// * zh-cn --> zh
/// * kr --> ko.
/// </summary>
///
/// <param name="locale">A string representing the language code.</param>
public void OnLocaleChange(string locale) {
Translation.HandleGameLocaleChange();
}

/// <summary>
/// Called when the game wants the mod to create its settings UI:
///
/// * When mod is first enabled
/// * Each time a city is loaded.
///
/// The <paramref name="inGame"/> parameter can be used to adapt your settings
/// screen depending on whether it's in-game or not.
/// </summary>
///
/// <param name="helper">The <see cref="UIHelperBase"/> instance used to create the UI.</param>
/// <param name="inGame">If <c>true</c>, the in-game settings screen should be created.</param>
public void OnSettings(UIHelperBase helper, bool inGame) {
// todo: instead of `inGame` bool, should we use an enum (or whatever) to
// differentiate between in-game, in scneario, in editor, etc?
// or have separate methods, eg. OnMainSettings(), OnGameSettings(), OnEditorSettings()?
Options.MakeSettings(helper);
}

/// <summary>
/// Called at an appropriate time to perform compatibility checks:
///
/// * PluginManager has processed all mods
/// * Intro screens have completed; UIView is available
/// * App localisation services are available
/// * NOT loading, unloading or exiting
/// * NOT in game or editor.
/// </summary>
///
/// <returns>Return <c>true</c> if environment is compatible, otherwise <c>false</c>.</returns>
public bool OnCompatibilityCheck() {
// todo: should we pass in game version as a `Version`?
return Temp.CheckCompatibility();
}


/// <summary>
/// Called when the mod is disabled in one of the following ways:
///
/// * Manually in Content Manager > Mods
/// * Unsubscribed while enabled
/// * Hot reload of dev build causes hot unload of current build
/// * Game exit to desktop.
/// </summary>
///
/// <param name="hotUnload">If <c>true</c>, the mod was enabled due to hot reload.</param>
public void OnDisabled(bool hotUnload) {
Log.Info("TM:PE disabled.");
}

}
}
67 changes: 1 addition & 66 deletions TLM/TLM/LoadingExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -392,72 +392,7 @@ public override void OnLevelLoaded(LoadMode mode) {
case SimulationManager.UpdateMode.NewGameFromMap:
case SimulationManager.UpdateMode.NewGameFromScenario:
case SimulationManager.UpdateMode.LoadGame: {
if (BuildConfig.applicationVersion != BuildConfig.VersionToString(
TrafficManagerMod.GAME_VERSION,
false))
{
string[] majorVersionElms = BuildConfig.applicationVersion.Split('-');
string[] versionElms = majorVersionElms[0].Split('.');
uint versionA = Convert.ToUInt32(versionElms[0]);
uint versionB = Convert.ToUInt32(versionElms[1]);
uint versionC = Convert.ToUInt32(versionElms[2]);

Log.Info($"Detected game version v{BuildConfig.applicationVersion}");

bool isModTooOld = TrafficManagerMod.GAME_VERSION_A < versionA ||
(TrafficManagerMod.GAME_VERSION_A == versionA &&
TrafficManagerMod.GAME_VERSION_B < versionB);
// || (TrafficManagerMod.GameVersionA == versionA
// && TrafficManagerMod.GameVersionB == versionB
// && TrafficManagerMod.GameVersionC < versionC);

bool isModNewer = TrafficManagerMod.GAME_VERSION_A < versionA ||
(TrafficManagerMod.GAME_VERSION_A == versionA &&
TrafficManagerMod.GAME_VERSION_B > versionB);
// || (TrafficManagerMod.GameVersionA == versionA
// && TrafficManagerMod.GameVersionB == versionB
// && TrafficManagerMod.GameVersionC > versionC);

if (isModTooOld) {
string msg = string.Format(
"Traffic Manager: President Edition detected that you are running " +
"a newer game version ({0}) than TM:PE has been built for ({1}). " +
"Please be aware that TM:PE has not been updated for the newest game " +
"version yet and thus it is very likely it will not work as expected.",
BuildConfig.applicationVersion,
BuildConfig.VersionToString(TrafficManagerMod.GAME_VERSION, false));

Log.Error(msg);
Singleton<SimulationManager>.instance.m_ThreadingWrapper.QueueMainThread(
() => {
UIView.library
.ShowModal<ExceptionPanel>("ExceptionPanel")
.SetMessage(
"TM:PE has not been updated yet",
msg,
false);
});
} else if (isModNewer) {
string msg = string.Format(
"Traffic Manager: President Edition has been built for game version {0}. " +
"You are running game version {1}. Some features of TM:PE will not " +
"work with older game versions. Please let Steam update your game.",
BuildConfig.VersionToString(TrafficManagerMod.GAME_VERSION, false),
BuildConfig.applicationVersion);

Log.Error(msg);
Singleton<SimulationManager>
.instance.m_ThreadingWrapper.QueueMainThread(
() => {
UIView.library
.ShowModal<ExceptionPanel>("ExceptionPanel")
.SetMessage(
"Your game should be updated",
msg,
false);
});
}
}
Temp.CheckGameVersion();

IsGameLoaded = true;
break;
Expand Down
6 changes: 4 additions & 2 deletions TLM/TLM/TLM.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
Expand Down Expand Up @@ -143,12 +143,14 @@
<Compile Include="Custom\AI\CustomVehicleAI.cs" />
<Compile Include="Custom\Data\CustomVehicle.cs" />
<Compile Include="Geometry\Impl\SegmentEndId.cs" />
<Compile Include="Lifecycle.cs" />
<Compile Include="Manager\AbstractCustomManager.cs" />
<Compile Include="Manager\AbstractFeatureManager.cs" />
<Compile Include="Manager\AbstractGeometryObservingManager.cs" />
<Compile Include="Manager\Impl\ExtNodeManager.cs" />
<Compile Include="Manager\Impl\ExtSegmentEndManager.cs" />
<Compile Include="Manager\Impl\ExtSegmentManager.cs" />
<Compile Include="Temp.cs" />
<Compile Include="UI\Helpers\NodeLaneMarker.cs" />
<Compile Include="UI\Helpers\SegmentLaneMarker.cs" />
<Compile Include="UI\Helpers\ExtUITabStrip.cs" />
Expand Down Expand Up @@ -525,7 +527,7 @@
</ItemGroup>
<ItemGroup>
<Folder Include="Traffic\Data\" />
<Folder Include="U\MainMenu" />
<Folder Include="U\MainMenu\" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\TrafficLights\pedestrian_mode_1.png" />
Expand Down
150 changes: 150 additions & 0 deletions TLM/TLM/Temp.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
namespace TrafficManager {
using ColossalFramework;
using ColossalFramework.UI;
using CSUtil.Commons;
using System;
using System.Reflection;
using TrafficManager.Util;

/// <summary>
/// This class is a temporary place to put a bunch of stuff until a better place is found for it.
///
/// Much of this stuff will be replaced as part of PR #699.
/// </summary>
public class Temp {

/// <summary>
/// Logs some info about TMPE build, mono version, etc.
/// </summary>
public static void LogEnvironmentDetails() {
LogBuildDetails();
LogTmpeGuid();
LogMonoVersion();
}

/// <summary>
/// Log TMPE build info and what game ver it expects.
/// </summary>
public static void LogBuildDetails() {
Log.InfoFormat(
"TM:PE enabled. Version {0}, Build {1} {2} for game version {3}.{4}.{5}-f{6}",
TrafficManagerMod.VersionString,
Assembly.GetExecutingAssembly().GetName().Version,
TrafficManagerMod.BRANCH,
TrafficManagerMod.GAME_VERSION_A,
TrafficManagerMod.GAME_VERSION_B,
TrafficManagerMod.GAME_VERSION_C,
TrafficManagerMod.GAME_VERSION_BUILD);
}

/// <summary>
/// Log TMPE Guid.
/// </summary>
public static void LogTmpeGuid() {
Log.InfoFormat(
"Enabled TM:PE has GUID {0}",
Assembly.GetExecutingAssembly().ManifestModule.ModuleVersionId);
}

/// <summary>
/// Log Mono version.
/// </summary>
public static void LogMonoVersion() {
// Log Mono version
Type monoRt = Type.GetType("Mono.Runtime");
if (monoRt != null) {
MethodInfo displayName = monoRt.GetMethod(
"GetDisplayName",
BindingFlags.NonPublic | BindingFlags.Static);
if (displayName != null) {
Log.InfoFormat("Mono version: {0}", displayName.Invoke(null, null));
}
}
}

/// <summary>
/// Run compatibility checker.
/// </summary>
///
/// <returns>Returns <c>false</c> if issues found, otherwise <c>true</c>.</returns>
public static bool CheckCompatibility() {
ModsCompatibilityChecker mcc = new ModsCompatibilityChecker();
mcc.PerformModCheck();
return true; // ideally this would return false if there are compatibility issues (#699 will sort that)
}

/// <summary>
/// Checks to see if game version is what TMPE expects, and if not warns users.
///
/// This will be replaced as part of #699.
/// </summary>
public static void CheckGameVersion() {
if (BuildConfig.applicationVersion != BuildConfig.VersionToString(
TrafficManagerMod.GAME_VERSION,
false)) {
string[] majorVersionElms = BuildConfig.applicationVersion.Split('-');
string[] versionElms = majorVersionElms[0].Split('.');
uint versionA = Convert.ToUInt32(versionElms[0]);
uint versionB = Convert.ToUInt32(versionElms[1]);
uint versionC = Convert.ToUInt32(versionElms[2]);

Log.Info($"Detected game version v{BuildConfig.applicationVersion}");

bool isModTooOld = TrafficManagerMod.GAME_VERSION_A < versionA ||
(TrafficManagerMod.GAME_VERSION_A == versionA &&
TrafficManagerMod.GAME_VERSION_B < versionB);
// || (TrafficManagerMod.GameVersionA == versionA
// && TrafficManagerMod.GameVersionB == versionB
// && TrafficManagerMod.GameVersionC < versionC);

bool isModNewer = TrafficManagerMod.GAME_VERSION_A < versionA ||
(TrafficManagerMod.GAME_VERSION_A == versionA &&
TrafficManagerMod.GAME_VERSION_B > versionB);
// || (TrafficManagerMod.GameVersionA == versionA
// && TrafficManagerMod.GameVersionB == versionB
// && TrafficManagerMod.GameVersionC > versionC);

if (isModTooOld) {
string msg = string.Format(
"Traffic Manager: President Edition detected that you are running " +
"a newer game version ({0}) than TM:PE has been built for ({1}). " +
"Please be aware that TM:PE has not been updated for the newest game " +
"version yet and thus it is very likely it will not work as expected.",
BuildConfig.applicationVersion,
BuildConfig.VersionToString(TrafficManagerMod.GAME_VERSION, false));

Log.Error(msg);
Singleton<SimulationManager>.instance.m_ThreadingWrapper.QueueMainThread(
() => {
UIView.library
.ShowModal<ExceptionPanel>("ExceptionPanel")
.SetMessage(
"TM:PE has not been updated yet",
msg,
false);
});
} else if (isModNewer) {
string msg = string.Format(
"Traffic Manager: President Edition has been built for game version {0}. " +
"You are running game version {1}. Some features of TM:PE will not " +
"work with older game versions. Please let Steam update your game.",
BuildConfig.VersionToString(TrafficManagerMod.GAME_VERSION, false),
BuildConfig.applicationVersion);

Log.Error(msg);
Singleton<SimulationManager>
.instance.m_ThreadingWrapper.QueueMainThread(
() => {
UIView.library
.ShowModal<ExceptionPanel>("ExceptionPanel")
.SetMessage(
"Your game should be updated",
msg,
false);
});
}
}
}

}
}
Loading