Skip to content

Bug fixes. #29

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jun 6, 2023
4 changes: 2 additions & 2 deletions samples/Unity.Mvvm.Calc/Packages/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
"com.chebanovdd.unitymvvmtoolkit": "file:../../../src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit",
"com.unity.collab-proxy": "2.0.4",
"com.unity.feature.2d": "1.0.0",
"com.unity.ide.rider": "3.0.21",
"com.unity.ide.rider": "3.0.22",
"com.unity.ide.visualstudio": "2.0.18",
"com.unity.ide.vscode": "1.2.5",
"com.unity.test-framework": "1.1.33",
"com.unity.textmeshpro": "3.0.6",
"com.unity.timeline": "1.6.4",
"com.unity.timeline": "1.6.5",
"com.unity.ugui": "1.0.0",
"com.unity.visualscripting": "1.8.0",
"com.unity.modules.ai": "1.0.0",
Expand Down
4 changes: 2 additions & 2 deletions samples/Unity.Mvvm.Calc/Packages/packages-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@
}
},
"com.unity.ide.rider": {
"version": "3.0.21",
"version": "3.0.22",
"depth": 0,
"source": "registry",
"dependencies": {
Expand Down Expand Up @@ -181,7 +181,7 @@
"url": "https://packages.unity.com"
},
"com.unity.timeline": {
"version": "1.6.4",
"version": "1.6.5",
"depth": 0,
"source": "registry",
"dependencies": {
Expand Down
4 changes: 2 additions & 2 deletions samples/Unity.Mvvm.Counter/Packages/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
"com.cysharp.unitask": "2.3.3",
"com.unity.collab-proxy": "2.0.4",
"com.unity.feature.2d": "1.0.0",
"com.unity.ide.rider": "3.0.21",
"com.unity.ide.rider": "3.0.22",
"com.unity.ide.visualstudio": "2.0.18",
"com.unity.ide.vscode": "1.2.5",
"com.unity.test-framework": "1.1.33",
"com.unity.textmeshpro": "3.0.6",
"com.unity.timeline": "1.6.4",
"com.unity.timeline": "1.6.5",
"com.unity.ugui": "1.0.0",
"com.unity.visualscripting": "1.8.0",
"com.unity.modules.ai": "1.0.0",
Expand Down
4 changes: 2 additions & 2 deletions samples/Unity.Mvvm.Counter/Packages/packages-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@
}
},
"com.unity.ide.rider": {
"version": "3.0.21",
"version": "3.0.22",
"depth": 0,
"source": "registry",
"dependencies": {
Expand Down Expand Up @@ -188,7 +188,7 @@
"url": "https://packages.unity.com"
},
"com.unity.timeline": {
"version": "1.6.4",
"version": "1.6.5",
"depth": 0,
"source": "registry",
"dependencies": {
Expand Down
4 changes: 2 additions & 2 deletions samples/Unity.Mvvm.CounterLegacy/Packages/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
"com.chebanovdd.unitymvvmtoolkit": "file:../../../src/UnityMvvmToolkit.UnityPackage/Assets/Plugins/UnityMvvmToolkit",
"com.unity.collab-proxy": "2.0.4",
"com.unity.feature.2d": "1.0.0",
"com.unity.ide.rider": "3.0.21",
"com.unity.ide.rider": "3.0.22",
"com.unity.ide.visualstudio": "2.0.18",
"com.unity.ide.vscode": "1.2.5",
"com.unity.test-framework": "1.1.33",
"com.unity.textmeshpro": "3.0.6",
"com.unity.timeline": "1.6.4",
"com.unity.timeline": "1.6.5",
"com.unity.ugui": "1.0.0",
"com.unity.visualscripting": "1.8.0",
"com.unity.modules.ai": "1.0.0",
Expand Down
4 changes: 2 additions & 2 deletions samples/Unity.Mvvm.CounterLegacy/Packages/packages-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@
}
},
"com.unity.ide.rider": {
"version": "3.0.21",
"version": "3.0.22",
"depth": 0,
"source": "registry",
"dependencies": {
Expand Down Expand Up @@ -181,7 +181,7 @@
"url": "https://packages.unity.com"
},
"com.unity.timeline": {
"version": "1.6.4",
"version": "1.6.5",
"depth": 0,
"source": "registry",
"dependencies": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@
}

.add-task-button--animation {
transition-property: rotate background-color;
transition-duration: 150ms 150ms;
transition-property: rotate, background-color;
transition-duration: 150ms, 150ms;
}

.add-task-button__icon {
Expand Down
4 changes: 2 additions & 2 deletions samples/Unity.Mvvm.ToDoList/Packages/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
"com.cysharp.unitask": "2.3.3",
"com.unity.collab-proxy": "2.0.4",
"com.unity.feature.2d": "1.0.0",
"com.unity.ide.rider": "3.0.21",
"com.unity.ide.rider": "3.0.22",
"com.unity.ide.visualstudio": "2.0.18",
"com.unity.ide.vscode": "1.2.5",
"com.unity.nuget.newtonsoft-json": "3.1.0",
"com.unity.test-framework": "1.1.33",
"com.unity.textmeshpro": "3.0.6",
"com.unity.timeline": "1.6.4",
"com.unity.timeline": "1.6.5",
"com.unity.ugui": "1.0.0",
"com.unity.visualscripting": "1.8.0",
"com.unity.modules.ai": "1.0.0",
Expand Down
4 changes: 2 additions & 2 deletions samples/Unity.Mvvm.ToDoList/Packages/packages-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@
}
},
"com.unity.ide.rider": {
"version": "3.0.21",
"version": "3.0.22",
"depth": 0,
"source": "registry",
"dependencies": {
Expand Down Expand Up @@ -195,7 +195,7 @@
"url": "https://packages.unity.com"
},
"com.unity.timeline": {
"version": "1.6.4",
"version": "1.6.5",
"depth": 0,
"source": "registry",
"dependencies": {
Expand Down
10 changes: 1 addition & 9 deletions src/UnityMvvmToolkit.Core/BindingContextObjectProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,15 +114,7 @@ public TCommand GetCommand<TCommand>(IBindingContext context, string propertyNam
throw new InvalidOperationException($"Command '{propertyName}' not found.");
}

var propertyInfo = (PropertyInfo) memberInfo;

if (typeof(TCommand).IsAssignableFrom(propertyInfo.PropertyType))
{
return (TCommand) propertyInfo.GetValue(context);
}

throw new InvalidCastException(
$"Can not cast the {propertyInfo.PropertyType} command to the {typeof(TCommand)} command.");
return _objectWrapperHandler.GetCommand<TCommand>(context, memberInfo);
}

public IBaseCommand RentCommandWrapper(IBindingContext context, CommandBindingData bindingData)
Expand Down
2 changes: 1 addition & 1 deletion src/UnityMvvmToolkit.Core/Interfaces/IProperty.T.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace UnityMvvmToolkit.Core.Interfaces
{
public interface IProperty<T> : IReadOnlyProperty<T>
public interface IProperty<T> : IReadOnlyProperty<T>, IProperty
{
new T Value { get; set; }

Expand Down
6 changes: 6 additions & 0 deletions src/UnityMvvmToolkit.Core/Interfaces/IProperty.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace UnityMvvmToolkit.Core.Interfaces
{
public interface IProperty
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,14 @@ public void CreateValueConverterInstances<T>(int capacity, WarmupType warmupType
public TProperty GetProperty<TProperty, TValueType>(IBindingContext context, BindingData bindingData,
MemberInfo memberInfo)
{
var property = GetMemberValue(context, memberInfo, out var propertyType);

var targetType = typeof(TValueType);
var contextProperty = GetMemberValue(context, memberInfo, out var sourceType);
var sourceType = propertyType.GenericTypeArguments[0];

if (targetType == sourceType)
if (targetType == sourceType && string.IsNullOrWhiteSpace(bindingData.ConverterName))
{
return (TProperty) contextProperty;
return (TProperty) property;
}

var converterId =
Expand All @@ -71,7 +73,7 @@ public TProperty GetProperty<TProperty, TValueType>(IBindingContext context, Bin
return (TProperty) propertyWrappers
.Dequeue()
.AsPropertyWrapper()
.SetProperty(contextProperty);
.SetProperty(property);
}
}
else
Expand All @@ -86,26 +88,40 @@ public TProperty GetProperty<TProperty, TValueType>(IBindingContext context, Bin
}

var args = new object[] { valueConverter };
var wrapperType = typeof(PropertyWrapper<,>).MakeGenericType(sourceType, targetType);

return (TProperty) ObjectWrapperHelper.CreatePropertyWrapper(wrapperType, args, converterId,
contextProperty);
var wrapperType = property is IProperty
? typeof(PropertyWrapper<,>).MakeGenericType(sourceType, targetType)
: typeof(ReadOnlyPropertyWrapper<,>).MakeGenericType(sourceType, targetType);

return (TProperty) ObjectWrapperHelper.CreatePropertyWrapper(wrapperType, args, converterId, property);
}

public TCommand GetCommand<TCommand>(IBindingContext context, MemberInfo memberInfo)
{
var command = GetMemberValue(context, memberInfo, out var commandType);

if (typeof(TCommand).IsAssignableFrom(commandType))
{
return (TCommand) command;
}

throw new InvalidCastException(
$"Can not cast the '{commandType}' command to the '{typeof(TCommand)}' command.");
}

public ICommandWrapper GetCommandWrapper(IBindingContext context, CommandBindingData bindingData,
MemberInfo memberInfo)
{
var propertyInfo = (PropertyInfo) memberInfo;
var propertyType = propertyInfo.PropertyType;
var command = GetMemberValue(context, memberInfo, out var commandType);

if (propertyType.IsGenericType == false ||
propertyType.GetInterface(nameof(IBaseCommand)) == null)
if (commandType.IsGenericType == false ||
commandType.GetInterface(nameof(IBaseCommand)) == null)
{
throw new InvalidCastException(
$"Can not cast the {propertyType} command to the {typeof(ICommand<>)} command.");
$"Can not cast the '{commandType}' command to the '{typeof(ICommand<>)}' command.");
}

var commandValueType = propertyType.GenericTypeArguments[0];
var commandValueType = commandType.GenericTypeArguments[0];

var commandId =
HashCodeHelper.GetCommandWrapperId(context.GetType(), commandValueType, bindingData.PropertyName);
Expand All @@ -126,7 +142,7 @@ public ICommandWrapper GetCommandWrapper(IBindingContext context, CommandBinding
return commandWrappers
.Dequeue()
.AsCommandWrapper()
.SetCommand(commandId, propertyInfo.GetValue(context))
.SetCommand(commandId, command)
.RegisterParameter(bindingData.ElementId, bindingData.ParameterValue);
}
}
Expand All @@ -143,7 +159,6 @@ public ICommandWrapper GetCommandWrapper(IBindingContext context, CommandBinding

var args = new object[] { valueConverter };
var wrapperType = typeof(CommandWrapper<>).MakeGenericType(commandValueType);
var command = propertyInfo.GetValue(context);

commandWrapper = ObjectWrapperHelper
.CreateCommandWrapper(wrapperType, args, converterId, commandId, command)
Expand Down Expand Up @@ -297,24 +312,26 @@ private void ReturnWrapper(IObjectWrapper wrapper)
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private object GetMemberValue(IBindingContext context, MemberInfo memberInfo, out Type memberValueType)
private static object GetMemberValue(IBindingContext context, MemberInfo memberInfo, out Type memberType)
{
switch (memberInfo.MemberType)
{
case MemberTypes.Field:
{
var fieldInfo = (FieldInfo) memberInfo;
memberValueType = fieldInfo.FieldType.GenericTypeArguments[0];
memberType = fieldInfo.FieldType;

return fieldInfo.GetValue(context);
}

case MemberTypes.Property:
{
var propertyInfo = (PropertyInfo) memberInfo;
memberValueType = propertyInfo.PropertyType.GenericTypeArguments[0];
memberType = propertyInfo.PropertyType;

return propertyInfo.GetValue(context);
}

default:
throw new ArgumentOutOfRangeException();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using System;
using System.Runtime.CompilerServices;
using UnityMvvmToolkit.Core.Attributes;
using UnityMvvmToolkit.Core.Interfaces;
using UnityMvvmToolkit.Core.Internal.Interfaces;

namespace UnityMvvmToolkit.Core.Internal.ObjectWrappers
{
internal sealed class ReadOnlyPropertyWrapper<TSource, TValue> : IReadOnlyProperty<TValue>, IPropertyWrapper
{
private readonly IPropertyValueConverter<TSource, TValue> _valueConverter;

private int _converterId;
private bool _isInitialized;

private TValue _value;

[Preserve]
public ReadOnlyPropertyWrapper(IPropertyValueConverter<TSource, TValue> valueConverter)
{
_converterId = -1;
_valueConverter = valueConverter;
}

public int ConverterId => _converterId;

public TValue Value
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _value;
}

#pragma warning disable 67
public event EventHandler<TValue> ValueChanged;
#pragma warning restore 67

public IPropertyWrapper SetConverterId(int converterId)
{
if (_converterId != -1)
{
throw new InvalidOperationException("Can not change converter ID.");
}

_converterId = converterId;

return this;
}

public IPropertyWrapper SetProperty(object readOnlyProperty)
{
if (_isInitialized)
{
throw new InvalidOperationException(
$"{nameof(ReadOnlyPropertyWrapper<TValue, TSource>)} was not reset.");
}

_value = _valueConverter.Convert(((IReadOnlyProperty<TSource>) readOnlyProperty).Value);
_isInitialized = true;

return this;
}

public void Reset()
{
_value = default;
_isInitialized = false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -114,15 +114,7 @@ public TCommand GetCommand<TCommand>(IBindingContext context, string propertyNam
throw new InvalidOperationException($"Command '{propertyName}' not found.");
}

var propertyInfo = (PropertyInfo) memberInfo;

if (typeof(TCommand).IsAssignableFrom(propertyInfo.PropertyType))
{
return (TCommand) propertyInfo.GetValue(context);
}

throw new InvalidCastException(
$"Can not cast the {propertyInfo.PropertyType} command to the {typeof(TCommand)} command.");
return _objectWrapperHandler.GetCommand<TCommand>(context, memberInfo);
}

public IBaseCommand RentCommandWrapper(IBindingContext context, CommandBindingData bindingData)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace UnityMvvmToolkit.Core.Interfaces
{
public interface IProperty<T> : IReadOnlyProperty<T>
public interface IProperty<T> : IReadOnlyProperty<T>, IProperty
{
new T Value { get; set; }

Expand Down
Loading