// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
using FlaxEditor.Scripting;
using FlaxEngine;
namespace FlaxEditor.Surface
{
///
/// The Visject Surface connection creation handler object.
///
[HideInEditor]
public interface IConnectionInstigator
{
///
/// Gets the connection origin point (in surface node space).
///
Vector2 ConnectionOrigin { get; }
///
/// Determines whether this surface object is connected with the specified other object.
///
/// The other object to check.
/// true if connection between given two objects exists; otherwise, false.
bool AreConnected(IConnectionInstigator other);
///
/// Determines whether this surface object can be connected with the specified other object.
///
/// The other object to check.
/// true if connection can be created; otherwise, false.
bool CanConnectWith(IConnectionInstigator other);
///
/// Draws the connecting line.
///
/// The start position.
/// The end position.
/// The color.
void DrawConnectingLine(ref Vector2 startPos, ref Vector2 endPos, ref Color color);
///
/// Created the new connection with the specified other object.
///
/// The other.
void Connect(IConnectionInstigator other);
}
public partial class VisjectSurface
{
///
/// Checks if can use direct conversion from one type to another.
///
/// Source type.
/// Target type.
/// True if can use direct conversion, otherwise false.
public bool CanUseDirectCast(ScriptType from, ScriptType to)
{
if (from == ScriptType.Null || to == ScriptType.Null)
return false;
bool result = from == to || to.IsAssignableFrom(from);
if (!result)
{
// Implicit casting is supported for reference types
var toIsReference = to.IsReference;
var fromIsReference = from.IsReference;
if (toIsReference && !fromIsReference)
{
var toTypeName = to.TypeName;
return from.TypeName == toTypeName.Substring(0, toTypeName.Length - 1);
}
if (!toIsReference && fromIsReference)
{
var fromTypeName = from.TypeName;
return to.TypeName == fromTypeName.Substring(0, fromTypeName.Length - 1);
}
// Implicit casting is supported for object reference to test whenever it is valid
var toType = to.Type;
if (_supportsImplicitCastFromObjectToBoolean && toType == typeof(bool) && new ScriptType(typeof(FlaxEngine.Object)).IsAssignableFrom(from))
{
return true;
}
// Implicit casting is supported for primitive types
var fromType = from.Type;
if (fromType == typeof(bool) ||
fromType == typeof(byte) ||
fromType == typeof(char) ||
fromType == typeof(short) ||
fromType == typeof(ushort) ||
fromType == typeof(int) ||
fromType == typeof(uint) ||
fromType == typeof(long) ||
fromType == typeof(ulong) ||
fromType == typeof(float) ||
fromType == typeof(double) ||
fromType == typeof(Vector2) ||
fromType == typeof(Vector3) ||
fromType == typeof(Vector4) ||
fromType == typeof(Color) ||
fromType == typeof(Quaternion))
{
if (toType == typeof(bool) ||
toType == typeof(byte) ||
toType == typeof(char) ||
toType == typeof(short) ||
toType == typeof(ushort) ||
toType == typeof(int) ||
toType == typeof(uint) ||
toType == typeof(long) ||
toType == typeof(ulong) ||
toType == typeof(float) ||
toType == typeof(double) ||
toType == typeof(Vector2) ||
toType == typeof(Vector3) ||
toType == typeof(Vector4) ||
toType == typeof(Color) ||
toType == typeof(Quaternion))
{
result = true;
}
}
}
return result;
}
///
/// Begins connecting surface objects action.
///
/// The connection instigator (eg. start box).
public void ConnectingStart(IConnectionInstigator instigator)
{
if (instigator != null && instigator != _connectionInstigator)
{
_connectionInstigator = instigator;
StartMouseCapture();
}
}
///
/// Callback for surface objects connections instigators to indicate mouse over control event (used to draw preview connections).
///
/// The instigator.
public void ConnectingOver(IConnectionInstigator instigator)
{
_lastInstigatorUnderMouse = instigator;
}
///
/// Ends connecting surface objects action.
///
/// The end object (eg. end box).
public void ConnectingEnd(IConnectionInstigator end)
{
// Ensure that there was a proper start box
if (_connectionInstigator == null)
return;
var start = _connectionInstigator;
_connectionInstigator = null;
// Check if boxes are different and end box is specified
if (start == end || end == null)
return;
// Connect them
if (start.CanConnectWith(end))
{
start.Connect(end);
}
}
}
}