From 93e191f522fbb22bc094e2e9dae37b92858f2d96 Mon Sep 17 00:00:00 2001 From: chylex <contact@chylex.com> Date: Thu, 5 Apr 2018 03:34:11 +0200 Subject: [PATCH] Reorganize hot swap code & add support for hot swapping plugins --- Resources/ScriptLoader.cs | 130 ++++++++++++++++++++++---------------- Resources/Scripts/code.js | 2 + 2 files changed, 78 insertions(+), 54 deletions(-) diff --git a/Resources/ScriptLoader.cs b/Resources/ScriptLoader.cs index c30c0ed7..4393d722 100644 --- a/Resources/ScriptLoader.cs +++ b/Resources/ScriptLoader.cs @@ -7,63 +7,13 @@ using TweetDuck.Core.Other; #if DEBUG using System.Diagnostics; +using System.Reflection; +using TweetDuck.Core; +using TweetDuck.Plugins; #endif namespace TweetDuck.Resources{ static class ScriptLoader{ - private const string UrlPrefix = "td:"; - - #if DEBUG - private static readonly string HotSwapProjectRoot = FixPathSlash(Path.GetFullPath(Path.Combine(Program.ProgramPath, "../../../"))); - private static readonly string HotSwapTargetDir = FixPathSlash(Path.Combine(HotSwapProjectRoot, "bin", "tmp")); - private static readonly string HotSwapRebuildScript = Path.Combine(HotSwapProjectRoot, "Resources", "PostBuild.ps1"); - - // TODO figure out hotswap support for plugins and scripts/plugins.* files - - static ScriptLoader(){ - if (File.Exists(HotSwapRebuildScript)){ - Debug.WriteLine("Activating resource hot swap"); - - ResetHotSwap(); - Application.ApplicationExit += (sender, args) => ResetHotSwap(); - } - } - - public static void HotSwap(){ - if (!File.Exists(HotSwapRebuildScript)){ - Debug.WriteLine("Failed resource hot swap, missing rebuild script: "+HotSwapRebuildScript); - return; - } - - ResetHotSwap(); - Directory.CreateDirectory(HotSwapTargetDir); - - using(Process process = Process.Start(new ProcessStartInfo{ - FileName = "powershell", - Arguments = $"-ExecutionPolicy Unrestricted -File \"{HotSwapRebuildScript}\" \"{HotSwapTargetDir}\\\" \"{HotSwapProjectRoot}\\\" \"{Program.VersionTag}\"", - WindowStyle = ProcessWindowStyle.Hidden - })){ - // ReSharper disable once PossibleNullReferenceException - if (!process.WaitForExit(8000)){ - Debug.WriteLine("Failed resource hot swap, script did not finish in time"); - } - else if (process.ExitCode != 0){ - Debug.WriteLine("Failed resource hot swap, script exited with code "+process.ExitCode); - } - } - } - - private static void ResetHotSwap(){ - try{ - Directory.Delete(HotSwapTargetDir, true); - }catch(DirectoryNotFoundException){} - } - - private static string FixPathSlash(string path){ - return path.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)+'\\'; - } - #endif - public static string LoadResource(string name, bool silent = false, Control sync = null){ try{ string path = Program.ScriptPath; @@ -110,7 +60,7 @@ public static bool ExecuteFile(IFrame frame, string file, Control sync = null){ public static void ExecuteScript(IFrame frame, string script, string identifier){ if (script != null){ - frame.ExecuteJavaScriptAsync(script, UrlPrefix+identifier, 1); + frame.ExecuteJavaScriptAsync(script, "td:"+identifier, 1); } } @@ -130,5 +80,77 @@ private static void ShowLoadError(bool silent, Control sync, string message){ sync.InvokeSafe(() => FormMessage.Error("Resource Error", message, FormMessage.OK)); } } + + #if DEBUG + private static readonly string HotSwapProjectRoot = FixPathSlash(Path.GetFullPath(Path.Combine(Program.ProgramPath, "../../../"))); + private static readonly string HotSwapTargetDir = FixPathSlash(Path.Combine(HotSwapProjectRoot, "bin", "tmp")); + private static readonly string HotSwapRebuildScript = Path.Combine(HotSwapProjectRoot, "Resources", "PostBuild.ps1"); + + static ScriptLoader(){ + if (File.Exists(HotSwapRebuildScript)){ + Debug.WriteLine("Activating resource hot swap"); + + ResetHotSwap(); + Application.ApplicationExit += (sender, args) => ResetHotSwap(); + } + } + + public static void HotSwap(){ + if (!File.Exists(HotSwapRebuildScript)){ + Debug.WriteLine("Failed resource hot swap, missing rebuild script: "+HotSwapRebuildScript); + return; + } + + ResetHotSwap(); + Directory.CreateDirectory(HotSwapTargetDir); + + using(Process process = Process.Start(new ProcessStartInfo{ + FileName = "powershell", + Arguments = $"-ExecutionPolicy Unrestricted -File \"{HotSwapRebuildScript}\" \"{HotSwapTargetDir}\\\" \"{HotSwapProjectRoot}\\\" \"{Program.VersionTag}\"", + WindowStyle = ProcessWindowStyle.Hidden + })){ + // ReSharper disable once PossibleNullReferenceException + if (!process.WaitForExit(8000)){ + Debug.WriteLine("Failed resource hot swap, script did not finish in time"); + return; + } + else if (process.ExitCode != 0){ + Debug.WriteLine("Failed resource hot swap, script exited with code "+process.ExitCode); + return; + } + } + + // Force update plugin manager setup scripts + + string newPluginRoot = Path.Combine(HotSwapTargetDir, "plugins"); + + const BindingFlags flagsInstance = BindingFlags.Instance | BindingFlags.NonPublic; + const BindingFlags flagsStatic = BindingFlags.Static | BindingFlags.NonPublic; + + Type typePluginManager = typeof(PluginManager); + Type typeFormBrowser = typeof(FormBrowser); + + // ReSharper disable PossibleNullReferenceException + object pluginSetupScripts = typePluginManager.GetMethod("LoadSetupScripts", flagsStatic).Invoke(null, new object[0]); + typePluginManager.GetField("PluginSetupScripts", flagsStatic).SetValue(null, pluginSetupScripts); + + object instPluginManager = typeFormBrowser.GetField("plugins", flagsInstance).GetValue(FormManager.TryFind<FormBrowser>()); + typePluginManager.GetField("rootPath", flagsInstance).SetValue(instPluginManager, newPluginRoot); + + Debug.WriteLine("Reloading hot swapped plugins..."); + ((PluginManager)instPluginManager).Reload(); + // ReSharper restore PossibleNullReferenceException + } + + private static void ResetHotSwap(){ + try{ + Directory.Delete(HotSwapTargetDir, true); + }catch(DirectoryNotFoundException){} + } + + private static string FixPathSlash(string path){ + return path.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)+'\\'; + } + #endif } } diff --git a/Resources/Scripts/code.js b/Resources/Scripts/code.js index 9b809acc..8aa6e3a7 100644 --- a/Resources/Scripts/code.js +++ b/Resources/Scripts/code.js @@ -1369,6 +1369,8 @@ window.gc && window.gc(); window.location.reload(); }); + + window.TDGF_reload = function(){}; // redefine to prevent reloading multiple times }; if (window.TD_SESSION && window.TD_SESSION.gc){