Skip to content

Commit

Permalink
😊 重写 新流变(粘土)对象事件处理机制及其实例作为方法调用的处理逻辑
Browse files Browse the repository at this point in the history
  • Loading branch information
MonkSoul committed Jan 19, 2025
1 parent 0e8756c commit a46500f
Show file tree
Hide file tree
Showing 4 changed files with 192 additions and 164 deletions.
71 changes: 40 additions & 31 deletions framework/Furion.Pure/V5_Experience/Shapeless/Clay/Clay.Override.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,41 +86,50 @@ public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object
/// <inheritdoc />
public override bool TryInvoke(InvokeBinder binder, object?[]? args, out object? result)
{
// 处理没有提供参数情况
if (args.IsNullOrEmpty())
// 处理 Clay 实例作为方法调用情况
switch (args)
{
result = ToJsonString();
return true;
}
// 处理没有提供参数情况
case { Length: 0 }:
result = ToJsonString();
return true;
// 处理单个参数情况
case { Length: 1 }:
switch (args)
{
// 处理 clay(JsonSerializerOptions) 情况
case [JsonSerializerOptions jsonSerializerOptions]:
result = ToJsonString(jsonSerializerOptions);
return true;
// 处理 clay(identifier) 情况
case [string or char or int or Index or Range]:
result = GetValue(args[0]!);
return true;
// 处理 clay(Type) 情况
case [Type resultType]:
result = As(resultType);
return true;
// 处理 clay(ClayOptions) 情况
case [ClayOptions clayOptions]:
result = Rebuilt(clayOptions);
return true;
}

// 处理非单个参数情况
if (args.Length != 1)
{
return base.TryInvoke(binder, args, out result);
}
break;
// 处理两个参数情况
case { Length: 2 }:
switch (args)
{
// 处理 clay(Type, JsonSerializerOptions) 情况
case [Type resultType, JsonSerializerOptions jsonSerializerOptions]:
result = As(resultType, jsonSerializerOptions);
return true;
}

// 处理单个参数情况
switch (args[0])
{
// 处理 clay(ClayOptions) 情况
case ClayOptions clayOptions:
result = Rebuilt(clayOptions);
return true;
// 处理 clay(Type) 情况
case Type resultType:
result = As(resultType);
return true;
// 处理 clay(JsonSerializerOptions) 情况
case JsonSerializerOptions jsonSerializerOptions:
result = ToJsonString(jsonSerializerOptions);
return true;
// 处理 clay(identifier) 情况
case string or char or int or Index or Range:
result = GetValue(args[0]!);
return true;
default:
return base.TryInvoke(binder, args, out result);
break;
}

return base.TryInvoke(binder, args, out result);
}

/// <inheritdoc />
Expand Down
107 changes: 56 additions & 51 deletions framework/Furion.Pure/V5_Experience/Shapeless/Clay/Clay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,21 +120,10 @@ internal bool SetValue(object identifier, object? value, bool insert = false)
// 空检查
ArgumentNullException.ThrowIfNull(identifier);

// 触发数据变更之前事件
OnChanging(identifier);

// 根据标识符设置值并获取结果
var result = IsObject
? SetNodeInObject(identifier, value, out var finalIndex)
: SetNodeInArray(identifier, value, out finalIndex, insert);

// 触发数据变更之后事件
if (result)
{
OnChanged(finalIndex);
}

return result;
return IsObject
? SetNodeInObject(identifier, value)
: SetNodeInArray(identifier, value, insert);
}

/// <summary>
Expand All @@ -152,27 +141,10 @@ internal bool RemoveValue(object identifier)
// 空检查
ArgumentNullException.ThrowIfNull(identifier);

// 检查是否是集合/数组且标识符是 Range 实例
if (IsArray && identifier is Range range)
{
return RemoveNodeFromArrayByRange(range);
}

// 触发移除数据之前事件
OnRemoving(identifier);

// 根据标识符移除值并获取结果
var result = IsObject
? RemoveNodeFromObject(identifier, out var finalIndex)
: RemoveNodeFromArray(identifier, out finalIndex);

// 触发移除数据之后事件
if (result)
{
OnRemoved(finalIndex);
}

return result;
return IsObject
? RemoveNodeFromObject(identifier)
: RemoveNodeFromArray(identifier);
}

/// <summary>
Expand Down Expand Up @@ -277,12 +249,11 @@ internal bool RemoveValue(object identifier)
/// </summary>
/// <param name="key">键</param>
/// <param name="value">属性值</param>
/// <param name="finalKey">最终设置键</param>
/// <returns>
/// <see cref="bool" />
/// </returns>
/// <exception cref="NotSupportedException"></exception>
internal bool SetNodeInObject(object key, object? value, out object finalKey)
internal bool SetNodeInObject(object key, object? value)
{
// 检查键是否是不受支持的类型
ThrowIfUnsupportedKeyType(key);
Expand All @@ -307,10 +278,16 @@ internal bool SetNodeInObject(object key, object? value, out object finalKey)
{
// 移除可能存在的同名委托属性
ObjectMethods.Remove(identifier);

// 触发数据变更之前事件
OnChanging(identifier);

jsonObject[identifier] = SerializeToNode(value, Options);

// 触发数据变更之后事件
OnChanged(identifier);
}

finalKey = identifier;
return true;
}

Expand All @@ -319,13 +296,12 @@ internal bool SetNodeInObject(object key, object? value, out object finalKey)
/// </summary>
/// <param name="index">索引</param>
/// <param name="value">元素值</param>
/// <param name="finalIndex">最终设置索引</param>
/// <param name="insert">是否作为在指定位置插入</param>
/// <returns>
/// <see cref="bool" />
/// </returns>
/// <exception cref="NotSupportedException"></exception>
internal bool SetNodeInArray(object index, object? value, out object finalIndex, bool insert = false)
internal bool SetNodeInArray(object index, object? value, bool insert = false)
{
// 检查是否是 Range 实例
if (index is Range)
Expand All @@ -347,6 +323,9 @@ internal bool SetNodeInArray(object index, object? value, out object finalIndex,
// 获取 JsonArray 长度
var count = jsonArray.Count;

// 触发数据变更之前事件
OnChanging(intIndex);

// 检查索引小于数组长度
if (intIndex < count)
{
Expand All @@ -363,19 +342,24 @@ internal bool SetNodeInArray(object index, object? value, out object finalIndex,
{
jsonArray.Insert(intIndex, jsonNodeValue);
}

// 触发数据变更之后事件
OnChanged(intIndex);
}
// 检查索引是否等于长度,如果是则追加
else if (intIndex == count)
{
jsonArray.Add(SerializeToNode(value, Options));

// 触发数据变更之后事件
OnChanged(intIndex);
}
// 检查是否允许访问越界的数组,如果是则采用补位方式
else if (Options.AllowIndexOutOfRange)
{
// 检查是否需要进行补位操作
if (!Options.AutoExpandArrayWithNulls)
{
finalIndex = null!;
return false;
}

Expand All @@ -387,26 +371,27 @@ internal bool SetNodeInArray(object index, object? value, out object finalIndex,
}

jsonArray.Add(SerializeToNode(value, Options));

// 触发数据变更之后事件
OnChanged(intIndex);
}
else
{
ThrowIfOutOfRange(intIndex, count);
}

finalIndex = intIndex;
return true;
}

/// <summary>
/// 根据键删除 <see cref="JsonNode" /> 节点
/// </summary>
/// <param name="key">键</param>
/// <param name="finalKey">最终移除键</param>
/// <returns>
/// <see cref="bool" />
/// </returns>
/// <exception cref="NotSupportedException"></exception>
internal bool RemoveNodeFromObject(object key, out object finalKey)
internal bool RemoveNodeFromObject(object key)
{
// 检查键是否是不受支持的类型
ThrowIfUnsupportedKeyType(key);
Expand All @@ -420,10 +405,21 @@ internal bool RemoveNodeFromObject(object key, out object finalKey)
// 将 JsonCanvas 转换为 JsonObject 实例
var jsonObject = JsonCanvas.AsObject();

// 移除可能存在的同名委托属性
if (ObjectMethods.Remove(identifier))
{
return true;
}

// 触发移除数据之前事件
OnRemoving(identifier);

// 移除键
if (ObjectMethods.Remove(identifier) || jsonObject.Remove(identifier))
if (jsonObject.Remove(identifier))
{
finalKey = identifier;
// 触发移除数据之后事件
OnRemoved(identifier);

return true;
}

Expand All @@ -433,20 +429,24 @@ internal bool RemoveNodeFromObject(object key, out object finalKey)
throw new KeyNotFoundException($"The property `{identifier}` was not found in the Clay.");
}

finalKey = null!;
return false;
}

/// <summary>
/// 根据索引删除 <see cref="JsonNode" /> 节点
/// </summary>
/// <param name="index">索引</param>
/// <param name="finalIndex">最终移除索引</param>
/// <returns>
/// <see cref="bool" />
/// </returns>
internal bool RemoveNodeFromArray(object index, out object finalIndex)
internal bool RemoveNodeFromArray(object index)
{
// 检查是否是 Range 实例
if (index is Range range)
{
return RemoveNodeFromArrayByRange(range);
}

// 将 JsonCanvas 转换为 JsonArray 实例
var jsonArray = JsonCanvas.AsArray();

Expand All @@ -461,11 +461,17 @@ internal bool RemoveNodeFromArray(object index, out object finalIndex)
// 获取 JsonArray 长度
var count = jsonArray.Count;

// 触发移除数据之前事件
OnRemoving(intIndex);

// 检查索引小于数组长度
if (intIndex < count)
{
jsonArray.RemoveAt(intIndex);
finalIndex = intIndex;

// 触发移除数据之后事件
OnRemoved(intIndex);

return true;
}

Expand All @@ -475,7 +481,6 @@ internal bool RemoveNodeFromArray(object index, out object finalIndex)
ThrowIfOutOfRange(intIndex, count);
}

finalIndex = null!;
return false;
}

Expand All @@ -496,7 +501,7 @@ internal bool RemoveNodeFromArrayByRange(Range range)
// 移除指定范围内的元素
for (var i = 0; i < length; i++)
{
RemoveValue(offset);
RemoveNodeFromArray(offset);
}

return true;
Expand Down
Loading

0 comments on commit a46500f

Please sign in to comment.