diff --git a/src/HotUI/HotReloadHelper.cs b/src/HotUI/HotReloadHelper.cs new file mode 100644 index 00000000..3107a5a1 --- /dev/null +++ b/src/HotUI/HotReloadHelper.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; + +namespace HotUI { + public static class HotReloadHelper { + static HotReloadHelper() + { + IsEnabled = Debugger.IsAttached; + } + public static bool IsEnabled { get; set; } + + public static void Register(View view, params object[] parameters) + { + if (!IsEnabled) + return; + currentViews [view] = parameters; + } + + public static void UnRegister(View view) + { + if (!IsEnabled) + return; + currentViews.Remove (view); + } + + public static View GetReplacedView(View view) + { + if (!IsEnabled) + return view; + if (!replacedViews.TryGetValue (view.GetType ().FullName, out var newViewType)) + return view; + + currentViews.TryGetValue (view, out var parameters); + var newView = parameters?.Length > 0 ? Activator.CreateInstance (newViewType, args: parameters) : Activator.CreateInstance (newViewType); + //TODO: Apply state! + return (View)newView; + } + + static Dictionary replacedViews = new Dictionary (); + static Dictionary currentViews = new Dictionary (); + public static void RegisterReplacedView(string oldViewType, Type newViewType) + { + if (!IsEnabled) + return; + replacedViews [oldViewType] = newViewType; + } + public static void TriggerReload() + { + var roots = View.ActiveViews.Where (x => x.Parent == null).ToList(); + foreach(var view in roots) { + Device.InvokeOnMainThread (view.Reload); + } + } + } +} diff --git a/tests/HotUI.Tests/HotReloadTestsNoParameters.cs b/tests/HotUI.Tests/HotReloadTestsNoParameters.cs new file mode 100644 index 00000000..964c4368 --- /dev/null +++ b/tests/HotUI.Tests/HotReloadTestsNoParameters.cs @@ -0,0 +1,41 @@ +using System; +using Xunit; + +namespace HotUI.Tests { + public class HotReloadTests { + + public class MyOrgView : View { + public const string TextValue = "Hello!"; + public MyOrgView () + { + this.Body = () => new Text (TextValue); + } + } + public class MyNewView : View { + public const string TextValue = "Goodbye!"; + public MyNewView () + { + this.Body = () => new Text (TextValue); + } + } + + public HotReloadTests () + { + HotReloadHelper.IsEnabled = true; + } + + [Fact] + public void HotReloadRegisterReplacedViewReplacesView () + { + var orgView = new MyOrgView (); + var orgText = orgView.GetView () as Text; + Assert.Equal (MyOrgView.TextValue, orgText.Value); + + HotReloadHelper.RegisterReplacedView (typeof (MyOrgView).FullName, typeof (MyNewView)); + var newText = orgView.GetView () as Text; + + Assert.Equal (MyNewView.TextValue, newText.Value); + + } + } +} diff --git a/tests/HotUI.Tests/HotReloadWithParameters.cs b/tests/HotUI.Tests/HotReloadWithParameters.cs new file mode 100644 index 00000000..b5f6d640 --- /dev/null +++ b/tests/HotUI.Tests/HotReloadWithParameters.cs @@ -0,0 +1,41 @@ +using System; +using Xunit; + +namespace HotUI.Tests { + public class HotReloadWithParameters : TestBase { + public class MyOrgView : View { + public const string TextValue = "Hello!"; + public MyOrgView (string text) + { + HotReloadHelper.Register (this, text); + this.Body = () => new Text (text); + } + } + public class MyNewView : View { + public MyNewView (string text) + { + HotReloadHelper.Register (this, text); + this.Body = () => new Text (text); + } + } + + public HotReloadWithParameters () + { + HotReloadHelper.IsEnabled = true; + } + + [Fact] + public void HotReloadRegisterReplacedViewReplacesView () + { + var orgView = new MyOrgView (MyOrgView.TextValue); + var orgText = orgView.GetView () as Text; + Assert.Equal (MyOrgView.TextValue, orgText.Value); + + HotReloadHelper.RegisterReplacedView (typeof (MyOrgView).FullName, typeof (MyNewView)); + var newText = orgView.GetView () as Text; + + Assert.Equal (MyOrgView.TextValue, newText.Value); + + } + } +}