Skip to content

Commit 0c9492b

Browse files
authored
Merge pull request #2 from coryleach/dev
Merge 1.0.3
2 parents 78a17d3 + 9a9dbda commit 0c9492b

16 files changed

+119
-95
lines changed

.codacy.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
exclude_paths:
2+
- '*.md'
3+
- 'Tests/Editor/*.cs'
4+
- 'Tests/Runtime/*.cs'

CHANGELOG.md

Lines changed: 0 additions & 1 deletion
This file was deleted.

Documentation~/com.gameframe.bindings.md

Lines changed: 0 additions & 1 deletion
This file was deleted.

Editor/BindingDataContextInfoDrawer.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using System;
2-
using System.Collections.Generic;
1+
using System.Collections.Generic;
32
using System.Linq;
43
using System.Reflection;
54
using UnityEngine;
@@ -13,7 +12,6 @@ namespace Gameframe.Bindings.Editor
1312
[CustomPropertyDrawer(typeof(BindingDataContextInfo))]
1413
public class BindingDataContextInfoDrawer : PropertyDrawer
1514
{
16-
private ObjectField dataContextField;
1715
private VisualElement rootContainer;
1816
private PopupField<Object> componentPopup;
1917
private PopupField<string> propertyPopup;
@@ -25,7 +23,7 @@ public class BindingDataContextInfoDrawer : PropertyDrawer
2523
public override VisualElement CreatePropertyGUI(SerializedProperty property)
2624
{
2725
// Create property container element.
28-
rootContainer = new VisualElement()
26+
rootContainer = new VisualElement
2927
{
3028
style =
3129
{
@@ -39,7 +37,10 @@ public override VisualElement CreatePropertyGUI(SerializedProperty property)
3937
borderLeftWidth = 1,
4038
borderRightWidth = 1,
4139
borderTopWidth = 1,
42-
borderColor = Color.black,
40+
borderBottomColor = Color.black,
41+
borderLeftColor = Color.black,
42+
borderRightColor = Color.black,
43+
borderTopColor = Color.black,
4344
backgroundColor = new Color(0,0,0,0.1f)
4445
}
4546
};
@@ -54,7 +55,7 @@ public override VisualElement CreatePropertyGUI(SerializedProperty property)
5455
rootContainer.Add(new Label(property.displayName));
5556

5657
//Data Context Field is always available
57-
dataContextField = new ObjectField("Object")
58+
var dataContextField = new ObjectField("Object")
5859
{
5960
objectType = typeof(Object),
6061
bindingPath = pDataContext.propertyPath

Editor/BindingEditor.cs

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@
66
using UnityEditor;
77
using UnityEditor.UIElements;
88
using UnityEngine.UIElements;
9+
using Object = UnityEngine.Object;
910

1011
namespace Gameframe.Bindings.Editor
1112
{
1213
[CustomEditor(typeof(BindingBehaviour), editorForChildClasses: true)]
1314
public class BindingEditor : UnityEditor.Editor
1415
{
1516
private SerializedProperty pDataContext;
16-
private List<BindingDataContextInfoDrawer> _drawerList = null;
17+
private List<BindingDataContextInfoDrawer> _drawerList;
1718

1819
private void OnEnable()
1920
{
@@ -38,7 +39,7 @@ public override VisualElement CreateInspectorGUI()
3839
return container;
3940
}
4041

41-
var fieldContainer = new VisualElement()
42+
var fieldContainer = new VisualElement
4243
{
4344
style =
4445
{
@@ -52,7 +53,10 @@ public override VisualElement CreateInspectorGUI()
5253
borderLeftWidth = 1,
5354
borderRightWidth = 1,
5455
borderTopWidth = 1,
55-
borderColor = Color.black,
56+
borderBottomColor = Color.black,
57+
borderLeftColor = Color.black,
58+
borderRightColor = Color.black,
59+
borderTopColor = Color.black,
5660
backgroundColor = new Color(0, 0, 0, 0.1f)
5761
}
5862
};
@@ -81,13 +85,10 @@ public override VisualElement CreateInspectorGUI()
8185
}
8286

8387

84-
private VisualElement CreateFieldFromProperty(SerializedProperty property)
88+
private static VisualElement CreateFieldFromProperty(SerializedProperty property)
8589
{
8690
SerializedPropertyType propertyType = property.propertyType;
8791

88-
/*if (EditorGUI.HasVisibleChildFields(property))
89-
return this.CreateFoldout(property);*/
90-
9192
//Ripped this from some decompiled internal unity code so it's wonky. Could fix it if there is every an actual need
9293
switch (propertyType + 1)
9394
{
@@ -111,7 +112,7 @@ private VisualElement CreateFieldFromProperty(SerializedProperty property)
111112
type = typeof(UnityEngine.Object);
112113
}
113114
field1.objectType = type;
114-
return ConfigureField<ObjectField, UnityEngine.Object>(field1, property);
115+
return ConfigureField<ObjectField, Object>(field1, property);
115116

116117
case SerializedPropertyType.Enum:
117118
return ConfigureField<LayerMaskField, int>(new LayerMaskField(), property);
@@ -136,7 +137,6 @@ private VisualElement CreateFieldFromProperty(SerializedProperty property)
136137
IntegerField integerField = new IntegerField();
137138
integerField.SetValueWithoutNotify(property.intValue);
138139
integerField.isDelayed = true;
139-
//integerField.RegisterValueChangedCallback<int>((EventCallback<ChangeEvent<int>>) (e => this.UpdateArrayFoldout(e, this, this.m_ParentPropertyField)));
140140
return ConfigureField<IntegerField, int>(integerField, property);
141141

142142
case SerializedPropertyType.AnimationCurve:
@@ -168,7 +168,7 @@ private VisualElement CreateFieldFromProperty(SerializedProperty property)
168168
}
169169
}
170170

171-
private VisualElement ConfigureField<TField, TValue>(
171+
private static VisualElement ConfigureField<TField, TValue>(
172172
TField field,
173173
SerializedProperty property)
174174
where TField : BaseField<TValue>
@@ -181,23 +181,21 @@ private VisualElement ConfigureField<TField, TValue>(
181181
if (label != null)
182182
{
183183
label.userData = property.Copy();
184-
//label.RegisterCallback<MouseUpEvent>(new EventCallback<MouseUpEvent>(this.RightClickMenuEvent), TrickleDown.NoTrickleDown);
185184
}
186185

187186
field.labelElement.AddToClassList(PropertyField.labelUssClassName);
188-
//field.visualInput.AddToClassList(PropertyField.inputUssClassName);
189187
return field;
190188
}
191189

192-
private static FieldInfo GetFieldInfoFromProperty(SerializedProperty property, out Type type)
190+
private static void GetFieldInfoFromProperty(SerializedProperty property, out Type type)
193191
{
194-
Type typeFromProperty = GetScriptTypeFromProperty(property);
192+
var typeFromProperty = GetScriptTypeFromProperty(property);
195193
if ((object) typeFromProperty != null)
196194
{
197-
return GetFieldInfoFromPropertyPath(typeFromProperty, property.propertyPath, out type);
195+
GetFieldInfoFromPropertyPath(typeFromProperty, property.propertyPath, out type);
196+
return;
198197
}
199198
type = null;
200-
return null;
201199
}
202200

203201
private static Type GetScriptTypeFromProperty(SerializedProperty property)
@@ -219,22 +217,23 @@ private static FieldInfo GetFieldInfoFromPropertyPath(Type host, string path, ou
219217
{
220218
FieldInfo fieldInfo1 = null;
221219
type = host;
222-
string[] strArray = path.Split('.');
223-
for (int index = 0; index < strArray.Length; ++index)
220+
var strArray = path.Split('.');
221+
var index = 0;
222+
while ( index < strArray.Length )
224223
{
225-
string name = strArray[index];
224+
var name = strArray[index];
226225
if (index < strArray.Length - 1 && name == "Array" && strArray[index + 1].StartsWith("data["))
227226
{
228227
if (type.IsArrayOrList())
229228
{
230229
type = type.GetArrayOrListElementType();
231230
}
232-
++index;
231+
index++;
233232
}
234233
else
235234
{
236235
FieldInfo fieldInfo2 = null;
237-
for (Type type1 = type; (object) fieldInfo2 == null && (object) type1 != null; type1 = type1.BaseType)
236+
for (var type1 = type; (object) fieldInfo2 == null && (object) type1 != null; type1 = type1.BaseType)
238237
{
239238
fieldInfo2 = type1.GetField(name,BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
240239
}
@@ -246,6 +245,7 @@ private static FieldInfo GetFieldInfoFromPropertyPath(Type host, string path, ou
246245
fieldInfo1 = fieldInfo2;
247246
type = fieldInfo1.FieldType;
248247
}
248+
index++;
249249
}
250250
return fieldInfo1;
251251
}
@@ -262,9 +262,15 @@ internal static bool IsArrayOrList(this System.Type listType)
262262
internal static Type GetArrayOrListElementType(this System.Type listType)
263263
{
264264
if (listType.IsArray)
265+
{
265266
return listType.GetElementType();
266-
if (listType.IsGenericType && (object) listType.GetGenericTypeDefinition() == (object) typeof(List<>))
267+
}
268+
269+
if (listType.IsGenericType && listType.GetGenericTypeDefinition() == typeof(List<>))
270+
{
267271
return listType.GetGenericArguments()[0];
272+
}
273+
268274
return null;
269275
}
270276
}

LICENSE renamed to LICENSE.md

File renamed without changes.
File renamed without changes.

README.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
<h1 align="center">Gameframe.Bindings 👋</h1>
2-
<p>
3-
<img alt="Version" src="https://img.shields.io/badge/version-1.0.3-blue.svg?cacheSeconds=2592000" />
4-
<a href="https://twitter.com/Cory Leach">
5-
<img alt="Twitter: coryleach" src="https://img.shields.io/twitter/follow/coryleach.svg?style=social" target="_blank" />
6-
</a>
7-
</p>
2+
3+
<!-- BADGE-START -->
4+
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/0bb60e11b3c9422d94c523c43bce4713)](https://www.codacy.com/manual/coryleach/UnityBindings?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=coryleach/UnityBindings&amp;utm_campaign=Badge_Grade)
5+
![GitHub release (latest by date including pre-releases)](https://img.shields.io/github/v/release/coryleach/UnityBindings?include_prereleases)
6+
[![openupm](https://img.shields.io/npm/v/com.gameframe.bindings?label=openupm&registry_uri=https://package.openupm.com)](https://openupm.com/packages/com.gameframe.bindings/)
7+
[![license](https://img.shields.io/github/license/coryleach/UnityBindings)](https://github.com/coryleach/UnityBindings/blob/master/LICENSE)
8+
9+
[![twitter](https://img.shields.io/twitter/follow/coryleach.svg?style=social)](https://twitter.com/coryleach)
10+
<!-- BADGE-END -->
811

912
This is a library of binding components that allow you to quickly wire data sources to target properties via the inspector.
1013

Runtime/BindableScriptableObject.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using System;
2-
using System.Collections.Generic;
1+
using System.Collections.Generic;
32
using System.ComponentModel;
43
using System.Runtime.CompilerServices;
54
using UnityEngine;
@@ -19,6 +18,11 @@ protected virtual void OnEnable()
1918
PropertyChanged = null;
2019
}
2120

21+
protected virtual void OnDisable()
22+
{
23+
PropertyChanged = null;
24+
}
25+
2226
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
2327
{
2428
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

Runtime/Binding.cs

Lines changed: 53 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,33 +11,49 @@ namespace Gameframe.Bindings
1111
/// </summary>
1212
public class Binding : IDisposable
1313
{
14-
private object _source = null;
15-
private object _target = null;
14+
private object _source;
15+
private object _target;
1616

17-
private string _sourcePath = null;
18-
private string _targetPath = null;
17+
private string _sourcePath;
1918

20-
private PropertyInfo _sourceProperty = null;
21-
private PropertyInfo _targetProperty = null;
19+
private PropertyInfo _sourceProperty;
20+
private PropertyInfo _targetProperty;
2221

2322
private INotifyPropertyChanged _propertyChangedNotifier;
2423

24+
private bool disposed;
25+
2526
/// <summary>
2627
/// Error context is passed to any error logs so that errors selected in the console
2728
/// Will direct the user to the associated context object
2829
/// </summary>
29-
public UnityEngine.Object ErrorContext = null;
30-
30+
private UnityEngine.Object errorContext;
31+
public UnityEngine.Object ErrorContext
32+
{
33+
get => errorContext;
34+
set => errorContext = value;
35+
}
36+
3137
/// <summary>
3238
/// Changes will only propagate while enabled is true
3339
/// </summary>
34-
public bool Enabled = true;
40+
private bool enabled = true;
41+
public bool Enabled
42+
{
43+
get => enabled;
44+
set => enabled = value;
45+
}
3546

3647
/// <summary>
3748
/// Converter function will transform values before assigning the target property
3849
/// </summary>
39-
public Func<object, object> Converter = null;
40-
50+
private Func<object, object> converter;
51+
public Func<object, object> Converter
52+
{
53+
get => converter;
54+
set => converter = value;
55+
}
56+
4157
/// <summary>
4258
/// Set the binding source. This hooks up where your data comes from.
4359
/// If the dataContext implements INotifyPropertyChanged it will also set up to listen for change events
@@ -67,7 +83,6 @@ public void SetSource(object dataContext, string path, bool refresh = true)
6783
public void SetTarget(object dataContext, string path, bool refresh = true)
6884
{
6985
_target = dataContext;
70-
_targetPath = path;
7186
_targetProperty = GetPropertyInfo(dataContext, path);
7287
if (refresh)
7388
{
@@ -80,36 +95,33 @@ public void SetTarget(object dataContext, string path, bool refresh = true)
8095
/// </summary>
8196
public void Refresh()
8297
{
83-
if (_target == null || _source == null || _targetProperty == null || _sourceProperty == null)
98+
if (_target == null || _source == null || _targetProperty == null || _sourceProperty == null || disposed)
8499
{
85100
return;
86101
}
87-
102+
88103
try
89104
{
90105
var sourceValue = _sourceProperty.GetValue(_source, null);
91106
if (Converter != null)
92107
{
93108
sourceValue = Converter(sourceValue);
94109
}
95-
_targetProperty.SetValue(_target, sourceValue);
110+
_targetProperty.SetValue(_target, sourceValue);
96111
}
97112
catch (Exception e)
98113
{
99114
Debug.LogException(e, ErrorContext);
100115
}
101116
}
102-
103-
/// <summary>
104-
/// Destroys the binding so changes will no longer propagate
105-
/// </summary>
106-
public void Dispose()
107-
{
108-
SetPropertyChangedNotifier(null);
109-
}
110-
117+
111118
private void PropertyChanged(object sender, PropertyChangedEventArgs args)
112119
{
120+
if (disposed)
121+
{
122+
throw new ObjectDisposedException("Binding was disposed but still getting property changed events.");
123+
}
124+
113125
if ( _targetProperty == null || !Enabled )
114126
{
115127
return;
@@ -144,5 +156,22 @@ private void SetPropertyChangedNotifier(INotifyPropertyChanged value)
144156
}
145157
}
146158

159+
/// <summary>
160+
/// Destroys the binding so changes will no longer propagate
161+
/// </summary>
162+
public void Dispose()
163+
{
164+
disposed = true;
165+
SetPropertyChangedNotifier(null);
166+
}
167+
168+
~Binding()
169+
{
170+
if (!disposed)
171+
{
172+
Dispose();
173+
}
174+
}
175+
147176
}
148177
}

0 commit comments

Comments
 (0)