Fix crash when removing Anim Event visual script that is used in opened Animation timeline
#2471
This commit is contained in:
@@ -249,6 +249,7 @@ namespace FlaxEditor.Content
|
|||||||
private ScriptMemberInfo[] _parameters;
|
private ScriptMemberInfo[] _parameters;
|
||||||
private ScriptMemberInfo[] _methods;
|
private ScriptMemberInfo[] _methods;
|
||||||
private object[] _attributes;
|
private object[] _attributes;
|
||||||
|
private List<Action<ScriptType>> _disposing;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the Visual Script asset that contains this type.
|
/// Gets the Visual Script asset that contains this type.
|
||||||
@@ -310,6 +311,13 @@ namespace FlaxEditor.Content
|
|||||||
|
|
||||||
internal void Dispose()
|
internal void Dispose()
|
||||||
{
|
{
|
||||||
|
if (_disposing != null)
|
||||||
|
{
|
||||||
|
foreach (var e in _disposing)
|
||||||
|
e(new ScriptType(this));
|
||||||
|
_disposing.Clear();
|
||||||
|
_disposing = null;
|
||||||
|
}
|
||||||
if (_parameters != null)
|
if (_parameters != null)
|
||||||
{
|
{
|
||||||
OnAssetReloading(_asset);
|
OnAssetReloading(_asset);
|
||||||
@@ -510,6 +518,14 @@ namespace FlaxEditor.Content
|
|||||||
}
|
}
|
||||||
return _methods;
|
return _methods;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void TrackLifetime(Action<ScriptType> disposing)
|
||||||
|
{
|
||||||
|
if (_disposing == null)
|
||||||
|
_disposing = new List<Action<ScriptType>>();
|
||||||
|
_disposing.Add(disposing);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
|||||||
if (Type == ScriptType.Null)
|
if (Type == ScriptType.Null)
|
||||||
{
|
{
|
||||||
Editor.LogError("Missing anim event type " + _instanceTypeName);
|
Editor.LogError("Missing anim event type " + _instanceTypeName);
|
||||||
|
InitMissing();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Instance = (AnimEvent)Type.CreateInstance();
|
Instance = (AnimEvent)Type.CreateInstance();
|
||||||
@@ -125,20 +126,37 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
|||||||
_isRegisteredForScriptsReload = true;
|
_isRegisteredForScriptsReload = true;
|
||||||
ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin;
|
ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin;
|
||||||
}
|
}
|
||||||
|
Type.TrackLifetime(OnTypeDisposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnTypeDisposing(ScriptType type)
|
||||||
|
{
|
||||||
|
if (Type == type && !IsDisposing)
|
||||||
|
{
|
||||||
|
// Turn into missing script
|
||||||
|
OnScriptsReloadBegin();
|
||||||
|
ScriptsBuilder.ScriptsReloadEnd -= OnScriptsReloadEnd;
|
||||||
|
InitMissing();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitMissing()
|
||||||
|
{
|
||||||
|
CanDelete = true;
|
||||||
|
CanSplit = false;
|
||||||
|
CanResize = false;
|
||||||
|
TooltipText = $"Missing Anim Event Type '{_instanceTypeName}'";
|
||||||
|
BackgroundColor = Color.Red;
|
||||||
|
Type = ScriptType.Null;
|
||||||
|
Instance = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void InitMissing(string typeName, byte[] data)
|
internal void InitMissing(string typeName, byte[] data)
|
||||||
{
|
{
|
||||||
Type = ScriptType.Null;
|
|
||||||
IsContinuous = false;
|
IsContinuous = false;
|
||||||
CanDelete = true;
|
|
||||||
CanSplit = false;
|
|
||||||
CanResize = false;
|
|
||||||
TooltipText = $"Missing Anim Event Type '{typeName}'";
|
|
||||||
Instance = null;
|
|
||||||
BackgroundColor = Color.Red;
|
|
||||||
_instanceTypeName = typeName;
|
_instanceTypeName = typeName;
|
||||||
_instanceData = data;
|
_instanceData = data;
|
||||||
|
InitMissing();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Load(BinaryReader stream)
|
internal void Load(BinaryReader stream)
|
||||||
|
|||||||
@@ -144,5 +144,11 @@ namespace FlaxEditor.Scripting
|
|||||||
{
|
{
|
||||||
return Utils.GetEmptyArray<ScriptMemberInfo>();
|
return Utils.GetEmptyArray<ScriptMemberInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void TrackLifetime(Action<ScriptType> disposing)
|
||||||
|
{
|
||||||
|
ElementType.TrackLifetime(disposing);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -167,6 +167,12 @@ namespace FlaxEditor.Scripting
|
|||||||
/// <param name="bindingAttr">A bitmask comprised of one or more <see cref="T:System.Reflection.BindingFlags" /> that specify how the search is conducted.-or- Zero (<see cref="F:System.Reflection.BindingFlags.Default" />), to return an empty array.</param>
|
/// <param name="bindingAttr">A bitmask comprised of one or more <see cref="T:System.Reflection.BindingFlags" /> that specify how the search is conducted.-or- Zero (<see cref="F:System.Reflection.BindingFlags.Default" />), to return an empty array.</param>
|
||||||
/// <returns>An array of member objects representing all methods defined for the current type that match the specified binding constraints.-or- An empty array of type member, if no methods are defined for the current type, or if none of the defined methods match the binding constraints.</returns>
|
/// <returns>An array of member objects representing all methods defined for the current type that match the specified binding constraints.-or- An empty array of type member, if no methods are defined for the current type, or if none of the defined methods match the binding constraints.</returns>
|
||||||
ScriptMemberInfo[] GetMethods(BindingFlags bindingAttr);
|
ScriptMemberInfo[] GetMethods(BindingFlags bindingAttr);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registers delegate to be invoked upon script type disposal (except hot-reload in Editor via <see cref="ScriptsBuilder.ScriptsReload"/>). For example, can happen when user deleted Visual Script asset.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">Event to call when script type gets disposed (eg. removed asset).</param>
|
||||||
|
void TrackLifetime(Action<ScriptType> disposing);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1395,11 +1395,21 @@ namespace FlaxEditor.Scripting
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Basic check to see if a type could be casted to another type
|
/// Registers delegate to be invoked upon script type disposal (except hot-reload in Editor via <see cref="ScriptsBuilder.ScriptsReload"/>). For example, can happen when user deleted Visual Script asset.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">Event to call when script type gets disposed (eg. removed asset).</param>
|
||||||
|
public void TrackLifetime(Action<ScriptType> disposing)
|
||||||
|
{
|
||||||
|
if (_custom != null)
|
||||||
|
_custom.TrackLifetime(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Basic check to see if a type could be cast to another type
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="from">Source type</param>
|
/// <param name="from">Source type</param>
|
||||||
/// <param name="to">Target type</param>
|
/// <param name="to">Target type</param>
|
||||||
/// <returns>True if the type can be casted</returns>
|
/// <returns>True if the type can be cast.</returns>
|
||||||
public static bool CanCast(ScriptType from, ScriptType to)
|
public static bool CanCast(ScriptType from, ScriptType to)
|
||||||
{
|
{
|
||||||
if (from == to)
|
if (from == to)
|
||||||
@@ -1412,10 +1422,10 @@ namespace FlaxEditor.Scripting
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Basic check to see if this type could be casted to another type
|
/// Basic check to see if this type could be cast to another type
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="to">Target type</param>
|
/// <param name="to">Target type</param>
|
||||||
/// <returns>True if the type can be casted</returns>
|
/// <returns>True if the type can be cast.</returns>
|
||||||
public bool CanCastTo(ScriptType to)
|
public bool CanCastTo(ScriptType to)
|
||||||
{
|
{
|
||||||
return CanCast(this, to);
|
return CanCast(this, to);
|
||||||
|
|||||||
@@ -104,6 +104,16 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnTypeDisposing(ScriptType type)
|
||||||
|
{
|
||||||
|
if (_type == type && !IsDisposing)
|
||||||
|
{
|
||||||
|
// Turn into missing script
|
||||||
|
_type = ScriptType.Null;
|
||||||
|
Instance = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnLoaded(SurfaceNodeActions action)
|
public override void OnLoaded(SurfaceNodeActions action)
|
||||||
{
|
{
|
||||||
base.OnLoaded(action);
|
base.OnLoaded(action);
|
||||||
@@ -113,6 +123,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
_type = TypeUtils.GetType(typeName);
|
_type = TypeUtils.GetType(typeName);
|
||||||
if (_type != null)
|
if (_type != null)
|
||||||
{
|
{
|
||||||
|
_type.TrackLifetime(OnTypeDisposing);
|
||||||
TooltipText = Editor.Instance.CodeDocs.GetTooltip(_type);
|
TooltipText = Editor.Instance.CodeDocs.GetTooltip(_type);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user