Skip to content

Commit

Permalink
feat(custom nodes): users now have necessary hooks to create their ow…
Browse files Browse the repository at this point in the history
…n custom nodes (experimental)

This is very experimental and simply opens up the APIs necessary to create custom node types. There
is still a lot of work to be done here before proper docs can be written.
  • Loading branch information
ashblue committed Apr 20, 2024
1 parent 96449e8 commit 09e8596
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@

namespace CleverCrow.Fluid.Dialogues.Editors.NodeDisplays {
public class ChoiceCollection {
private readonly DialogueWindow _window;
private readonly NodeEditorBase _node;
private readonly NodeDataChoiceBase _data;
protected readonly DialogueWindow _window;
protected readonly NodeEditorBase _node;
protected readonly NodeDataChoiceBase _data;

private readonly List<ChoiceData> _graveyard = new List<ChoiceData>();
private readonly List<Connection> _connections = new List<Connection>();
private readonly List<SerializedObject> _serializedObjects = new List<SerializedObject>();
private readonly Stack<Action> _callbacks = new Stack<Action>();
private readonly SerializedObject _serializedData;
private readonly SerializedProperty _propChoices;
protected readonly List<ChoiceData> _graveyard = new List<ChoiceData>();
protected readonly List<Connection> _connections = new List<Connection>();
protected readonly List<SerializedObject> _serializedObjects = new List<SerializedObject>();
protected readonly Stack<Action> _callbacks = new Stack<Action>();
protected readonly SerializedObject _serializedData;
protected readonly SerializedProperty _propChoices;

private bool IsChoiceMemoryLeak => _data.choices.Count != _connections.Count;

Expand All @@ -35,9 +35,9 @@ public void Add () {
Undo.SetCurrentGroupName("Add choice");
Undo.RecordObject(_data, "Add choice");

var choice = ScriptableObject.CreateInstance<ChoiceData>();
choice.name = "Choice";
choice.Setup();
var choice = CreateChoice();

// Field should be overridable
_data.choices.Add(choice);

if (FluidDialogueSettings.Current.HideNestedNodeData) {
Expand All @@ -53,6 +53,14 @@ public void Add () {
Undo.CollapseUndoOperations(Undo.GetCurrentGroup());
}

protected virtual ChoiceData CreateChoice () {
var choice = ScriptableObject.CreateInstance<ChoiceData>();
choice.name = "Choice";
choice.Setup();

return choice;
}

public void Print (Event e) {
_serializedData.Update();

Expand Down Expand Up @@ -90,7 +98,7 @@ public NodeDataBase GetParentDataCopy (NodeDataChoiceBase copy) {
return copy;
}

private void PrintChoices (Event e) {
protected virtual void PrintChoices (Event e) {
for (var i = 0; i < _propChoices.arraySize; i++) {
GUILayout.BeginHorizontal();

Expand Down Expand Up @@ -120,7 +128,7 @@ private void PrintChoices (Event e) {
}
}

private void ShowEditMenu (ChoiceData choice, int index) {
protected void ShowEditMenu (ChoiceData choice, int index) {
GUI.FocusControl(null);
var menu = new GenericMenu();

Expand Down
67 changes: 43 additions & 24 deletions Assets/com.fluid.dialogue/Editor/Utilities/NodeAssemblies.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,52 @@ public static class NodeAssemblies {
_stringToData ?? (_stringToData = GetStringToData());

private static Dictionary<Type, Type> GetDataToDisplay () {
var displayTypes = Assembly
.GetAssembly(typeof(NodeEditorBase))
.GetTypes()
.Where(t => t.IsSubclassOf(typeof(NodeEditorBase)));

return displayTypes.ToDictionary(
(k) => {
var attribute = k.GetCustomAttribute<NodeTypeAttribute>();
return attribute.Type;
},
(v) => v);
var dict = new Dictionary<Type, Type>();

// Expensive to get all assemblies, but only way to get data outside the package
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) {
foreach (var type in assembly.GetTypes()) {
if (!type.IsSubclassOf(typeof(NodeEditorBase)) || type.IsAbstract) continue;

var attr = type.GetCustomAttribute<NodeTypeAttribute>();
if (attr == null) continue;

dict.Add(attr.Type, type);
}
}

return dict;
}

class TypeEntry {
public Type type;
public string path;
public int priority;
}

private static Dictionary<string, Type> GetStringToData () {
var menuTypes = Assembly
.GetAssembly(typeof(NodeDataBase))
.GetTypes()
.Where(t => t.IsSubclassOf(typeof(NodeDataBase))
&& t.GetCustomAttribute<CreateMenuAttribute>() != null)
.OrderByDescending(t => t.GetCustomAttribute<CreateMenuAttribute>().Priority);

return menuTypes.ToDictionary(
(k) => {
var attribute = k.GetCustomAttribute<CreateMenuAttribute>();
return attribute.Path;
},
(v) => v);
var list = new List<TypeEntry>();

// Expensive to get all assemblies, but only way to get data outside the package
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) {
foreach (var type in assembly.GetTypes()) {
if (!type.IsSubclassOf(typeof(NodeDataBase)) || type.IsAbstract) continue;
var attr = type.GetCustomAttribute<CreateMenuAttribute>();
if (attr == null) continue;

list.Add(new TypeEntry {
type = type,
path = attr?.Path ?? type.FullName,
priority = attr?.Priority ?? 0,
});
}
}

return list
.OrderByDescending(t => t.priority)
.ToDictionary(
(k) => k.path,
(v) => v.type);
}
}
}

0 comments on commit 09e8596

Please sign in to comment.