Seven is the number.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

208 lines
5.1 KiB

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace LeTai.TrueShadow
{
interface IChangeTracker
{
void Check();
}
class ChangeTracker<T> : IChangeTracker
{
T previousValue;
readonly Func<T> getValue;
readonly Func<T, T> onChange;
readonly IEqualityComparer<T> comparer;
public ChangeTracker(Func<T> getValue,
Func<T, T> onChange,
IEqualityComparer<T> comparer = null)
{
this.getValue = getValue;
this.onChange = onChange;
this.comparer = comparer ?? EqualityComparer<T>.Default;
previousValue = this.getValue();
}
public void Forget()
{
previousValue = getValue();
}
public void Check()
{
T newValue = getValue();
if (!comparer.Equals(newValue, previousValue))
{
previousValue = onChange(newValue);
}
}
}
public partial class TrueShadow
{
Action checkHierarchyDirtiedDelegate;
IChangeTracker[] transformTrackers;
ChangeTracker<int>[] hierachyTrackers;
void InitInvalidator()
{
checkHierarchyDirtiedDelegate = CheckHierarchyDirtied;
hierachyTrackers = new[] {
new ChangeTracker<int>(
() => transform.GetSiblingIndex(),
newValue =>
{
SetHierachyDirty();
return newValue; // + 1;
}
),
new ChangeTracker<int>(
() =>
{
if (shadowRenderer)
return shadowRenderer.transform.GetSiblingIndex();
return -1;
},
newValue =>
{
SetHierachyDirty();
return newValue; // + 1;
}
)
};
transformTrackers = new IChangeTracker[] {
new ChangeTracker<Vector3>(
() => transform.position,
newValue =>
{
SetLayoutDirty();
return newValue;
}
),
new ChangeTracker<Quaternion>(
() => transform.rotation,
newValue =>
{
SetLayoutDirty();
if (Cutout)
SetTextureDirty();
return newValue;
}
),
};
Graphic.RegisterDirtyLayoutCallback(SetLayoutTextureDirty);
Graphic.RegisterDirtyVerticesCallback(SetLayoutTextureDirty);
Graphic.RegisterDirtyMaterialCallback(OnGraphicMaterialDirty);
CheckHierarchyDirtied();
CheckTransformDirtied();
}
void TerminateInvalidator()
{
if (Graphic)
{
Graphic.UnregisterDirtyLayoutCallback(SetLayoutTextureDirty);
Graphic.UnregisterDirtyVerticesCallback(SetLayoutTextureDirty);
Graphic.UnregisterDirtyMaterialCallback(OnGraphicMaterialDirty);
}
}
void OnGraphicMaterialDirty()
{
SetLayoutTextureDirty();
shadowRenderer.UpdateMaterial();
}
internal void CheckTransformDirtied()
{
if (transformTrackers != null)
{
for (var i = 0; i < transformTrackers.Length; i++)
{
transformTrackers[i].Check();
}
}
}
internal void CheckHierarchyDirtied()
{
if (ShadowAsSibling && hierachyTrackers != null)
{
for (var i = 0; i < hierachyTrackers.Length; i++)
{
hierachyTrackers[i].Check();
}
}
}
internal void ForgetSiblingIndexChanges()
{
for (var i = 0; i < hierachyTrackers.Length; i++)
{
hierachyTrackers[i].Forget();
}
}
protected override void OnTransformParentChanged()
{
base.OnTransformParentChanged();
if (!isActiveAndEnabled) return;
SetHierachyDirty();
this.NextFrames(checkHierarchyDirtiedDelegate);
}
protected override void OnRectTransformDimensionsChange()
{
base.OnRectTransformDimensionsChange();
if (!isActiveAndEnabled) return;
SetLayoutTextureDirty();
}
protected override void OnDidApplyAnimationProperties()
{
if (!isActiveAndEnabled) return;
SetLayoutTextureDirty();
}
public void ModifyMesh(Mesh mesh)
{
if (!isActiveAndEnabled) return;
if (SpriteMesh) Utility.SafeDestroy(SpriteMesh);
SpriteMesh = Instantiate(mesh);
SetLayoutTextureDirty();
}
public void ModifyMesh(VertexHelper verts)
{
if (!isActiveAndEnabled) return;
// For when pressing play while in prefab mode
if (!SpriteMesh) SpriteMesh = new Mesh();
verts.FillMesh(SpriteMesh);
SetLayoutTextureDirty();
}
void SetLayoutTextureDirty()
{
SetLayoutDirty();
SetTextureDirty();
}
}
}