public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
NodeModel node = null;
var obj = JObject.Load(reader);
var type = Type.GetType(obj["$type"].Value<string>());
var guid = Guid.Parse(obj["Uuid"].Value<string>());
var displayName = obj["DisplayName"].Value<string>();
var inPorts = obj["InputPorts"].ToArray().Select(t => t.ToObject<PortModel>()).ToArray();
var outPorts = obj["OutputPorts"].ToArray().Select(t => t.ToObject<PortModel>()).ToArray();
var resolver = (IdReferenceResolver)serializer.ReferenceResolver;
if (type == typeof(Function))
{
var functionId = Guid.Parse(obj["FunctionUuid"].Value<string>());
node = manager.CreateCustomNodeInstance(functionId);
RemapPorts(node, inPorts, outPorts, resolver);
}
else if(type == typeof(CodeBlockNodeModel))
{
var code = obj["Code"].Value<string>();
node = new CodeBlockNodeModel(code, guid, 0.0, 0.0, libraryServices, ElementResolver);
RemapPorts(node, inPorts, outPorts, resolver);
}
else if(typeof(DSFunctionBase).IsAssignableFrom(type))
{
var mangledName = obj["FunctionSignature"].Value<string>();
var description = libraryServices.GetFunctionDescriptor(mangledName);
if(type == typeof(DSVarArgFunction))
{
node = new DSVarArgFunction(description);
// The node syncs with the function definition.
// Then we need to make the inport count correct
var varg = (DSVarArgFunction)node;
varg.VarInputController.SetNumInputs(inPorts.Count());
}
else if(type == typeof(DSFunction))
{
node = new DSFunction(description);
}
RemapPorts(node, inPorts, outPorts, resolver);
}
else if (type == typeof(DSVarArgFunction))
{
var functionId = Guid.Parse(obj["FunctionUuid"].Value<string>());
node = manager.CreateCustomNodeInstance(functionId);
RemapPorts(node, inPorts, outPorts, resolver);
}
else if(type == typeof(Formula))
{
node = (Formula)obj.ToObject(type);
RemapPorts(node, inPorts, outPorts, resolver);
}
else
{
node = (NodeModel)obj.ToObject(type);
}
node.GUID = guid;
node.NickName = displayName;
//node.X = x;
//node.Y = y;
// Add references to the node and the ports to the reference resolver,
// so that they are available for entities which are deserialized later.
serializer.ReferenceResolver.AddReference(serializer.Context, node.GUID.ToString(), node);
foreach(var p in node.InPorts)
{
serializer.ReferenceResolver.AddReference(serializer.Context, p.GUID.ToString(), p);
}
foreach (var p in node.OutPorts)
{
serializer.ReferenceResolver.AddReference(serializer.Context, p.GUID.ToString(), p);
}
return node;
}