Started on environment, This is for #5

This commit is contained in:
James Clancey 2019-06-28 15:00:29 -08:00
Родитель 61a73c9600
Коммит 37968357ac
5 изменённых файлов: 206 добавлений и 2 удалений

Просмотреть файл

@ -5,6 +5,8 @@ using System.Linq;
namespace HotUI {
public class View {
internal static readonly EnvironmentData Environment = new EnvironmentData ();
internal readonly EnvironmentData Context = new EnvironmentData ();
View parent;
public View Parent {
get => parent;
@ -23,6 +25,7 @@ namespace HotUI {
protected State State { get; set; }
public View (bool hasConstructors)
{
Context.View = this;
State = StateBuilder.CurrentState ?? new State {
StateChanged = ResetView
};
@ -77,7 +80,7 @@ namespace HotUI {
State.SetParent (this);
State.StartProperty ();
var view = Body.Invoke ();
view.Parent = this.Parent;
view.Parent = this;
var props = State.EndProperty ();
var propCount = props.Length;
if (propCount > 0) {
@ -99,5 +102,13 @@ namespace HotUI {
#endif
ViewHandler?.UpdateValue (property, value);
}
public static void SetGlobalEnvironment (string key, object value) => Environment.SetValue (key, value);
public static void SetGlobalEnvironment (IDictionary<string, object> data)
{
foreach(var pair in data)
Environment.SetValue (pair.Key, pair.Value);
}
public static T GetGlobalEnvironment<T> (string key) => Environment.GetValue<T> (key);
}
}

Просмотреть файл

@ -0,0 +1,52 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace HotUI {
public static class EnvironmentKeys {
public const string DocumentsFolder = "DocumentsFolder";
public const string UserFolder = "UserFolder";
public const string OS = "OS";
}
class EnvironmentData : BindingObject {
public View View { get; internal set; }
protected ICollection<string> GetAllKeys ()
{
//This is the global Environment
if (View?.Parent == null)
return dictionary.Keys;
//TODO: we need a fancy way of collapsing this. This may be too slow
var keys = new HashSet<string> ();
var localKeys = dictionary?.Keys;
if (localKeys != null)
foreach (var k in localKeys)
keys.Add (k);
var parentKeys = View?.Parent?.Context?.GetAllKeys () ?? View.Environment.GetAllKeys ();
if (parentKeys != null)
foreach (var k in parentKeys)
keys.Add (k);
return keys;
}
public T GetValue<T> (string key)
{
try {
var value = GetValue (key);
if (value == null)
value = View?.Parent?.Context?.GetValue (key) ?? View.Environment.GetValue (key);
return (T)value;
} catch (Exception ex) {
return default;
}
}
public void SetValue (string key, object value) => SetProperty (value, key);
}
}

Просмотреть файл

@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
namespace HotUI {
public static class ViewExtensions {
@ -7,6 +9,21 @@ namespace HotUI {
listview.ItemSelected = (o) => selected?.Invoke ((T)o);
return listview;
}
public static T SetEnvironment<T>(this T view, string key, object value) where T: View
{
view.Context.SetValue (key, value);
return view;
}
public static T SetEnvironment<T> (this T view, IDictionary<string, object> data) where T : View
{
foreach (var pair in data)
view.Context.SetValue (pair.Key, pair.Value);
return view;
}
public static T GetEnvironment<T> (this View view, string key) => view.Context.GetValue<T> (key);
}
}

3
src/HotUI/HotUI.cs Normal file
Просмотреть файл

@ -0,0 +1,3 @@
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo ("HotUI.Tests")]

Просмотреть файл

@ -0,0 +1,121 @@
using System;
using Xunit;
namespace HotUI.Tests {
public class EnvironmentTests {
[Fact]
public void CanSetAndReadGlobalEnvironment()
{
View.Environment.dictionary.Clear ();
const string myStringConstant = "myString";
const string myStringKey = "myString";
//Not set so should be null
var environmentEntry = View.GetGlobalEnvironment<string> (myStringKey);
Assert.Null (environmentEntry);
View.SetGlobalEnvironment (myStringKey, myStringConstant);
environmentEntry = View.GetGlobalEnvironment<string> (myStringKey);
Assert.Equal (myStringConstant, environmentEntry);
}
[Fact]
public void CanSetAndReadGlobalEnvironmentFromView ()
{
const string myStringConstant = "myString";
const string myStringKey = "myString";
View.SetGlobalEnvironment (myStringKey, myStringConstant);
var myView = new View ();
var environmentEntry = myView.GetEnvironment<string> (myStringKey);
Assert.Equal (myStringConstant, environmentEntry);
}
[Fact]
public void ViewEnvironmentOverwritesGlobal ()
{
const string myStringConstant = "myString";
const string myStringKey = "myString";
const string parentStringValue = "myParentString";
View.SetGlobalEnvironment (myStringKey, myStringConstant);
var myView = new View ().SetEnvironment(myStringKey,parentStringValue);
var environmentEntry = myView.GetEnvironment<string> (myStringKey);
Assert.Equal (parentStringValue, environmentEntry);
}
[Fact]
public void NestedViewGetsValueFromParent ()
{
const string myStringConstant = "myString";
const string myStringKey = "myString";
const string parentStringValue = "myParentString";
View.SetGlobalEnvironment (myStringKey, myStringConstant);
Text text = null;
var view = new View {
Body = () => (text = new Text ())
}.SetEnvironment(myStringKey, parentStringValue);
var viewHandler = new GenericViewHandler ();
view.ViewHandler = viewHandler;
var textHandler = new GenericViewHandler ();
text.ViewHandler = textHandler;
var environmentEntry = text.GetEnvironment<string> (myStringKey);
Assert.Equal (parentStringValue, environmentEntry);
}
[Fact]
public void NestedViewGetsIts ()
{
const string myStringConstant = "myString";
const string myStringKey = "myString";
const string parentStringValue = "myParentString";
const string testStringValue = "myTextString";
View.SetGlobalEnvironment (myStringKey, myStringConstant);
Text text1 = null;
Text text2 = null;
var view = new View {
Body = () => new VStack {
(text1 = new Text ().SetEnvironment(myStringKey,testStringValue)),
(text2 = new Text ())
}.SetEnvironment (myStringKey, parentStringValue)
};
var viewHandler = new GenericViewHandler ();
view.ViewHandler = viewHandler;
var text1Value = text1.GetEnvironment<string> (myStringKey);
Assert.Equal (testStringValue, text1Value);
var text2Value = text2.GetEnvironment<string> (myStringKey);
Assert.Equal (parentStringValue, text2Value);
}
}
}