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