Example #1
0
        public Symbol ReadSymbol(Model model, JToken o, bool allowNonOperatorInstanceType = false)
        {
            var id = Guid.Parse(o["Id"].Value <string>());

            if (SymbolRegistry.Entries.ContainsKey(id))
            {
                return(null); // symbol already in registry - nothing to do
            }
            var name           = o["Name"].Value <string>();
            var @namespace     = o["Namespace"]?.Value <string>() ?? "";
            var symbolChildren = new List <SymbolChild>();

            var missingSymbolChildIds = new HashSet <Guid>();
            var missingSymbolsIds     = new HashSet <Guid>();

            foreach (var childJson in ((JArray)o["Children"]))
            {
                SymbolChild symbolChild = ReadSymbolChild(model, childJson);
                if (symbolChild == null)
                {
                    var childId  = Guid.Parse((childJson["Id"] ?? "").Value <string>() ?? string.Empty);
                    var symbolId = Guid.Parse((childJson["SymbolId"] ?? "").Value <string>() ?? string.Empty);
                    Log.Warning($"Skipping child of undefined type {symbolId} in {name}");

                    if (childId != Guid.Empty)
                    {
                        missingSymbolChildIds.Add(childId);
                    }

                    if (symbolId != Guid.Empty)
                    {
                        missingSymbolsIds.Add(symbolId);
                    }
                }
                else
                {
                    symbolChildren.Add(symbolChild);
                }
            }

            var connections = new List <Symbol.Connection>();

            foreach (var c in ((JArray)o["Connections"]))
            {
                Symbol.Connection connection = ReadConnection(c);
                if (connection == null)
                {
                    Log.Warning($"Skipping invalid connection in {name}");
                }
                else if (missingSymbolChildIds.Contains(connection.TargetParentOrChildId) ||
                         missingSymbolChildIds.Contains(connection.SourceParentOrChildId)
                         )
                {
                    Log.Warning("Skipping connection to child of undefined type");
                }
                else
                {
                    connections.Add(connection);
                }
            }

            var orderedInputIds = (from jsonInput in (JArray)o["Inputs"]
                                   let idAndValue = ReadSymbolInputDefaults(jsonInput)
                                                    select idAndValue.Item1).ToArray();

            var inputDefaultValues = (from jsonInput in (JArray)o["Inputs"]
                                      let idAndValue = ReadSymbolInputDefaults(jsonInput)
                                                       select idAndValue).ToDictionary(entry => entry.Item1, entry => entry.Item2);
            var animatorData = (JArray)o["Animator"];

            string namespaceId      = id.ToString().ToLower().Replace('-', '_');
            string instanceTypeName = "T3.Operators.Types.Id_" + namespaceId + "." + name +
                                      ", Operators, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null";
            Type instanceType = Type.GetType(instanceTypeName);

            if (instanceType == null)
            {
                if (allowNonOperatorInstanceType)
                {
                    instanceType = typeof(object);
                }
                else
                {
                    throw new Exception($"The type for '{instanceTypeName}' could not be found in Operator assembly.");
                }
            }

            var symbol = new Symbol(instanceType, id, orderedInputIds, symbolChildren)
            {
                Name      = name,
                Namespace = @namespace,
            };

            symbol.Connections.AddRange(connections);

            if (animatorData != null)
            {
                symbol.Animator.Read(animatorData);
            }

            foreach (var input in symbol.InputDefinitions)
            {
                // if no entry is present just the value default is used, happens for new inputs
                if (inputDefaultValues.TryGetValue(input.Id, out var jsonDefaultValue))
                {
                    input.DefaultValue.SetValueFromJson(jsonDefaultValue);
                }
            }

            var jAudioClipArray = (JArray)o[nameof(symbol.AudioClips)];

            if (jAudioClipArray != null)
            {
                foreach (var c in jAudioClipArray)
                {
                    AudioClip clip = AudioClip.FromJson(c);
                    symbol.AudioClips.Add(clip);
                }
            }

            return(symbol);
        }