Automatic recreate cluster instance

This commit is contained in:
Pascal Serrarens 2026-05-20 17:14:38 +02:00
parent 92bfb29ed0
commit 57967e3409
3 changed files with 59 additions and 17 deletions

View File

@ -103,6 +103,8 @@ namespace NanoBrain.Unity {
public Nucleus currentNucleus = null;
public Nucleus selectedSynapseNeuron = null;
public Nucleus selectedOutput;
public bool isOpen = true;
public bool initialized;
#region Focus Graph

View File

@ -1,12 +1,9 @@
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using UnityEngine.UIElements;
using UnityEditor;
using System;
using System.Reflection;
namespace NanoBrain.Unity {
@ -15,7 +12,16 @@ namespace NanoBrain.Unity {
static Cluster_Drawer() {
SceneView.duringSceneGui += OnSceneGUI;
Selection.selectionChanged += OnSelectionChanged;
if (clusterView != null)
clusterView.initialized = false;
}
~Cluster_Drawer() {
SceneView.duringSceneGui -= OnSceneGUI;
}
//static readonly Dictionary<string, bool> s_foldouts = new();
static readonly Dictionary<string, ClusterView> clusterViews = new();
public static void Insepctor(SerializedObject serializedObject, string propertyName) {
EditorGUILayout.PropertyField(serializedObject.FindProperty(propertyName));
@ -26,12 +32,24 @@ namespace NanoBrain.Unity {
private static ClusterView clusterView;
private static UnityEngine.Object selectedTarget;
public ClusterView GetClusterView(SerializedProperty property) {
string key = property.propertyPath + "_" + property.serializedObject.targetObject.GetInstanceID();//GetEntityId();
if (clusterViews.TryGetValue(key, out ClusterView view))
return view;
view = new ClusterView();
clusterViews[key] = view;
return view;
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) {
float height = EditorGUIUtility.singleLineHeight + padding;
string key = property.propertyPath + "_" + property.serializedObject.targetObject.GetInstanceID();//GetEntityId();
s_foldouts.TryGetValue(key, out bool isOpen);
// string key = property.propertyPath + "_" + property.serializedObject.targetObject.GetInstanceID();//GetEntityId();
// //s_foldouts.TryGetValue(key, out bool isOpen);
// clusterViews.TryGetValue(key, out ClusterView view);
ClusterView view = GetClusterView(property);
SerializedProperty prefabProp = property.FindPropertyRelative(nameof(Cluster.prefab));
if (prefabProp.objectReferenceValue != null && isOpen) {
if (prefabProp.objectReferenceValue != null && view.isOpen) {
height += padding + elementHeight;
height = 500;
}
@ -40,9 +58,10 @@ namespace NanoBrain.Unity {
return height;
}
static readonly Dictionary<string, bool> s_foldouts = new();
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
ClusterView clusterView = GetClusterView(property);
label = EditorGUI.BeginProperty(position, label, property);
// Begin indent block
@ -73,27 +92,40 @@ namespace NanoBrain.Unity {
}
if (prefabProp.objectReferenceValue is ClusterPrefab prefab) {
// // Graph is not shown when multi-editing
if (property.serializedObject.targetObjects.Length == 1) {
// Graph is not shown when multi-editing
UnityEngine.Object targetObject = property.serializedObject.targetObject;
Cluster_Drawer.selectedTarget = targetObject;
Cluster cluster = SerializedPropertyUtility.GetManagedObjectForProperty(targetObject, property.propertyPath) as Cluster;
Cluster cluster;
if (clusterView.initialized) {
cluster = SerializedPropertyUtility.GetManagedObjectForProperty(targetObject, property.propertyPath) as Cluster;
}
else {
ClusterPrefab clusterPrefab = prefabProp.objectReferenceValue as ClusterPrefab;
cluster = new(clusterPrefab);
object parent = SerializedPropertyUtility.GetParentObjectAndMember(targetObject, property.propertyPath, out var memberInfo, out int outIndex);
if (parent != null && memberInfo is FieldInfo fieldInfo) {
fieldInfo.SetValue(parent, cluster);
EditorUtility.SetDirty(targetObject);
}
clusterView.initialized = true;
}
// key per field instance
string key = property.propertyPath + "_" + property.serializedObject.targetObject.GetInstanceID();//GetEntityId();
if (!s_foldouts.TryGetValue(key, out bool isOpen))
isOpen = true;
// if (!s_foldouts.TryGetValue(key, out bool isOpen))
// isOpen = true;
// foldout header rect
Rect headerRect = new(fieldRect.x, fieldRect.yMax + 4f, fieldRect.width, EditorGUIUtility.singleLineHeight);
isOpen = EditorGUI.Foldout(headerRect, isOpen, "Graph", true);
s_foldouts[key] = isOpen;
clusterView.isOpen = EditorGUI.Foldout(headerRect, clusterView.isOpen, "Graph", true);
if (isOpen) {
if (clusterView.isOpen) {
// content rect below header
Rect drawRect = new(fieldRect.x, headerRect.yMax + 2f, fieldRect.width, 450f);
Cluster_Drawer.clusterView = ClusterView.GetClusterView(property);
Cluster_Drawer.clusterView = clusterView;
ClusterView.Render(drawRect, cluster, property);
//Debug.Log(prefab.cluster.defaultOutput.outputMagnitude);
}
@ -105,6 +137,9 @@ namespace NanoBrain.Unity {
}
private static void OnSceneGUI(SceneView sceneView) {
if (selectedTarget == null)
return;
GameObject gameObject = null;
if (selectedTarget is Component c)
gameObject = c.gameObject;
@ -125,7 +160,12 @@ namespace NanoBrain.Unity {
Handles.DrawLine(gameObject.transform.position, gameObject.transform.position + worldVector);
}
}
}
private static void OnSelectionChanged() {
foreach (ClusterView clusterView in clusterViews.Values) {
clusterView.initialized = false;
}
}
}

View File

@ -176,7 +176,7 @@ namespace NanoBrain {
};
for (int instanceIx = 1; instanceIx < clonedCluster.instanceCount; instanceIx++) {
// Create another sibling
Debug.Log($"create {clonedCluster.prefab.name} sibling");
// Debug.Log($"create {clonedCluster.prefab.name} sibling");
Cluster sibling = new(clonedCluster.prefab, this) {
name = $"{clonedCluster.baseName}: {instanceIx}",
parent = this.parent,
@ -241,7 +241,7 @@ namespace NanoBrain {
}
clonedNeuron.AddReceiver(receiver, weight);
Debug.Log($"external: {receiver.name} receives from {clonedNeuron.name} {clonedNeuron.GetHashCode()}");
// Debug.Log($"external: {receiver.name} receives from {clonedNeuron.name} {clonedNeuron.GetHashCode()}");
}
}