Skip to content

Commit 1f5cecc

Browse files
committed
Resolve #17. Add BindingContextProvider.
1 parent ab9d8c7 commit 1f5cecc

24 files changed

Lines changed: 433 additions & 161 deletions

src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/Common/Extensions/VisualElementExtensions.cs

Lines changed: 0 additions & 81 deletions
This file was deleted.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
using UnityMvvmToolkit.Core.Interfaces;
2+
3+
namespace UnityMvvmToolkit.Common.Interfaces
4+
{
5+
public interface IBindableCollection : IBindableElement
6+
{
7+
}
8+
}

src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/Common/Interfaces/IBindableCollection.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using UnityMvvmToolkit.Core.Interfaces;
2+
3+
namespace UnityMvvmToolkit.Common.Interfaces
4+
{
5+
public interface IBindingContextProvider
6+
{
7+
bool IsValid { get; }
8+
IBindingContext BindingContext { get;}
9+
}
10+
}

src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/Common/Interfaces/IBindingContextProvider.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/Common/MonoBehaviourView.cs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,12 @@ private void Awake()
3131
private void OnDestroy()
3232
{
3333
ResetBindingContext();
34+
OnDispose();
3435
}
3536

3637
public void SetBindingContext(IBindingContext context, IObjectProvider objectProvider)
3738
{
38-
if (_bindingContext != null)
39+
if (_bindingContext is not null)
3940
{
4041
throw new InvalidOperationException(
4142
$"{GetType().Name} - binding context was not reset. Reset the binding context first.");
@@ -53,11 +54,12 @@ public void ResetBindingContext(IObjectProvider objectProvider)
5354
}
5455

5556
protected abstract void OnInit();
56-
protected abstract IBindableElement[] GetBindableElements();
57+
protected abstract void OnDispose();
58+
protected abstract IReadOnlyList<IBindableElement> GetBindableElements();
5759

5860
protected virtual TBindingContext GetBindingContext()
5961
{
60-
if (typeof(TBindingContext).GetConstructor(Type.EmptyTypes) == null)
62+
if (typeof(TBindingContext).GetConstructor(Type.EmptyTypes) is null)
6163
{
6264
throw new InvalidOperationException(
6365
$"Cannot create an instance of the type parameter {typeof(TBindingContext)} because it does not have a parameterless constructor.");
@@ -109,13 +111,13 @@ private void ResetBindingContext()
109111
}
110112

111113
[MethodImpl(MethodImplOptions.AggressiveInlining)]
112-
private void SetBindingContext(ReadOnlySpan<IBindableElement> bindableElements, IBindingContext context,
114+
private void SetBindingContext(IReadOnlyList<IBindableElement> bindableElements, IBindingContext context,
113115
IObjectProvider objectProvider, bool initialize)
114116
{
115117
_bindingContext = (TBindingContext) context;
116118
_objectProvider = objectProvider;
117119

118-
for (var i = 0; i < bindableElements.Length; i++)
120+
for (var i = 0; i < bindableElements.Count; i++)
119121
{
120122
var bindableElement = bindableElements[i];
121123

@@ -129,10 +131,10 @@ private void SetBindingContext(ReadOnlySpan<IBindableElement> bindableElements,
129131
}
130132

131133
[MethodImpl(MethodImplOptions.AggressiveInlining)]
132-
private void ResetBindingContext(ReadOnlySpan<IBindableElement> bindableElements,
134+
private void ResetBindingContext(IReadOnlyList<IBindableElement> bindableElements,
133135
IObjectProvider objectProvider, bool dispose)
134136
{
135-
for (var i = 0; i < bindableElements.Length; i++)
137+
for (var i = 0; i < bindableElements.Count; i++)
136138
{
137139
var bindableElement = bindableElements[i];
138140

src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UGUI/CanvasView.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Linq;
1+
using System.Collections.Generic;
2+
using System.Linq;
23
using UnityEngine;
34
using UnityMvvmToolkit.Common;
45
using UnityMvvmToolkit.Core.Interfaces;
@@ -8,7 +9,7 @@ namespace UnityMvvmToolkit.UGUI
89
public abstract class CanvasView<TBindingContext> : MonoBehaviourView<TBindingContext>
910
where TBindingContext : class, IBindingContext
1011
{
11-
private IBindableElement[] _bindableElements;
12+
private List<IBindableElement> _bindableElements;
1213

1314
public GameObject RootElement { get; private set; }
1415

@@ -19,12 +20,17 @@ protected override void OnInit()
1920
_bindableElements = RootElement
2021
.GetComponentsInChildren<IBindableElement>(true)
2122
.Where(element => ((MonoBehaviour) element).gameObject != RootElement)
22-
.ToArray();
23+
.ToList();
2324
}
2425

25-
protected override IBindableElement[] GetBindableElements()
26+
protected override IReadOnlyList<IBindableElement> GetBindableElements()
2627
{
2728
return _bindableElements;
2829
}
30+
31+
protected override void OnDispose()
32+
{
33+
_bindableElements.Clear();
34+
}
2935
}
3036
}

src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableListView.cs renamed to src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableListView.T.cs

Lines changed: 50 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,42 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Collections.ObjectModel;
34
using System.Collections.Specialized;
4-
using System.Runtime.CompilerServices;
5+
using JetBrains.Annotations;
56
using UnityEngine.UIElements;
6-
using UnityMvvmToolkit.Common.Extensions;
77
using UnityMvvmToolkit.Common.Interfaces;
88
using UnityMvvmToolkit.Core;
99
using UnityMvvmToolkit.Core.Extensions;
1010
using UnityMvvmToolkit.Core.Interfaces;
11+
using UnityMvvmToolkit.UITK.Extensions;
1112

1213
namespace UnityMvvmToolkit.UITK.BindableUIElements
1314
{
14-
public abstract partial class BindableListView<TItemBindingContext> : ListView, IBindableElement
15-
where TItemBindingContext : ICollectionItem
15+
public abstract partial class BindableListView<TItemBindingContext> : ListView, IBindableCollection,
16+
IInitializable, IDisposable where TItemBindingContext : ICollectionItem
1617
{
1718
private VisualTreeAsset _itemTemplate;
1819

1920
private PropertyBindingData _itemsSourceBindingData;
2021
private IReadOnlyProperty<ObservableCollection<TItemBindingContext>> _itemsSource;
2122

2223
private IObjectProvider _objectProvider;
24+
private List<VisualElement> _itemAssets;
25+
26+
public virtual void Initialize()
27+
{
28+
_itemAssets = new List<VisualElement>();
29+
}
30+
31+
public virtual void Dispose()
32+
{
33+
for (var i = 0; i < _itemAssets.Count; i++)
34+
{
35+
_itemAssets[i].DisposeBindableElement(_objectProvider);
36+
}
37+
38+
_itemAssets.Clear();
39+
}
2340

2441
public virtual void SetBindingContext(IBindingContext context, IObjectProvider objectProvider)
2542
{
@@ -28,31 +45,29 @@ public virtual void SetBindingContext(IBindingContext context, IObjectProvider o
2845

2946
_objectProvider = objectProvider;
3047

31-
_itemsSource =
32-
objectProvider.RentReadOnlyProperty<ObservableCollection<TItemBindingContext>>(context,
33-
_itemsSourceBindingData);
48+
_itemsSource = objectProvider
49+
.RentReadOnlyProperty<ObservableCollection<TItemBindingContext>>(context, _itemsSourceBindingData);
3450
_itemsSource.Value.CollectionChanged += OnItemsCollectionChanged;
3551

3652
itemsSource = _itemsSource.Value;
37-
makeItem += MakeItem;
38-
bindItem += BindItem;
39-
unbindItem += UnbindItem;
53+
makeItem += OnMakeItem;
54+
bindItem += OnBindItem;
55+
unbindItem += OnUnbindItem;
4056
}
4157

4258
public virtual void ResetBindingContext(IObjectProvider objectProvider)
4359
{
44-
if (_itemsSource == null)
60+
if (_itemsSource is null)
4561
{
4662
return;
4763
}
4864

4965
_itemsSource.Value.CollectionChanged -= OnItemsCollectionChanged;
5066

51-
makeItem -= MakeItem;
52-
bindItem -= BindItem;
53-
unbindItem -= UnbindItem;
54-
55-
ClearItems();
67+
makeItem -= OnMakeItem;
68+
bindItem -= OnBindItem;
69+
unbindItem -= OnUnbindItem;
70+
itemsSource = Array.Empty<TItemBindingContext>();
5671

5772
objectProvider.ReturnReadOnlyProperty(_itemsSource);
5873

@@ -63,39 +78,42 @@ public virtual void ResetBindingContext(IObjectProvider objectProvider)
6378

6479
protected virtual VisualElement MakeItem(VisualTreeAsset itemTemplate)
6580
{
66-
return itemTemplate.InstantiateBindableElement(); // TODO: Pool.
81+
return itemTemplate
82+
.InstantiateBindableElement()
83+
.InitializeBindableElement();
6784
}
6885

6986
protected virtual void BindItem(VisualElement item, int index, TItemBindingContext bindingContext,
7087
IObjectProvider objectProvider)
7188
{
72-
item.SetBindingContext(bindingContext, objectProvider, true);
89+
item.SetChildsBindingContext(bindingContext, objectProvider);
7390
}
7491

75-
protected virtual void UnbindItem(VisualElement item, int index, TItemBindingContext bindingContext,
92+
protected virtual void UnbindItem(VisualElement item, int index, [CanBeNull] TItemBindingContext bindingContext,
7693
IObjectProvider objectProvider)
7794
{
78-
item.ResetBindingContext(objectProvider, true);
95+
item.ResetChildsBindingContext(objectProvider);
7996
}
8097

81-
private VisualElement MakeItem()
98+
private void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
8299
{
83-
return MakeItem(_itemTemplate);
100+
RefreshItems(); // TODO: Do not refresh all items.
84101
}
85102

86-
private void BindItem(VisualElement item, int index)
103+
private VisualElement OnMakeItem()
87104
{
88-
if (index >= 0 && index < itemsSource.Count)
89-
{
90-
BindItem(item, index, _itemsSource.Value[index], _objectProvider);
91-
}
92-
else
93-
{
94-
BindItem(item, index, default, _objectProvider);
95-
}
105+
var item = MakeItem(_itemTemplate);
106+
_itemAssets.Add(item);
107+
108+
return item;
96109
}
97110

98-
private void UnbindItem(VisualElement item, int index)
111+
private void OnBindItem(VisualElement item, int index)
112+
{
113+
BindItem(item, index, _itemsSource.Value[index], _objectProvider);
114+
}
115+
116+
private void OnUnbindItem(VisualElement item, int index)
99117
{
100118
if (index >= 0 && index < itemsSource.Count)
101119
{
@@ -106,16 +124,5 @@ private void UnbindItem(VisualElement item, int index)
106124
UnbindItem(item, index, default, _objectProvider);
107125
}
108126
}
109-
110-
private void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
111-
{
112-
RefreshItems(); // TODO: Do not refresh all items.
113-
}
114-
115-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
116-
private void ClearItems()
117-
{
118-
itemsSource = Array.Empty<TItemBindingContext>();
119-
}
120127
}
121128
}

src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableListView.cs.meta renamed to src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit/Runtime/UITK/BindableUIElements/BindableListView.T.cs.meta

File renamed without changes.

0 commit comments

Comments
 (0)