feat: 项目初始化 + 3D方块世界原型 + AI助搭系统
CI / Go Backend (push) Canceled after 0s

初始化 monorepo: Go后端(7微服务) + Unity客户端(9模块) + 启动器

HTML5原型: Three.js 3D体素世界, Perlin噪声地形, 原版材质, 22种方块

Minecraft创造模式背包: 双栏布局, 拖拽移动物品, 方向性元件引脚

AI助搭策划文档 + 客户端/服务端骨架 + Docker Compose + CI
This commit is contained in:
xyou
2026-08-08 14:07:56 +08:00
parent 9500c4c80a
commit f70b061d1a
1972 changed files with 159760 additions and 6 deletions
@@ -0,0 +1,28 @@
using System;
namespace PCL.Core.UI.Animation.Animatable;
public sealed class ClrAnimatable<TOwner, T> : IAnimatable
{
private readonly TOwner _owner;
private readonly Func<TOwner, T> _getter;
private readonly Action<TOwner, T> _setter;
public ClrAnimatable(
TOwner owner,
Func<TOwner, T> getter,
Action<TOwner, T> setter)
{
_owner = owner ?? throw new ArgumentNullException(nameof(owner));
_getter = getter ?? throw new ArgumentNullException(nameof(getter));
_setter = setter ?? throw new ArgumentNullException(nameof(setter));
}
public T GetValue() => _getter(_owner);
public void SetValue(T value) => _setter(_owner, value);
object? IAnimatable.GetValue() => GetValue();
void IAnimatable.SetValue(object? value) => SetValue((T)value!);
void IAnimatable.SetValue<TValue>(TValue value) => SetValue((T)(object)value!);
}
@@ -0,0 +1,23 @@
namespace PCL.Core.UI.Animation.Animatable;
public sealed class EmptyAnimatable : IAnimatable
{
public static EmptyAnimatable Instance { get; } = new();
private EmptyAnimatable() { }
public object? GetValue()
{
return null;
}
public void SetValue(object value)
{
// 空
}
public void SetValue<T>(T value)
{
// 空
}
}
@@ -0,0 +1,8 @@
namespace PCL.Core.UI.Animation.Animatable;
public interface IAnimatable
{
public object? GetValue();
public void SetValue(object value);
public void SetValue<T>(T value);
}
@@ -0,0 +1,105 @@
using System;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Media;
using PCL.Core.UI.Animation.ValueProcessor;
namespace PCL.Core.UI.Animation.Animatable;
public sealed class WpfAnimatable(DependencyObject owner, DependencyProperty? property) : IAnimatable
{
public DependencyObject Owner { get; set; } = owner;
public DependencyProperty? Property { get; set; } = property;
public object? GetValue()
{
DependencyProperty? actualProperty;
if (Property == FrameworkElement.WidthProperty)
{
actualProperty = FrameworkElement.ActualWidthProperty;
}
else if (Property == FrameworkElement.HeightProperty)
{
actualProperty = FrameworkElement.ActualHeightProperty;
}
else
{
actualProperty = Property;
}
ArgumentNullException.ThrowIfNull(actualProperty);
var value = Owner.GetValue(actualProperty);
return value switch
{
SolidColorBrush brush => (NColor)brush,
Color color => (NColor)color,
ScaleTransform scaleTransform => (NScaleTransform)scaleTransform,
RotateTransform rotateTransform => (NRotateTransform)rotateTransform,
_ => value
};
}
public void SetValue(object value)
{
value = ValueProcessorManager.Filter(value);
ArgumentNullException.ThrowIfNull(Property);
value = value switch
{
NColor color => Property.Name switch
{
"Color" => (Color)color,
_ => (SolidColorBrush)color
},
NScaleTransform st => (ScaleTransform)st,
NRotateTransform rt => (RotateTransform)rt,
_ => value
};
Owner.SetValue(Property, value);
}
public void SetValue<T>(T value)
{
value = ValueProcessorManager.Filter(value);
ArgumentNullException.ThrowIfNull(Property);
_SetValueCore(value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void _SetValueCore<T>(T value)
{
ArgumentNullException.ThrowIfNull(Property);
if (typeof(T) == typeof(NColor))
{
var color = Unsafe.As<T, NColor>(ref value);
Owner.SetValue(
Property,
Property.Name == "Color"
? (Color)color
: (SolidColorBrush)color);
return;
}
if (typeof(T) == typeof(NScaleTransform))
{
var st = Unsafe.As<T, NScaleTransform>(ref value);
Owner.SetValue(Property, (ScaleTransform)st);
return;
}
if (typeof(T) == typeof(NRotateTransform))
{
var rt = Unsafe.As<T, NRotateTransform>(ref value);
Owner.SetValue(Property, (RotateTransform)rt);
return;
}
Owner.SetValue(Property, value!);
}
}