using Godot; using System; using System.Reflection; using System.Collections.Generic; namespace Rokojori { public partial class ShaderPropertyName:Resource { [Export] public string propertyName; string _cSharpName; MultiMap _propertyInfoCache = new MultiMap(); public void _Set<[MustBeVariant] T>( Material m, T value ) { if ( m is ShaderMaterial shaderMaterial ) { // RJLog.Log( "_Set", value, value.GetType() ); var variant = Variant.From( value ); shaderMaterial.SetShaderParameter( propertyName, variant ); return; } _SetStandardValue( m, value ); } public T _Get<[MustBeVariant] T>( Material material, T fallback ) { if ( material is ShaderMaterial shaderMaterial ) { return shaderMaterial.GetShaderParameter( propertyName ).As(); } return _GetStandardValue( material, fallback ); } protected void _SetStandardValue( Material material, object value ) { var p = _GetProperty( material ); if ( p == null ) { return; } p.SetValue( material, value ); } protected T _GetStandardValue( Material material, T fallback ) { var p = _GetProperty( material ); if ( p == null ) { return fallback; } var value = p.GetValue( material ); RJLog.Log( "GetStandardValue", _cSharpName, p.Name, ">>", value ); return (T) p.GetValue( material ); } protected PropertyInfo _GetProperty( Material material ) { var type = material.GetType(); if ( _cSharpName != null && _cSharpName != "" && _propertyInfoCache.Has( type, _cSharpName ) ) { RJLog.Log( type, ">>", material, "_cSharpName", _cSharpName ); return _propertyInfoCache[ type ][ _cSharpName ]; } if ( ! RegexUtility.StartsWithUpperCase( propertyName ) ) { _cSharpName = GDScriptNames.ToCS( propertyName ); } else { _cSharpName = propertyName; } var p = type.GetProperty( _cSharpName ); RJLog.Log( "_cSharpName", _cSharpName, material ); _propertyInfoCache.Set( type, _cSharpName, p ); return _propertyInfoCache[ type ][ _cSharpName ]; } } }