Add output nucleus selection

This commit is contained in:
Pascal Serrarens 2026-02-06 17:31:58 +01:00
parent 7fffa6dbe5
commit 790deab7c6
3 changed files with 145 additions and 89 deletions

View File

@ -18,10 +18,56 @@ public class ClusterInspector : Editor {
public override VisualElement CreateInspectorGUI() { public override VisualElement CreateInspectorGUI() {
ClusterPrefab cluster = target as ClusterPrefab; ClusterPrefab cluster = target as ClusterPrefab;
if (cluster != null)
cluster.EnsureInitialization();
serializedObject.Update(); serializedObject.Update();
VisualElement root = new(); VisualElement root = new();
//GraphView graph =
CreateInspector(root, cluster);
// root.style.paddingLeft = 0;
// root.style.paddingRight = 0;
// root.style.paddingTop = 0;
// root.style.paddingBottom = 0;
// root.styleSheets.Add(Resources.Load<StyleSheet>("GraphStyles"));
// mainContainer = new() {
// style = {
// height = 450
// }
// };
// GraphView graph = new();
// graph.style.flexGrow = 1;
// inspectorContainer = new VisualElement {
// name = "inspector"
// };
// mainContainer.Add(graph);
// mainContainer.Add(inspectorContainer);
// root.Add(mainContainer);
// // Run once for initial state (use resolved style width if available)
// float initialWidth = root.layout.width > 0 ? root.layout.width : root.contentRect.width;
// UpdateLayout(initialWidth);
// // React to size changes of root (or parent if appropriate)
// root.RegisterCallback<GeometryChangedEvent>(evt => {
// UpdateLayout(evt.newRect.width);
// });
//graph.SetGraph(null, cluster, cluster.output, inspectorContainer);
// else
// Debug.LogWarning(" No brain!");
serializedObject.ApplyModifiedProperties();
return root;
}
public static GraphView CreateInspector(VisualElement root, ClusterPrefab cluster) {
root.style.paddingLeft = 0; root.style.paddingLeft = 0;
root.style.paddingRight = 0; root.style.paddingRight = 0;
root.style.paddingTop = 0; root.style.paddingTop = 0;
@ -29,16 +75,23 @@ public class ClusterInspector : Editor {
root.styleSheets.Add(Resources.Load<StyleSheet>("GraphStyles")); root.styleSheets.Add(Resources.Load<StyleSheet>("GraphStyles"));
// does the main container have added value?
// is just is like the root
mainContainer = new() { mainContainer = new() {
style = { style = {
height = 450 height = 450,
flexDirection = FlexDirection.Row
} }
}; };
GraphView graph = new(); GraphView graph = new();
graph.style.flexGrow = 1; graph.style.flexGrow = 1;
inspectorContainer = new VisualElement { inspectorContainer = new VisualElement {
// name = "inspector" name = "inspector",
style = {
width = 300,
flexGrow = 0
}
}; };
mainContainer.Add(graph); mainContainer.Add(graph);
@ -47,24 +100,33 @@ public class ClusterInspector : Editor {
// Run once for initial state (use resolved style width if available) // Run once for initial state (use resolved style width if available)
float initialWidth = root.layout.width > 0 ? root.layout.width : root.contentRect.width; float initialWidth = root.layout.width > 0 ? root.layout.width : root.contentRect.width;
UpdateLayout(initialWidth); //UpdateLayout(initialWidth);
// React to size changes of root (or parent if appropriate) // React to size changes of root (or parent if appropriate)
root.RegisterCallback<GeometryChangedEvent>(evt => { // root.RegisterCallback<GeometryChangedEvent>(evt => {
UpdateLayout(evt.newRect.width); // UpdateLayout(evt.newRect.width);
}); // });
if (cluster != null) { graph.SetGraph(null, cluster, cluster.output, inspectorContainer);
cluster.EnsureInitialization();
graph.SetGraph(null, cluster, cluster.output, inspectorContainer);
}
else
Debug.LogWarning(" No brain!");
serializedObject.ApplyModifiedProperties(); return graph;
return root;
} }
private static void UpdateLayout(float containerWidth) {
// if (containerWidth > 600f) {
// mainContainer.style.flexDirection = FlexDirection.Row;
// inspectorContainer.style.width = 300; // fixed sidebar width
// inspectorContainer.style.flexGrow = 0;
// }
// else {
// mainContainer.style.flexDirection = FlexDirection.Column;
// inspectorContainer.style.width = Length.Percent(100); // full width below
// inspectorContainer.style.flexDirection = FlexDirection.Column;
// inspectorContainer.style.flexGrow = 1; // can set 0 or keep as needed
// }
}
public class GraphView : VisualElement { public class GraphView : VisualElement {
ClusterPrefab cluster; ClusterPrefab cluster;
SerializedObject serializedBrain; SerializedObject serializedBrain;
@ -76,6 +138,12 @@ public class ClusterInspector : Editor {
ClusterWrapper currentWrapper; ClusterWrapper currentWrapper;
public enum OutputNodes {
Output,
Output2,
Output3
}
public GraphView() { public GraphView() {
name = "content"; name = "content";
style.flexGrow = 1; style.flexGrow = 1;
@ -88,11 +156,17 @@ public class ClusterInspector : Editor {
imguiContainer.focusable = true; imguiContainer.focusable = true;
Add(imguiContainer); Add(imguiContainer);
PopupField<OutputNodes> enumField = new(System.Enum.GetValues(typeof(OutputNodes)).Cast<OutputNodes>().ToList(), OutputNodes.Output);
enumField.RegisterValueChangedCallback(evt => OnOutputChanged(evt.newValue));
Add(enumField);
// Subscribe when added to panel (editor UI ready) // Subscribe when added to panel (editor UI ready)
RegisterCallback<AttachToPanelEvent>(evt => Subscribe()); RegisterCallback<AttachToPanelEvent>(evt => Subscribe());
RegisterCallback<DetachFromPanelEvent>(evt => Unsubscribe()); RegisterCallback<DetachFromPanelEvent>(evt => Unsubscribe());
} }
void OnOutputChanged(OutputNodes output) {
}
bool subscribed = false; bool subscribed = false;
void Subscribe() { void Subscribe() {
@ -400,7 +474,8 @@ public class ClusterInspector : Editor {
if (colonPos > 0) { if (colonPos > 0) {
string baseName = nucleus.name[..colonPos]; string baseName = nucleus.name[..colonPos];
Handles.Label(labelPos, baseName, style); Handles.Label(labelPos, baseName, style);
} else }
else
Handles.Label(labelPos, nucleus.name, style); Handles.Label(labelPos, nucleus.name, style);
} }
@ -706,23 +781,6 @@ public class ClusterInspector : Editor {
#endregion Start #endregion Start
#region Update
private void UpdateLayout(float containerWidth) {
// if (containerWidth > 600f) {
mainContainer.style.flexDirection = FlexDirection.Row;
inspectorContainer.style.width = 300; // fixed sidebar width
inspectorContainer.style.flexGrow = 0;
// }
// else {
// mainContainer.style.flexDirection = FlexDirection.Column;
// inspectorContainer.style.width = Length.Percent(100); // full width below
// inspectorContainer.style.flexDirection = FlexDirection.Column;
// inspectorContainer.style.flexGrow = 1; // can set 0 or keep as needed
// }
}
#endregion Update
} }
public class NeuroidLayer { public class NeuroidLayer {

View File

@ -11,14 +11,14 @@ public class NanoBrainComponent_Editor : Editor {
protected NanoBrain component; protected NanoBrain component;
private SerializedProperty brainProp; private SerializedProperty brainProp;
ClusterInspector.GraphView board; ClusterInspector.GraphView board;
public void OnEnable() { public void OnEnable() {
component = target as NanoBrain; component = target as NanoBrain;
if (Application.isPlaying == false) if (Application.isPlaying == false)
brainProp = serializedObject.FindProperty(nameof(NanoBrain.defaultBrain)); brainProp = serializedObject.FindProperty(nameof(NanoBrain.defaultBrain));
} }
public override VisualElement CreateInspectorGUI() { public override VisualElement CreateInspectorGUI() {
@ -29,56 +29,53 @@ public class NanoBrainComponent_Editor : Editor {
VisualElement root = new(); VisualElement root = new();
root.style.flexDirection = FlexDirection.Column; // side-by-side layout //ClusterInspector.GraphView board =
root.style.flexGrow = 1; ClusterInspector.CreateInspector(root, brain.prefab);
root.style.minHeight = 600; // root.style.paddingLeft = 0;
root.style.paddingLeft = 0; // root.style.paddingRight = 0;
root.style.paddingRight = 0; // root.style.paddingTop = 0;
root.style.paddingTop = 0; // root.style.paddingBottom = 0;
root.style.paddingBottom = 0;
root.styleSheets.Add(Resources.Load<StyleSheet>("GraphStyles")); // root.styleSheets.Add(Resources.Load<StyleSheet>("GraphStyles"));
if (Application.isPlaying == false) { // if (Application.isPlaying == false) {
PropertyField brainField = new(brainProp) { // PropertyField brainField = new(brainProp) {
label = "Nano Brain" // label = "Nano Brain"
}; // };
root.Add(brainField); // root.Add(brainField);
} // }
mainContainer = new() { // mainContainer = new() {
name = "main", // name = "main",
style = { // style = {
flexDirection = FlexDirection.Row, // height = 450,
flexGrow = 1, // }
minHeight = 500, // };
} // board = new ClusterInspector.GraphView();
}; // board.style.flexGrow = 1;
board = new ClusterInspector.GraphView(); // mainContainer.Add(board);
board.style.flexGrow = 1;
mainContainer.Add(board);
inspectorContainer = new VisualElement { // inspectorContainer = new VisualElement {
name = "inspector", // name = "inspector"
style = { // // style = {
width = 400, // // width = 400,
} // // }
}; // };
mainContainer.Add(inspectorContainer); // mainContainer.Add(inspectorContainer);
root.Add(mainContainer); // root.Add(mainContainer);
// Run once for initial state (use resolved style width if available) // // Run once for initial state (use resolved style width if available)
float initialWidth = root.layout.width > 0 ? root.layout.width : root.contentRect.width; // float initialWidth = root.layout.width > 0 ? root.layout.width : root.contentRect.width;
UpdateLayout(initialWidth); // UpdateLayout(initialWidth);
// React to size changes of root (or parent if appropriate) // // React to size changes of root (or parent if appropriate)
root.RegisterCallback<GeometryChangedEvent>(evt => { // root.RegisterCallback<GeometryChangedEvent>(evt => {
UpdateLayout(evt.newRect.width); // UpdateLayout(evt.newRect.width);
}); // });
if (brain != null && board != null) // if (brain != null && board != null)
board.SetGraph(component.gameObject, brain.prefab, brain.output, inspectorContainer); // board.SetGraph(component.gameObject, brain.prefab, brain.output, inspectorContainer);
// else // else
// Debug.LogWarning(" No brain!"); // Debug.LogWarning(" No brain!");
@ -87,18 +84,18 @@ public class NanoBrainComponent_Editor : Editor {
return root; return root;
} }
private void UpdateLayout(float containerWidth) { // private void UpdateLayout(float containerWidth) {
// if (containerWidth > 800f) { // // if (containerWidth > 800f) {
mainContainer.style.flexDirection = FlexDirection.Row; // mainContainer.style.flexDirection = FlexDirection.Row;
inspectorContainer.style.width = 400; // fixed sidebar width // inspectorContainer.style.width = 300; // fixed sidebar width
inspectorContainer.style.flexGrow = 0; // inspectorContainer.style.flexGrow = 0;
// } // // }
// else { // // else {
// mainContainer.style.flexDirection = FlexDirection.Column; // // mainContainer.style.flexDirection = FlexDirection.Column;
// inspectorContainer.style.width = Length.Percent(100); // full width below // // inspectorContainer.style.width = Length.Percent(100); // full width below
// inspectorContainer.style.flexDirection = FlexDirection.Column; // // inspectorContainer.style.flexDirection = FlexDirection.Column;
// inspectorContainer.style.flexGrow = 1; // can set 0 or keep as needed // // inspectorContainer.style.flexGrow = 1; // can set 0 or keep as needed
// } // // }
} // }
} }

View File

@ -27,6 +27,7 @@ public abstract class Nucleus {
_outputValue = value; _outputValue = value;
} }
} }
public bool isFiring => length(_outputValue) > 0.5f;
public bool isSleeping => lengthsq(this.outputValue) == 0; public bool isSleeping => lengthsq(this.outputValue) == 0;
[NonSerialized] [NonSerialized]