Skip to content

Commit 166062a

Browse files
authored
Update readme file.
1 parent 2d33260 commit 166062a

File tree

1 file changed

+179
-5
lines changed

1 file changed

+179
-5
lines changed

README.md

Lines changed: 179 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ A package that brings data-binding to your Unity project.
2424
- [How To Use](#joystick-how-to-use)
2525
- [Data-binding](#data-binding)
2626
- [Create custom control](#create-custom-control)
27+
- [Source code generator](#source-code-generator)
2728
- [External Assets](#link-external-assets)
2829
- [UniTask](#unitask)
2930
- [Performance](#rocket-performance)
@@ -879,8 +880,6 @@ public class Image : VisualElement
879880
}
880881

881882
public new class UxmlFactory : UxmlFactory<Image, UxmlTraits> {}
882-
883-
public new class UxmlTraits : VisualElement.UxmlTraits {}
884883
}
885884
```
886885

@@ -899,7 +898,7 @@ public class BindableImage : Image, IBindableElement
899898
_imagePathBindingData ??= BindingImagePath.ToPropertyBindingData();
900899

901900
_imageProperty = objectProvider.RentReadOnlyProperty<Texture2D>(context, _imagePathBindingData);
902-
_imageProperty.ValueChanged += OnImageValueChanged;
901+
_imageProperty.ValueChanged += OnImagePropertyValueChanged;
903902

904903
SetImage(_imageProperty.Value);
905904
}
@@ -911,7 +910,7 @@ public class BindableImage : Image, IBindableElement
911910
return;
912911
}
913912

914-
_imageProperty.ValueChanged -= OnImageValueChanged;
913+
_imageProperty.ValueChanged -= OnImagePropertyValueChanged;
915914

916915
objectProvider.ReturnReadOnlyProperty(_imageProperty);
917916

@@ -920,7 +919,7 @@ public class BindableImage : Image, IBindableElement
920919
SetImage(null);
921920
}
922921

923-
private void OnImageValueChanged(object sender, Texture2D newImage)
922+
private void OnImagePropertyValueChanged(object sender, Texture2D newImage)
924923
{
925924
SetImage(newImage);
926925
}
@@ -961,6 +960,181 @@ public class ImageViewerViewModel : IBindingContext
961960
</UXML>
962961
```
963962

963+
### Source code generator
964+
965+
The best way to speed up the creation of custom `VisualElement` is to use source code generators. With this powerful tool, you can achieve the same great results with minimal boilerplate code and focus on what really matters: programming!
966+
967+
Let's create the `BindableImage` control, but this time using source code generators.
968+
969+
For a visual element without bindings, we will use a [UnityUxmlGenerator](https://github.com/LibraStack/UnityUxmlGenerator).
970+
971+
```csharp
972+
[UxmlElement]
973+
public partial class Image : VisualElement
974+
{
975+
public void SetImage(Texture2D image)
976+
{
977+
style.backgroundImage = new StyleBackground(image);
978+
}
979+
}
980+
```
981+
982+
<details><summary><b>Generated code</b></summary>
983+
<br />
984+
985+
`Image.UxmlFactory.g.cs`
986+
987+
```csharp
988+
partial class Image
989+
{
990+
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("UnityUxmlGenerator", "1.0.0.0")]
991+
public new class UxmlFactory : global::UnityEngine.UIElements.UxmlFactory<Image, UxmlTraits>
992+
{
993+
}
994+
}
995+
```
996+
997+
</details>
998+
999+
For a bindable visual element, we will use a [UnityMvvmToolkit.Generator](https://github.com/LibraStack/UnityMvvmToolkit.Generator).
1000+
1001+
```csharp
1002+
[BindableElement]
1003+
public partial class BindableImage : Image
1004+
{
1005+
[BindableProperty]
1006+
private IReadOnlyProperty<Texture2D> _imageProperty;
1007+
1008+
partial void AfterSetBindingContext(IBindingContext context, IObjectProvider objectProvider)
1009+
{
1010+
SetImage(_imageProperty?.Value);
1011+
}
1012+
1013+
partial void AfterResetBindingContext(IObjectProvider objectProvider)
1014+
{
1015+
SetImage(null);
1016+
}
1017+
1018+
partial void OnImagePropertyValueChanged([CanBeNull] Texture2D value)
1019+
{
1020+
SetImage(value);
1021+
}
1022+
}
1023+
```
1024+
1025+
<details><summary><b>Generated code</b></summary>
1026+
<br />
1027+
1028+
`BindableImage.Bindings.g.cs`
1029+
1030+
```csharp
1031+
partial class BindableImage : global::UnityMvvmToolkit.Core.Interfaces.IBindableElement
1032+
{
1033+
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("UnityMvvmToolkit.Generator", "1.0.0.0")]
1034+
private global::UnityMvvmToolkit.Core.PropertyBindingData? _imageBindingData;
1035+
1036+
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("UnityMvvmToolkit.Generator", "1.0.0.0")]
1037+
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
1038+
public void SetBindingContext(global::UnityMvvmToolkit.Core.Interfaces.IBindingContext context,
1039+
global::UnityMvvmToolkit.Core.Interfaces.IObjectProvider objectProvider)
1040+
{
1041+
BeforeSetBindingContext(context, objectProvider);
1042+
1043+
if (string.IsNullOrWhiteSpace(BindingImagePath) == false)
1044+
{
1045+
_imageBindingData ??=
1046+
global::UnityMvvmToolkit.Core.Extensions.StringExtensions.ToPropertyBindingData(BindingImagePath!);
1047+
_imageProperty = objectProvider.RentReadOnlyProperty<global::UnityEngine.Texture2D>(context, _imageBindingData!);
1048+
_imageProperty!.ValueChanged += OnImagePropertyValueChanged;
1049+
}
1050+
1051+
AfterSetBindingContext(context, objectProvider);
1052+
}
1053+
1054+
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("UnityMvvmToolkit.Generator", "1.0.0.0")]
1055+
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
1056+
public void ResetBindingContext(global::UnityMvvmToolkit.Core.Interfaces.IObjectProvider objectProvider)
1057+
{
1058+
BeforeResetBindingContext(objectProvider);
1059+
1060+
if (_imageProperty != null)
1061+
{
1062+
_imageProperty!.ValueChanged -= OnImagePropertyValueChanged;
1063+
objectProvider.ReturnReadOnlyProperty(_imageProperty);
1064+
_imageProperty = null;
1065+
}
1066+
1067+
AfterResetBindingContext(objectProvider);
1068+
}
1069+
1070+
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("UnityMvvmToolkit.Generator", "1.0.0.0")]
1071+
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
1072+
private void OnImagePropertyValueChanged(object sender, global::UnityEngine.Texture2D value)
1073+
{
1074+
OnImagePropertyValueChanged(value);
1075+
}
1076+
1077+
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("UnityMvvmToolkit.Generator", "1.0.0.0")]
1078+
partial void BeforeSetBindingContext(global::UnityMvvmToolkit.Core.Interfaces.IBindingContext context,
1079+
global::UnityMvvmToolkit.Core.Interfaces.IObjectProvider objectProvider);
1080+
1081+
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("UnityMvvmToolkit.Generator", "1.0.0.0")]
1082+
partial void AfterSetBindingContext(global::UnityMvvmToolkit.Core.Interfaces.IBindingContext context,
1083+
global::UnityMvvmToolkit.Core.Interfaces.IObjectProvider objectProvider);
1084+
1085+
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("UnityMvvmToolkit.Generator", "1.0.0.0")]
1086+
partial void BeforeResetBindingContext(global::UnityMvvmToolkit.Core.Interfaces.IObjectProvider objectProvider);
1087+
1088+
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("UnityMvvmToolkit.Generator", "1.0.0.0")]
1089+
partial void AfterResetBindingContext(global::UnityMvvmToolkit.Core.Interfaces.IObjectProvider objectProvider);
1090+
1091+
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("UnityMvvmToolkit.Generator", "1.0.0.0")]
1092+
partial void OnImagePropertyValueChanged(global::UnityEngine.Texture2D value);
1093+
}
1094+
```
1095+
1096+
`BindableImage.Uxml.g.cs`
1097+
1098+
```csharp
1099+
partial class BindableImage
1100+
{
1101+
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("UnityMvvmToolkit.Generator", "1.0.0.0")]
1102+
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
1103+
private string BindingImagePath { get; set; }
1104+
1105+
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("UnityMvvmToolkit.Generator", "1.0.0.0")]
1106+
public new class UxmlFactory : global::UnityEngine.UIElements.UxmlFactory<BindableImage, UxmlTraits>
1107+
{
1108+
}
1109+
1110+
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("UnityMvvmToolkit.Generator", "1.0.0.0")]
1111+
public new class UxmlTraits : global::BindableUIElements.Image.UxmlTraits
1112+
{
1113+
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("UnityMvvmToolkit.Generator", "1.0.0.0")]
1114+
private readonly global::UnityEngine.UIElements.UxmlStringAttributeDescription _bindingImagePath = new()
1115+
{ name = "binding-image-path", defaultValue = "" };
1116+
1117+
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("UnityMvvmToolkit.Generator", "1.0.0.0")]
1118+
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
1119+
public override void Init(global::UnityEngine.UIElements.VisualElement visualElement,
1120+
global::UnityEngine.UIElements.IUxmlAttributes bag,
1121+
global::UnityEngine.UIElements.CreationContext context)
1122+
{
1123+
base.Init(visualElement, bag, context);
1124+
1125+
var control = (BindableImage) visualElement;
1126+
control.BindingImagePath = _bindingImagePath.GetValueFromBag(bag, context);
1127+
}
1128+
}
1129+
}
1130+
```
1131+
1132+
</details>
1133+
1134+
As you can see, using [UnityUxmlGenerator](https://github.com/LibraStack/UnityUxmlGenerator) and [UnityMvvmToolkit.Generator](https://github.com/LibraStack/UnityMvvmToolkit.Generator) we can achieve the same results but with just a few lines of code.
1135+
1136+
> **Note:** The [UnityMvvmToolkit.Generator](https://github.com/LibraStack/UnityMvvmToolkit.Generator) is available exclusively for my [patrons](https://patreon.com/DimaChebanov).
1137+
9641138
## :link: External Assets
9651139

9661140
### UniTask

0 commit comments

Comments
 (0)