Zitga-Tech / ZBase.Foundation.Mvvm

An MVVM framework for Unity that utilizes C# Source Generator for better performance, based on CommunityToolkit.Mvvm
MIT License
11 stars 5 forks source link

How to define Adapter or Convert for custom struct? #8

Open eefan000 opened 2 months ago

grashaar commented 2 months ago

Adapters

To implement custom adapters, you might want to inspect the code here https://github.com/laicasaane/tower_of_encosy/tree/main/Assets/Module.Core/Mvvm You can start with this simple one though https://github.com/laicasaane/tower_of_encosy/blob/main/Assets/Module.Core/Mvvm/TimeToStringAdapters.cs

Converters

For custom converters, you don't have to do anything. For example, with this code:

[ObservableProperty] public AddressableKey<Sprite> Key { get => Get_Key(); set => Set_Key(value); }

a converter for AddressableKey<Sprite> will be source-generated under the hood.

Size of Custom Structs

I support structs whose size is up to 128 bytes. By default, only 8-bytes structs are supported without doing anything. For larger ones, you have to add one of these symbols into your project.

UNION_SIZE_16_BYTES
UNION_SIZE_24_BYTES
UNION_SIZE_32_BYTES
UNION_SIZE_40_BYTES
UNION_SIZE_48_BYTES
UNION_SIZE_56_BYTES
UNION_SIZE_64_BYTES
UNION_SIZE_72_BYTES
UNION_SIZE_80_BYTES
UNION_SIZE_88_BYTES
UNION_SIZE_96_BYTES
UNION_SIZE_104_BYTES
UNION_SIZE_112_BYTES
UNION_SIZE_120_BYTES
UNION_SIZE_128_BYTES

image

In case your struct is larger than 128 bytes you would need to modify the source code to support it.

https://github.com/Zitga-Tech/ZBase.Foundation.Mvvm/blob/main/Packages/ZBase.Foundation.Mvvm/Mvvm/Union/UnionData.cs

eefan000 commented 2 months ago

适配器

要实现自定义适配器,您可能需要检查此处的代码 https://github.com/laicasaane/tower_of_encosy/tree/main/Assets/Module.Core/Mvvm 您可以从这个简单的适配器开始,不过 https://github.com/laicasaane/tower_of_encosy/blob/main/Assets/Module.Core/Mvvm/TimeToStringAdapters.cs

变换 器

对于自定义转换器,您无需执行任何操作。例如,使用以下代码:

[ObservableProperty] public AddressableKey<Sprite> Key { get => Get_Key(); set => Set_Key(value); }

的转换器将在后台生成源。AddressableKey<Sprite>

自定义结构的大小

我支持最大 128 字节的结构体。默认情况下,仅支持 8 字节的结构体,无需执行任何操作。对于较大的元件,您必须将其中一个元件添加到您的项目中。

UNION_SIZE_16_BYTES
UNION_SIZE_24_BYTES
UNION_SIZE_32_BYTES
UNION_SIZE_40_BYTES
UNION_SIZE_48_BYTES
UNION_SIZE_56_BYTES
UNION_SIZE_64_BYTES
UNION_SIZE_72_BYTES
UNION_SIZE_80_BYTES
UNION_SIZE_88_BYTES
UNION_SIZE_96_BYTES
UNION_SIZE_104_BYTES
UNION_SIZE_112_BYTES
UNION_SIZE_120_BYTES
UNION_SIZE_128_BYTES

image

如果您的结构体大于 128 字节,则需要修改源代码以支持它。

https://github.com/Zitga-Tech/ZBase.Foundation.Mvvm/blob/main/Packages/ZBase.Foundation.Mvvm/Mvvm/Union/UnionData.cs

[Adapter(fromType: typeof(double), toType: typeof(string), order: 0)] Can other non base types be used for 'from Type'? For example, MyStruct

grashaar commented 2 months ago

Totally yes, you can inspect the custom adapters here https://github.com/laicasaane/tower_of_encosy/blob/main/Assets/Module.Core/Mvvm/AnyAddressablesAdapters.gen.cs

eefan000 commented 2 months ago

I noticed that some types automatically set adapters. How is this achieved? Can my custom adapter do this?

grashaar commented 2 months ago

Only C# built-in types are supported. Anything other than those you must implement a custom adapter.

grashaar commented 2 months ago

However, these is nothing magical though. It's just that default adapters are implemented for built-in types. I use T4 template for them so I can avoid manually and repetitively typing a lot of code.

https://github.com/Zitga-Tech/ZBase.Foundation.Mvvm/tree/main/Packages/ZBase.Foundation.Mvvm/Mvvm/ViewBinding/Adapters

grashaar commented 2 months ago

I noticed that some types automatically set adapters.

Wait a minute, you mean the inspector functionality that automatically chooses converter for you?

2024-09-11-21-59-55-642-Unity

eefan000 commented 2 months ago

I noticed that some types automatically set adapters.

Wait a minute, you mean the inspector functionality that automatically chooses converter for you?

2024-09-11-21-59-55-642-Unity 2024-09-11-21-59-55-642-Unity

Yes

grashaar commented 2 months ago

Edit: This is wrong! Read my later comment!


Oh. It depends on whether the tool can find a converter for type A => type B direction. However you generally don't need a converter for type A => type A (identity) direction.

As you can see in the image, I have loading circle that rotates over time. I bind its Transform with an EulerAngles property that returns a Vector3. The binder for Local Euler Angles also receives a Vector3 parameter, so I don't need a custom converter for this binding.

2024-09-11-22-05-41-287-Unity

For any direction that is Vector3 => other type you have to write the converter yourself, because the source generator just can't possibly know the logic behind that conversion.

You can inspect the code here to understand how to write a custom converter https://github.com/Zitga-Tech/ZBase.Foundation.Mvvm/blob/main/Packages/ZBase.Foundation.Mvvm/Mvvm/Union/UnionConverters.t4.cs

grashaar commented 2 months ago

Oops. I remembered it wrong!

You don't have to write any custom converter at all. But you're required to write a custom adapter for the direction Vector3 => other type.

I'm so sorry about this mistake.

grashaar commented 2 months ago

This terrible mistake is the consequence of not having a proper documentation. However I can't write any document for this package right now. You might see this package in another form later on. But I do have some plan for that by the way. Stay tuned!

eefan000 commented 2 months ago

This terrible mistake is the consequence of not having a proper documentation. However I can't write any document for this package right now. You might see this package in another form later on. But I do have some plan for that by the way. Stay tuned!

I am very much looking forward to it. What are the significant improvements expected to be made in the new Mvvm library?

grashaar commented 2 months ago

Oh. I don't intend for any improvement at first though. There will be a great change in the package structure. You should expect a monolithic/all-in-one package where I develop everything together. The internal code will see some changes too as I plan to update/replace some foundational code. You can think of this as a stage setup. Only after everything is in place, I will work on any meaningful improvement.