Skip to content

Commit

Permalink
cleanup and implementation of OnChange
Browse files Browse the repository at this point in the history
  • Loading branch information
Niikelion committed Dec 26, 2024
1 parent 8e4656a commit a11b51b
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 15 deletions.
2 changes: 2 additions & 0 deletions Documentation~/ui.lithium.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ To make it easier to use, `ComponentStateExtensions` provides a couple of method
* `MutableList<T> RememberList<T>(Func<IEnumerable<T>> factory)` - same as `RememberList(IEnumerable<T>)`, but uses `factory` to create initial value on first render.
* `MutableDictionary<TKey, TValue> RememberDictionary(IDictionary<TKey, TValue> dictionary = null)` - same as `Remember`, but stores dictionary instead of single value.
* `MutableDictionary<TKey, TValue> RememberDictionary(Func<IDictionary<TKey, TValue>> factory)` - same as `RememberDictionary(IDictionary<TKey, TValue>)`, but uses `factory` to create initial value of first render.
* `T Cache<T>(Func<T> factory, params object[] vars)` - uses `factory` to create value, only recalculates when content of vars changes between renders.

### Callbacks

Expand All @@ -95,6 +96,7 @@ Available callback:
* `void OnInit(Action onInit)` - calls `onInit` on first render.
* `void OnDestroy(Action onDestroy)` - calls `onDestroy` before component is destroyed.
* `void OnInit(Func<Action> onInit)` - calls `onInit` on first render and then calls value returned by it before component is destroyed.
* `void OnChange(Action onChanged, params object[] vars)` - calls `onChanged` during render when any item of the `vars` array is not equal to corresponding item of `vars` from previous render. Can be used to call action when any of the dependencies changes.

### Contexts

Expand Down
4 changes: 2 additions & 2 deletions Editor/Debugging/Debugger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ private static IComponent ValueInspector(object value) => WithState(() =>
{
//TODO: https://docs.unity3d.com/6000.0/Documentation/Manual/UIE-runtime-binding-define-data-source.html
//TODO: use above guide to show editor for custom types without creating ScriptableObject instance
var property = UseMemo(() =>
var property = Cache(() =>
{
var instance = CreateInstance<GenericProperty>();

Expand Down Expand Up @@ -216,7 +216,7 @@ private static IComponent RenderNode(CompositionContext.InspectedNode node, int

var children = node.Children;

// NOTE: for some reason ui toolkit has a bug where height calculations are incorrect without wrapping element
//NOTE: for some reason ui toolkit has a bug where height calculations are incorrect without wrapping element
return Box(Switch(children.Count == 0, () =>
Text(name, manipulators: new Clickable(OnSelected))
.WithStyle(new(flexGrow: 1, padding: new(left: offset)))
Expand Down
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,11 @@ V1 roadmap:

V2 roadmap:

- [ ] implement `useMemo` / `useEffect` equivalent from ReactJS
- [x] implement `useMemo` equivalent from ReactJS(`Cache`)
- [x] implement `useEffect` equivalent from ReactJS(`OnUpdate`)
- [x] rework methods for inspecting composition context
- [ ] fully featured layout debugger with support for modifying variables and handling contexts
- [ ] async handling to make working with network resources and files easier
- [x] fully featured layout debugger with support for modifying variables and handling contexts
- [x] basic async handling to make working with network resources and files easier
- [x] remove/hide OnRender event from `IComponent`
- [x] ensure support for unity tailwind
- [x] component for stylesheet loading
Expand All @@ -103,11 +104,12 @@ Future releases:

- [ ] optimization of styling system
- [ ] support for named variables
- [ ] pooling of `VisualElement`
- [ ] global pooling of `VisualElement`s
- [ ] pooling of components
- [ ] further caching optimizations
- [ ] visual ui builder
- [ ] static style extraction
- [ ] better async handling with tasks that can report status

## UI Elements interoperability

Expand Down
2 changes: 1 addition & 1 deletion Runtime/Async/Async.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class AsyncMutable<T> : IMutableValue
public bool HasError => task.IsFaulted;
public bool HasResult => task.IsCompletedSuccessfully;

public T Result => HasResult ? task.Result : throw new Exception("Value not ready!");
public T Result => HasResult ? task.Result : throw new("Value not ready!");
public Exception Error => HasError ? task.Exception : null;

[NotNull] private readonly Task<T> task;
Expand Down
26 changes: 20 additions & 6 deletions Runtime/ComponentState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,20 +104,34 @@ public static void OnDestroy([NotNull] Action onDestroy) =>

public static T UseContext<T>() => Ctx.UseContext<T>();

public static T UseMemo<T>(CompositionContext.FactoryDelegate<T> factory, params object[] vars)
public static T Cache<T>([NotNull] CompositionContext.FactoryDelegate<T> factory, params object[] vars)
{
var c = Ctx;
var oldVars = c.RememberRef(vars);
var oldResult = RememberRefF(factory);

if (oldVars.Value.Length != vars.Length || !oldVars.Value.Zip(vars, Equals).All(v => v))
{
oldResult.Value = factory();
oldVars.Value = vars;
}
if (oldVars.Value.Length == vars.Length && oldVars.Value.Zip(vars, Equals).All(v => v))
return oldResult.Value;

oldResult.Value = factory();
oldVars.Value = vars;

return oldResult.Value;
}

public static void OnChange([NotNull] Action onChanged, params object[] vars)
{
var c = Ctx;
var oldVars = c.RememberRef(vars);
// during first render, oldVars == vars is always true, so we compensate for that with OnInit
c.OnInit(onChanged);

if (oldVars.Value.Length == vars.Length && oldVars.Value.Zip(vars, Equals).All(v => v))
return;

oldVars.Value = vars;
onChanged.Invoke();
}
}

[PublicAPI]
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"name": "com.niikelion.ui.lithium",
"version": "1.2.0",
"version": "2.0.0",
"displayName": "Lithium UI",
"description": "Reactive UI library designed for editor tools creation.",
"unity": "2023.1",
"unity": "6000.0",
"keywords": [
"ui", "lithium", "reactive", "ui-toolkit"
],
Expand Down

0 comments on commit a11b51b

Please sign in to comment.