// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
using System;
using System.Collections.Generic;
using System.Linq;
using FlaxEngine;
using FlaxEngine.Assertions;
namespace FlaxEditor.Surface
{
///
/// It's responsible for creating new objects.
/// It contains collection of and allows to plug custom node types as well.
///
[HideInEditor]
public static class NodeFactory
{
///
/// The list of supported attribute types for Visject Surface parameters. Attributes must be marked with Serializable attribute and contain empty constructor.
///
public static readonly List ParameterAttributeTypes = new List(16)
{
typeof(TooltipAttribute),
typeof(LimitAttribute),
typeof(EditorDisplayAttribute),
typeof(EditorOrderAttribute),
typeof(HeaderAttribute),
typeof(RangeAttribute),
typeof(SpaceAttribute),
typeof(NoAnimateAttribute),
typeof(NoUndoAttribute),
};
///
/// The list of supported attribute types for Visject Surface function nodes. Attributes must be marked with Serializable attribute and contain empty constructor.
///
public static readonly List FunctionAttributeTypes = new List(8)
{
typeof(TooltipAttribute),
typeof(HideInEditorAttribute),
typeof(NoAnimateAttribute),
};
///
/// The list of supported attribute types for Visject Surface type. Attributes must be marked with Serializable attribute and contain empty constructor.
///
public static readonly List TypeAttributeTypes = new List(8)
{
typeof(TooltipAttribute),
typeof(HideInEditorAttribute),
};
///
/// The default Visject Node archetype groups collection.
///
public static readonly List DefaultGroups = new List(32)
{
new GroupArchetype
{
GroupID = 1,
Name = "Material",
Color = new Color(231, 76, 60),
Archetypes = Archetypes.Material.Nodes
},
new GroupArchetype
{
GroupID = 2,
Name = "Constants",
Color = new Color(243, 156, 18),
Archetypes = Archetypes.Constants.Nodes
},
new GroupArchetype
{
GroupID = 3,
Name = "Math",
Color = new Color(52, 152, 219),
Archetypes = Archetypes.Math.Nodes
},
new GroupArchetype
{
GroupID = 4,
Name = "Packing",
Color = new Color(155, 89, 182),
Archetypes = Archetypes.Packing.Nodes
},
new GroupArchetype
{
GroupID = 5,
Name = "Textures",
Color = new Color(46, 204, 113),
Archetypes = Archetypes.Textures.Nodes
},
new GroupArchetype
{
GroupID = 6,
Name = "Parameters",
Color = new Color(52, 73, 94),
Archetypes = Archetypes.Parameters.Nodes
},
new GroupArchetype
{
GroupID = 7,
Name = "Tools",
Color = new Color(149, 165, 166),
Archetypes = Archetypes.Tools.Nodes
},
new GroupArchetype
{
GroupID = 8,
Name = "Layers",
Color = new Color(249, 105, 116),
Archetypes = Archetypes.Layers.Nodes
},
new GroupArchetype
{
GroupID = 9,
Name = "Animations",
Color = new Color(105, 179, 160),
Archetypes = Archetypes.Animation.Nodes
},
new GroupArchetype
{
GroupID = 10,
Name = "Boolean",
Color = new Color(237, 28, 36),
Archetypes = Archetypes.Boolean.Nodes
},
new GroupArchetype
{
GroupID = 11,
Name = "Bitwise",
Color = new Color(181, 230, 29),
Archetypes = Archetypes.Bitwise.Nodes
},
new GroupArchetype
{
GroupID = 12,
Name = "Comparisons",
Color = new Color(148, 30, 34),
Archetypes = Archetypes.Comparisons.Nodes
},
// GroupID = 13 -> Custom Nodes provided externally
new GroupArchetype
{
GroupID = 14,
Name = "Particles",
Color = new Color(121, 210, 176),
Archetypes = Archetypes.Particles.Nodes
},
new GroupArchetype
{
GroupID = 15,
Name = "Particle Modules",
Color = new Color(221, 110, 176),
Archetypes = Archetypes.ParticleModules.Nodes
},
new GroupArchetype
{
GroupID = 16,
Name = "Function",
Color = new Color(109, 160, 24),
Archetypes = Archetypes.Function.Nodes
},
new GroupArchetype
{
GroupID = 17,
Name = "Flow",
Color = new Color(237, 136, 64),
Archetypes = Archetypes.Flow.Nodes
},
new GroupArchetype
{
GroupID = 18,
Name = "Collections",
Color = new Color(110, 180, 81),
Archetypes = Archetypes.Collections.Nodes
},
};
///
/// Gets the archetypes for the node.
///
/// The group archetypes.
/// The group identifier.
/// The type identifier.
/// The output group archetype.
/// The output node archetype.
/// True if found it, otherwise false.
public static bool GetArchetype(List groups, ushort groupID, ushort typeID, out GroupArchetype gArch, out NodeArchetype arch)
{
gArch = null;
arch = null;
// Find archetype for that node
foreach (var groupArchetype in groups)
{
if (groupArchetype.GroupID == groupID && groupArchetype.Archetypes != null)
{
foreach (var nodeArchetype in groupArchetype.Archetypes)
{
if (nodeArchetype.TypeID == typeID)
{
// Found
gArch = groupArchetype;
arch = nodeArchetype;
return true;
}
}
}
}
// Error
Editor.LogError($"Failed to create Visject Surface node with id: {groupID}:{typeID}");
return false;
}
///
/// Creates the node.
///
/// The group archetypes.
/// The node id.
/// The context.
/// The group identifier.
/// The type identifier.
/// Created node or null if failed.
public static SurfaceNode CreateNode(List groups, uint id, VisjectSurfaceContext context, ushort groupID, ushort typeID)
{
for (var i = 0; i < groups.Count; i++)
{
var groupArchetype = groups[i];
if (groupArchetype.GroupID == groupID && groupArchetype.Archetypes != null)
{
foreach (var nodeArchetype in groupArchetype.Archetypes)
{
if (nodeArchetype.TypeID == typeID)
{
SurfaceNode node;
if (nodeArchetype.Create != null)
node = nodeArchetype.Create(id, context, nodeArchetype, groupArchetype);
else
node = new SurfaceNode(id, context, nodeArchetype, groupArchetype);
return node;
}
}
}
}
return null;
}
///
/// Creates the node.
///
/// The node id.
/// The context.
/// The group archetype.
/// The node archetype.
/// Created node or null if failed.
public static SurfaceNode CreateNode(uint id, VisjectSurfaceContext context, GroupArchetype groupArchetype, NodeArchetype nodeArchetype)
{
Assert.IsTrue(groupArchetype.Archetypes.Contains(nodeArchetype));
SurfaceNode node;
if (nodeArchetype.Create != null)
node = nodeArchetype.Create(id, context, nodeArchetype, groupArchetype);
else
node = new SurfaceNode(id, context, nodeArchetype, groupArchetype);
return node;
}
}
}