using System;
using System.Collections.Generic;
using UnityEngine;
/// Base class for all nodes
[Serializable]
public abstract class Node : ScriptableObject {
public enum ShowBackingValue {
/// Never show the backing value
Never,
/// Show the backing value only when the port does not have any active connections
Unconnected,
/// Always show the backing value
Always
}
/// Parent
[SerializeField] public NodeGraph graph;
/// Position on the
[SerializeField] public Vector2 position;
/// Input s. It is recommended not to modify these at hand. Instead, see
[SerializeField] public List inputs = new List();
/// Output s. It is recommended not to modify these at hand. Instead, see
[SerializeField] public List outputs = new List();
public int InputCount { get { return inputs.Count; } }
public int OutputCount { get { return outputs.Count; } }
protected void OnEnable() {
NodeDataCache.UpdatePorts(this, inputs, outputs);
Init();
}
/// Checks all connections for invalid references, and removes them.
public void VerifyConnections() {
for (int i = 0; i < InputCount; i++) {
inputs[i].VerifyConnections();
}
for (int i = 0; i < OutputCount; i++) {
outputs[i].VerifyConnections();
}
}
/// Returns input or output port which matches fieldName
public NodePort GetPortByFieldName(string fieldName) {
NodePort port = GetOutputByFieldName(fieldName);
if (port != null) return port;
else return GetInputByFieldName(fieldName);
}
/// Returns output port which matches fieldName. Returns null if none found.
public NodePort GetOutputByFieldName(string fieldName) {
for (int i = 0; i < OutputCount; i++) {
if (outputs[i].fieldName == fieldName) return outputs[i];
}
return null;
}
/// Returns input port which matches fieldName. Returns null if none found.
public NodePort GetInputByFieldName(string fieldName) {
for (int i = 0; i < InputCount; i++) {
if (inputs[i].fieldName == fieldName) return inputs[i];
}
return null;
}
/// Return input value for a specified port. Returns fallback value if no ports are connected
/// Field name of requested input port
/// If no ports are connected, this value will be returned
public T GetInputByFieldName(string fieldName, T fallback = default(T)) {
NodePort port = GetInputByFieldName(fieldName);
if (port != null && port.IsConnected) return port.GetInputValue();
else return fallback;
}
/// Return all input values for a specified port. Returns fallback value if no ports are connected
/// Field name of requested input port
/// If no ports are connected, this value will be returned
public T[] GetInputsByFieldName(string fieldName, T[] fallback = default(T[])) {
NodePort port = GetInputByFieldName(fieldName);
if (port != null && port.IsConnected) return port.GetInputValues();
else return fallback;
}
/// Returns a value based on requested port output. Should be overridden before used.
/// The requested port.
public virtual object GetValue(NodePort port) {
Debug.LogWarning("No GetValue(NodePort port) override defined for " + GetType());
return null;
}
/// Initialize node. Called on creation.
protected virtual void Init() { name = GetType().Name; }
/// Called whenever a connection is being made between two s
/// Output Input
public virtual void OnCreateConnection(NodePort from, NodePort to) { }
/// Disconnect everything from this node
public void ClearConnections() {
for (int i = 0; i < inputs.Count; i++) {
inputs[i].ClearConnections();
}
for (int i = 0; i < outputs.Count; i++) {
outputs[i].ClearConnections();
}
}
public override int GetHashCode() {
return JsonUtility.ToJson(this).GetHashCode();
}
/// Mark a serializable field as an input port. You can access this through
[AttributeUsage(AttributeTargets.Field, AllowMultiple = true)]
public class InputAttribute : Attribute {
public ShowBackingValue backingValue;
/// Mark a serializable field as an input port. You can access this through
/// Should we display the backing value for this port as an editor field?
public InputAttribute(ShowBackingValue backingValue = ShowBackingValue.Unconnected) { this.backingValue = backingValue; }
}
/// Mark a serializable field as an output port. You can access this through
[AttributeUsage(AttributeTargets.Field, AllowMultiple = true)]
public class OutputAttribute : Attribute {
/// Mark a serializable field as an output port. You can access this through
public OutputAttribute() { }
}
}