Deserialization first version
This commit is contained in:
parent
27f4237890
commit
85017861b5
@ -15,12 +15,24 @@ namespace NanoBrain.Unity {
|
|||||||
|
|
||||||
void OnEnable() {
|
void OnEnable() {
|
||||||
clusterPrefab = (ClusterPrefab)target;
|
clusterPrefab = (ClusterPrefab)target;
|
||||||
clusterPrefab.cluster.name = clusterPrefab.name;
|
|
||||||
view = ClusterView.GetClusterView(serializedObject);
|
view = ClusterView.GetClusterView(serializedObject);
|
||||||
|
|
||||||
|
string assetPath = AssetDatabase.GetAssetPath(clusterPrefab);
|
||||||
|
if (!string.IsNullOrEmpty(assetPath)) {
|
||||||
|
string folder = System.IO.Path.GetDirectoryName(assetPath);
|
||||||
|
string jsonPath = System.IO.Path.Combine(folder, clusterPrefab.name + ".json");
|
||||||
|
if (System.IO.File.Exists(jsonPath)) {
|
||||||
|
ClusterData newClusterData = Cluster.Import(jsonPath);
|
||||||
|
clusterPrefab.cluster = new(newClusterData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
view.currentCluster ??= clusterPrefab.cluster;
|
view.currentCluster ??= clusterPrefab.cluster;
|
||||||
view.currentNucleus = clusterPrefab.cluster.defaultOutput;
|
view.currentNucleus = clusterPrefab.cluster.defaultOutput;
|
||||||
view.selectedOutput = view.currentNucleus;
|
view.selectedOutput = view.currentNucleus;
|
||||||
|
|
||||||
|
clusterPrefab.cluster.name = clusterPrefab.name;
|
||||||
|
|
||||||
clusterPrefab.cluster.Cleanup();
|
clusterPrefab.cluster.Cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,25 +230,25 @@ namespace NanoBrain.Unity {
|
|||||||
showSynapses = EditorGUILayout.Foldout(showSynapses, "Synapses", true);
|
showSynapses = EditorGUILayout.Foldout(showSynapses, "Synapses", true);
|
||||||
if (showSynapses) {
|
if (showSynapses) {
|
||||||
EditorGUI.indentLevel--;
|
EditorGUI.indentLevel--;
|
||||||
if (this.view.currentNucleus is Neuron neuron2) {
|
if (this.view.currentNucleus is Neuron neuron) {
|
||||||
Neuron.CombinatorType newCombinator = (Neuron.CombinatorType)EditorGUILayout.EnumPopup("Combinator", neuron2.combinator);
|
Neuron.CombinatorType newCombinator = (Neuron.CombinatorType)EditorGUILayout.EnumPopup("Combinator", neuron.combinator);
|
||||||
anythingChanged |= newCombinator != neuron2.combinator;
|
anythingChanged |= newCombinator != neuron.combinator;
|
||||||
neuron2.combinator = newCombinator;
|
neuron.combinator = newCombinator;
|
||||||
|
|
||||||
EditorGUIUtility.wideMode = true;
|
EditorGUIUtility.wideMode = true;
|
||||||
float previousLabelWidth = EditorGUIUtility.labelWidth;
|
float previousLabelWidth = EditorGUIUtility.labelWidth;
|
||||||
EditorGUIUtility.labelWidth = 100;
|
EditorGUIUtility.labelWidth = 100;
|
||||||
|
|
||||||
Vector3 newBias = EditorGUILayout.Vector3Field("Bias", neuron2.bias);
|
Vector3 newBias = EditorGUILayout.Vector3Field("Bias", neuron.bias);
|
||||||
if (newBias != neuron2.bias) {
|
if (newBias != neuron.bias) {
|
||||||
anythingChanged = true;
|
anythingChanged = true;
|
||||||
neuron2.bias = newBias;
|
neuron.bias = newBias;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool newTrainable = EditorGUILayout.Toggle("Trainable", neuron2.trainable);
|
bool newTrainable = EditorGUILayout.Toggle("Trainable", neuron.trainable);
|
||||||
if (newTrainable != neuron2.trainable) {
|
if (newTrainable != neuron.trainable) {
|
||||||
anythingChanged = true;
|
anythingChanged = true;
|
||||||
neuron2.trainable = newTrainable;
|
neuron.trainable = newTrainable;
|
||||||
}
|
}
|
||||||
|
|
||||||
EditorGUIUtility.labelWidth = previousLabelWidth;
|
EditorGUIUtility.labelWidth = previousLabelWidth;
|
||||||
|
|||||||
@ -41,7 +41,8 @@ namespace NanoBrain.Unity {
|
|||||||
);
|
);
|
||||||
propertyExtraHeight = 2 + 2 * EditorGUIUtility.singleLineHeight;
|
propertyExtraHeight = 2 + 2 * EditorGUIUtility.singleLineHeight;
|
||||||
EditorGUI.HelpBox(helpRect, "Selected asset is not a .json file.", MessageType.Error);
|
EditorGUI.HelpBox(helpRect, "Selected asset is not a .json file.", MessageType.Error);
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
propertyExtraHeight = 0;
|
propertyExtraHeight = 0;
|
||||||
|
|
||||||
EditorGUI.EndProperty();
|
EditorGUI.EndProperty();
|
||||||
@ -56,16 +57,19 @@ namespace NanoBrain.Unity {
|
|||||||
private readonly Dictionary<EntityId, bool> _invalidCache = new();
|
private readonly Dictionary<EntityId, bool> _invalidCache = new();
|
||||||
|
|
||||||
private bool IsInvalidJson(SerializedProperty jsonFileProp) {
|
private bool IsInvalidJson(SerializedProperty jsonFileProp) {
|
||||||
TextAsset current = jsonFileProp.objectReferenceValue as TextAsset;
|
TextAsset jsonFile = jsonFileProp.objectReferenceValue as TextAsset;
|
||||||
if (current == null) return false;
|
if (jsonFile == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
EntityId id = current.GetEntityId();
|
EntityId id = jsonFile.GetEntityId();
|
||||||
if (_invalidCache.TryGetValue(id, out bool invalid))
|
if (_invalidCache.TryGetValue(id, out bool invalid))
|
||||||
return invalid;
|
return invalid;
|
||||||
|
|
||||||
string path = AssetDatabase.GetAssetPath(current);
|
string path = AssetDatabase.GetAssetPath(jsonFile);
|
||||||
invalid = !path.EndsWith(".json", System.StringComparison.OrdinalIgnoreCase);
|
invalid = !path.EndsWith(".json", System.StringComparison.OrdinalIgnoreCase);
|
||||||
_invalidCache[id] = invalid;
|
_invalidCache[id] = invalid;
|
||||||
|
|
||||||
|
|
||||||
return invalid;
|
return invalid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,7 +44,7 @@ namespace NanoBrain.Unity {
|
|||||||
|
|
||||||
EditorGUILayout.Space();
|
EditorGUILayout.Space();
|
||||||
scroll = EditorGUILayout.BeginScrollView(scroll);
|
scroll = EditorGUILayout.BeginScrollView(scroll);
|
||||||
foreach (var it in items) {
|
foreach (ClusterPrefab it in this.items) {
|
||||||
if (!string.IsNullOrEmpty(search) && it.name.IndexOf(search, StringComparison.OrdinalIgnoreCase) < 0)
|
if (!string.IsNullOrEmpty(search) && it.name.IndexOf(search, StringComparison.OrdinalIgnoreCase) < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|||||||
@ -93,7 +93,7 @@ namespace NanoBrain.Unity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If a brain has been selected
|
// If a brain has been selected
|
||||||
//if (prefabProp.objectReferenceValue != null) {
|
if (prefabProp.objectReferenceValue != null) {
|
||||||
// Graph is not shown when multi-editing
|
// Graph is not shown when multi-editing
|
||||||
if (property.serializedObject.targetObjects.Length == 1) {
|
if (property.serializedObject.targetObjects.Length == 1) {
|
||||||
UnityEngine.Object targetObject = property.serializedObject.targetObject;
|
UnityEngine.Object targetObject = property.serializedObject.targetObject;
|
||||||
@ -101,11 +101,11 @@ namespace NanoBrain.Unity {
|
|||||||
|
|
||||||
Cluster cluster = SerializedPropertyUtility.GetManagedObjectForProperty(targetObject, property.propertyPath) as Cluster;
|
Cluster cluster = SerializedPropertyUtility.GetManagedObjectForProperty(targetObject, property.propertyPath) as Cluster;
|
||||||
if (cluster != null) {
|
if (cluster != null) {
|
||||||
// if (cluster.version != cluster.prefab.version) {
|
if (cluster.version != cluster.prefab.version) {
|
||||||
// // Debug.Log($"prefab version: {cluster.prefab.version} cluster version: {cluster.version}");
|
// Debug.Log($"prefab version: {cluster.prefab.version} cluster version: {cluster.version}");
|
||||||
// clusterView.initialized = false;
|
clusterView.initialized = false;
|
||||||
// EditorApplication.delayCall += () => InstantiateCluster(property, clusterView);
|
EditorApplication.delayCall += () => InstantiateCluster(property, clusterView);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// foldout header rect
|
// foldout header rect
|
||||||
Rect headerRect = new(fieldRect.x, fieldRect.yMax + 4f, fieldRect.width, EditorGUIUtility.singleLineHeight);
|
Rect headerRect = new(fieldRect.x, fieldRect.yMax + 4f, fieldRect.width, EditorGUIUtility.singleLineHeight);
|
||||||
@ -127,7 +127,7 @@ namespace NanoBrain.Unity {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//}
|
}
|
||||||
|
|
||||||
EditorGUI.indentLevel = indent;
|
EditorGUI.indentLevel = indent;
|
||||||
EditorGUI.EndProperty();
|
EditorGUI.EndProperty();
|
||||||
|
|||||||
@ -25,6 +25,7 @@ namespace NanoBrain {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// Cluster should always be created from prefabs
|
/// Cluster should always be created from prefabs
|
||||||
public ClusterPrefab prefab;
|
public ClusterPrefab prefab;
|
||||||
|
public ClusterJson json;
|
||||||
|
|
||||||
//[HideInInspector]
|
//[HideInInspector]
|
||||||
|
|
||||||
@ -129,6 +130,46 @@ namespace NanoBrain {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public Cluster(ClusterData clusterData) {
|
||||||
|
this.name = clusterData.name;
|
||||||
|
// First create all neurons
|
||||||
|
foreach (NeuronData neuronData in clusterData.neurons) {
|
||||||
|
if (neuronData.type == Type.MemoryCell)
|
||||||
|
new MemoryCell(this, neuronData.name) {
|
||||||
|
bias = neuronData.bias,
|
||||||
|
combinator = neuronData.combinatorType,
|
||||||
|
activator = neuronData.activationType
|
||||||
|
};
|
||||||
|
else
|
||||||
|
new Neuron(this, neuronData.name) {
|
||||||
|
bias = neuronData.bias,
|
||||||
|
combinator = neuronData.combinatorType,
|
||||||
|
activator = neuronData.activationType
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
// Now create the synapses between them
|
||||||
|
foreach (NeuronData neuronData in clusterData.neurons) {
|
||||||
|
Neuron receiver = this.GetNeuron(neuronData.name);
|
||||||
|
foreach (SynapseData synapseData in neuronData.synapses) {
|
||||||
|
if (synapseData.clusterName != this.name) {
|
||||||
|
// Add reference to external cluster
|
||||||
|
ClusterPrefab extPrefab = Resources.Load(synapseData.clusterName) as ClusterPrefab;
|
||||||
|
if (extPrefab == null)
|
||||||
|
Debug.LogError($"Could not find cluster Resource {synapseData.clusterName}");
|
||||||
|
else {
|
||||||
|
Cluster extCluster = new Cluster(extPrefab, this);
|
||||||
|
Neuron extNeuron = extCluster.GetNeuron(synapseData.neuronName);
|
||||||
|
extNeuron.AddReceiver(receiver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Neuron sender = this.GetNeuron(synapseData.neuronName);
|
||||||
|
sender?.AddReceiver(receiver, synapseData.weight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -804,8 +845,9 @@ namespace NanoBrain {
|
|||||||
System.IO.File.WriteAllText(path, json);
|
System.IO.File.WriteAllText(path, json);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClusterData Import(string path) {
|
public static ClusterData Import(string path) {
|
||||||
string json = File.ReadAllText(path);
|
string json = File.ReadAllText(path);
|
||||||
|
Debug.Log($"Importing json from {path}");
|
||||||
return JsonUtility.FromJson<ClusterData>(json);
|
return JsonUtility.FromJson<ClusterData>(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -824,14 +866,16 @@ namespace NanoBrain {
|
|||||||
if (nucleus is Neuron neuron) {
|
if (nucleus is Neuron neuron) {
|
||||||
NeuronData neuronData = new(neuron);
|
NeuronData neuronData = new(neuron);
|
||||||
this.neurons.Add(neuronData);
|
this.neurons.Add(neuronData);
|
||||||
}
|
foreach (Synapse synapse in neuron.synapses) {
|
||||||
else if (nucleus is Cluster extCluster) {
|
if (synapse.neuron.parent.name != cluster.name) {
|
||||||
ExternalClusterData clusterData = new(extCluster);
|
ExternalClusterData clusterData = new(synapse.neuron.parent);
|
||||||
this.clusters.Add(clusterData);
|
this.clusters.Add(clusterData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class ExternalClusterData {
|
public class ExternalClusterData {
|
||||||
|
|||||||
@ -737,12 +737,17 @@ namespace NanoBrain {
|
|||||||
[Serializable]
|
[Serializable]
|
||||||
public class NeuronData {
|
public class NeuronData {
|
||||||
public string name;
|
public string name;
|
||||||
|
public Nucleus.Type type;
|
||||||
public Vector3 bias = Vector3.zero;
|
public Vector3 bias = Vector3.zero;
|
||||||
public Neuron.CombinatorType combinatorType;
|
public Neuron.CombinatorType combinatorType;
|
||||||
public List<SynapseData> synapses = new();
|
public List<SynapseData> synapses = new();
|
||||||
public Neuron.ActivationType activationType;
|
public Neuron.ActivationType activationType;
|
||||||
|
|
||||||
public NeuronData(Neuron neuron) {
|
public NeuronData(Neuron neuron) {
|
||||||
|
if (neuron is MemoryCell)
|
||||||
|
this.type = Nucleus.Type.MemoryCell;
|
||||||
|
else
|
||||||
|
this.type = Nucleus.Type.Neuron;
|
||||||
this.name = neuron.name;
|
this.name = neuron.name;
|
||||||
this.bias = neuron.bias;
|
this.bias = neuron.bias;
|
||||||
this.combinatorType = neuron.combinator;
|
this.combinatorType = neuron.combinator;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user