Skip to content

Commit

Permalink
Add colored logs, fix ScreenId generator
Browse files Browse the repository at this point in the history
  • Loading branch information
neilsarkar committed Jul 25, 2020
1 parent 2d62f77 commit 7483c1c
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 31 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.2.0] - 2020-07-25

### Added
- Navigator
- Screen

## [0.1.42] - 2020-07-21

### Added
- ChildView
- StateMonobehaviour

## [0.1.0] - 2020-07-19

### Added
Expand Down
7 changes: 1 addition & 6 deletions Editor/ScreenEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,10 @@ public static class ScreenEditor {
private static GUIStyle singleStyle, leftStyle, rightStyle;

static Navigator navigator;
static Color violet = new Color(0.898f, 0.745f, 0.935f);
static Color saturatedViolet;

static ScreenEditor() {
EditorApplication.hierarchyWindowItemOnGUI -= DrawHierarchyItem;
EditorApplication.hierarchyWindowItemOnGUI += DrawHierarchyItem;
float h,s,v;
Color.RGBToHSV(violet, out h, out s, out v);
saturatedViolet = Color.HSVToRGB(h, 1f, 1f);
}

static void DrawHierarchyItem(int instanceID, Rect rect) {
Expand Down Expand Up @@ -86,7 +81,7 @@ static bool Button(Rect rect, string label, bool isActive = false) {

// set color to violet if active
var originalColor = GUI.color;
GUI.color = isActive ? violet : originalColor;
GUI.color = isActive ? Violet.Hue : originalColor;
var response = GUI.Button(rect, new GUIContent(label), style);
GUI.color = originalColor;

Expand Down
3 changes: 2 additions & 1 deletion Runtime/Exceptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ public Bail(string message) : base(message) { }
}

public class VioletException : Exception {
public VioletException(string message) : base(message) { }
public VioletException(string message) :
base($"{Violet.Color("VioletUI")} | {message}") { }
}

public class VioletEnumException : VioletException {
Expand Down
19 changes: 9 additions & 10 deletions Runtime/Navigation/Navigator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@

namespace VioletUI {
/// <summary>
/// Screens maintains a map of <see cref="ScreenId"/> enum to menu screens.
/// Navigator maintains a map of <see cref="ScreenId"/> enum to menu screens.
///
/// It is primarily used to navigate between screens, and also exposes the <see cref="OnWillVisit"/> and <seealso cref="OnDidVisit"/> lifecycle events.
/// It is used to navigate between screens and exposes <see cref="OnWillLeave"/>, <see cref="OnDidLeave" />, <see cref="OnWillVisit"/>, and <see cref="OnDidVisit"/>.
/// </summary>
[ExecuteAlways]
public class Navigator : TidyBehaviour {
Expand Down Expand Up @@ -46,15 +46,14 @@ void Awake() {
VisitFirstScreen();
}
void LoadScreens() {
if (transform.childCount == 0) {
throw new Exception($"Tried to create a NavigationController with no children - try adding some NavigationScreens to {gameObject.name}");
}
if (transform.childCount == 0) { return; }

ScreenId screenId = ScreenId.None;
foreach (Screen screen in GetComponentsInChildren<Screen>(true)) {
var isValid = Enum.TryParse(screen.name, out screenId);
if (!isValid) {
throw new VioletException($"{screen.name} does not have a valid ScreenId. Make sure this screen is added to MenuBuilder.");
RegenerateEnums();
throw new VioletException($"{screen.name} does not have a valid ScreenId.");
}

if (hasCamera) {
Expand Down Expand Up @@ -82,7 +81,7 @@ void LoadScreens() {
/// <param name="screenId"></param>
public async void Visit(ScreenId screenId) {
if (!screens.ContainsKey(screenId)) {
throw new Exception($"Tried to visit {screenId} but it doesn't exist in the current scene. You'll want to add the {screenId} prefab to this scene or to the MenuBuilder prefab. Or change the Home Screen to the screen you want.");
throw new VioletException($"Tried to visit {screenId} but it doesn't exist in the current scene. You'll want to add the {screenId} prefab to this scene or to the MenuBuilder prefab. Or change the Home Screen to the screen you want.");
}

// if we're currently in a transition, cancel the transition and run OnHide/OnShow immediately
Expand Down Expand Up @@ -142,7 +141,7 @@ public void Visit(string screenIdString) {
ScreenId screenId;
var isValid = Enum.TryParse<ScreenId>(screenIdString.Replace(" ", ""), out screenId);
if (!isValid) {
throw new Exception($"Couldn't find a screen with the id {screenIdString.Replace(" ", "")}. Please check the spelling.");
throw new VioletException($"Couldn't find a screen with the id {screenIdString.Replace(" ", "")}. Please check the spelling.");
}
Visit(screenId);
}
Expand All @@ -151,7 +150,7 @@ public void ShowModal (string screenIdString) {
ScreenId screenId;
var isValid = Enum.TryParse<ScreenId>(screenIdString.Replace(" ", ""), out screenId);
if (!isValid) {
throw new Exception($"Couldn't find a screen with the id {screenIdString.Replace(" ", "")}. Please check the spelling.");
throw new VioletException($"Couldn't find a screen with the id {screenIdString.Replace(" ", "")}. Please check the spelling.");
}

ShowModal(screenId);
Expand Down Expand Up @@ -181,7 +180,7 @@ public void Edit(Screen screen) {
homeScreen = ScreenToScreenId(screen);
} catch (VioletEnumException) {
ScreenIdGenerator.Generate(screen);
Debug.LogWarning($"VioletUI - Couldn't find {screen.name} in the ScreenId enum. This should be fixed if you try your action again. If not, please report a bug.");
Violet.LogWarning($"Couldn't find {screen.name} in the ScreenId enum. This should be fixed if you hit edit again. If not, please report a bug.");
return;
}

Expand Down
2 changes: 1 addition & 1 deletion Runtime/Navigation/ScreenId.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//Names are automatically added through ScreenIdGenerator.cs, deletions are done manually :)
namespace VioletUI {
public enum ScreenId {
None = 0
None = 0,
}
}
27 changes: 24 additions & 3 deletions Runtime/Navigation/ScreenIdGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEditor;
using UnityEditor.Compilation;
using UnityEngine;

namespace VioletUI {
Expand All @@ -30,10 +32,11 @@ public static void Generate(List<string> screens) {

static List<string> Filter(List<string> screens) {
var ret = new List<string>();
foreach (var screen in screens) {
foreach (var screen in screens.Distinct()) {
if (screen == null) { continue; }
var name = sanitize(screen);
if (Enum.TryParse<ScreenId>(screen, out _)) { continue; }
if (Enum.TryParse<ScreenId>(name, out _)) { continue; }
Violet.Log($"Adding new screen to enum - {name}");
ret.Add(name);
}
return ret;
Expand All @@ -60,13 +63,31 @@ static void AddScreens(List<string> screens) {
}
sb.AppendLine("\t}");
sb.AppendLine("}");
string path = Path.GetFullPath("Packages/violetui/Runtime/Navigation/ScreenId.cs");
string path = $"{packagePath()}/Runtime/Navigation/ScreenId.cs";
File.WriteAllText(path, sb.ToString());
Violet.Log("Regenerating the ScreenId enum, this may take a second to recompile.");
AssetDatabase.Refresh();
}

static string sanitize(string s) {
return s.Replace(" ", "");
}

static string scriptPath() {
return null;
}
static string packagePath() {
foreach (var path in packagePaths) {
var paths = Directory.GetDirectories(path, "*violetui*", SearchOption.TopDirectoryOnly);
if (paths.Length > 0) { return paths[0];}
}
throw new VioletException("Can't find violetui in Library/PackageCache or Packages. Please report a bug.");
}
static string[] packagePaths = new string[] {
Path.GetFullPath("Library/PackageCache"),
Path.GetFullPath("Packages")
};
}
}


7 changes: 5 additions & 2 deletions Runtime/StateMonoBehaviour.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@

namespace VioletUI {
[ExecuteAlways]
public abstract class StateMonoBehaviour<TState> : TidyBehaviour where TState : class, IState {
public static StateMonoBehaviour<TState> Singleton;
public abstract class StateMonobehaviour<TState> : TidyBehaviour where TState : class, IState {
public static StateMonobehaviour<TState> Singleton;

public TState State;
[NonSerialized, HideInInspector] public TState LastState;
Expand All @@ -30,16 +30,19 @@ public Dispatcher<TState> Dispatcher {
public class View : View<TState> {
protected override TState State => Singleton?.State;
protected override TState LastState => Singleton?.LastState;
protected override Dispatcher<TState> Dispatcher => Dispatcher;
}

public abstract class RepeatView<T> : RepeatView<TState, T> {
protected override TState State => Singleton?.State;
protected override TState LastState => Singleton?.LastState;
protected override Dispatcher<TState> Dispatcher => Dispatcher;
}

public abstract class ChildView<T> : ChildView<TState, T> {
protected override TState State => Singleton?.State;
protected override TState LastState => Singleton?.LastState;
protected override Dispatcher<TState> Dispatcher => Dispatcher;
}

void Awake() {
Expand Down
28 changes: 20 additions & 8 deletions Runtime/Views/View.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
namespace VioletUI {
[ExecuteAlways]
public abstract class View<TState> : TidyBehaviour where TState : class, IState {
/// <summary>
/// A view requires a reference to State and LastState.
/// </summary>
/// <value></value>
protected abstract TState State { get; }
protected abstract TState LastState { get; }

Expand All @@ -18,7 +22,7 @@ protected virtual void OnShow() { }
/// </summary>
protected virtual void OnHide() { }
/// <summary>
/// ShouldRender is used to short circuit expensive render calls by focusing on parts of the state you care about.
/// IsDirty is used to short circuit expensive render calls by focusing on parts of the state you care about.
///
/// return `false` to avoid rendering
/// </summary>
Expand All @@ -32,13 +36,21 @@ protected virtual void OnHide() { }
/// <param name="state"></param>
protected virtual void Render(TState state) { }

Dispatcher<TState> m_dispatcher;
protected Dispatcher<TState> dispatcher {
/// <summary>
/// dispatcher allows you to send Actions that
/// </summary>
protected virtual Dispatcher<TState> Dispatcher {
get {
if (m_dispatcher == null) { m_dispatcher = new Dispatcher<TState>(State, LastState); }
return m_dispatcher;
if (dispatcher == null) { dispatcher = new Dispatcher<TState>(State, LastState); }
return dispatcher;
}
}
Dispatcher<TState> dispatcher;

// convenience methods for logging in views
protected void Log(string s) { Violet.Log(s); }
protected void LogWarning(string s) { Violet.LogWarning(s); }
protected void LogError(string s) { Violet.LogError(s); }

// Internal methods are so that callers don't have to remember to call base. at the beginning of their implementations
internal virtual void OnShowInternal() {}
Expand Down Expand Up @@ -96,20 +108,20 @@ void OnDisable() {

void Warn(string msg) {
#if VIOLETDEV
UnityEngine.Debug.LogWarning(msg);
Violet.LogWarning(msg);
#endif
}

void Verbose(string msg) {
#if VIOLETDEV && VIOLET_VERBOSE
UnityEngine.Debug.Log(msg);
Violet.Log(msg);
#endif
}

#if UNITY_EDITOR
public virtual void Update() {
if (Application.isPlaying) { return; }
if (State == null) { Debug.LogWarning("State is null"); return; }
if (State == null) { Warn("State is null"); return; }
State.OnChange -= State_OnChange;
State.OnChange += State_OnChange;
}
Expand Down
36 changes: 36 additions & 0 deletions Runtime/Violet.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using UnityEngine;

/// <summary>
/// Static utility methods
/// </summary>
public static class Violet {
public static void Log(string s) {
Debug.Log($"{Color("VioletUI")} | {s}");
}

public static void LogWarning(string s) {
Debug.LogWarning($"{Color("VioletUI")} | {s}");
}

public static void LogError(string s) {
Debug.LogError($"{Color("VioletUI")} | {s}");
}

// #ceb2da
// hsl(282, 35%, 78%)
public static Color Hue = new Color(0.898f, 0.745f, 0.935f);

// #b300ff
// rgb(179, 0, 255)
// hsl(282, 100%, 50%)
public static Color BrightHue = new Color(179/255, 0, 1);
/// <summary>
/// Wraps `s` in <color> tags for printing to unity console
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static string Color(string s, string hex = "b300ff") {
return $"<color=#{hex}>{s}</color>";
}

}
11 changes: 11 additions & 0 deletions Runtime/Violet.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 7483c1c

Please sign in to comment.