public void Write(BinaryBuffer buf) { buf.Write(collectionCounts.Count); foreach (var i in collectionCounts) { buf.Write(i); } buf.Write(fieldSizes.Count); foreach (var i in fieldSizes) { buf.Write(i); } fieldSizes.Clear(); //Guid crumb, so we can jump to the guid table on read var guidCrumbPosition = buf.position; buf.position += 5; //Type table //At this point includes only node types, which we iterate through adding fields type ids var keys = new Type[typeToLocalID.Count]; typeToLocalID.Keys.CopyTo(keys, 0); buf.Write(keys.Length); foreach (var type in keys) { var metaNode = NodeBindings.GetBindings(type); buf.Write(metaNode.fields.Length); foreach (var field in metaNode.fields) { var typeUnits = TypeUnitUtility.GetTypeUnits(field.type); buf.Write(typeUnits.Length); foreach (var subType in typeUnits) { WriteLocalID(buf, subType); } } } //Guids var currentPosition = buf.position; buf.position = guidCrumbPosition; buf.Write(currentPosition); buf.position = currentPosition; buf.Write(typeToLocalID.Count); foreach (var pair in typeToLocalID) { buf.Write(DeltaCore.GetGUID(pair.Key)); } typeToLocalID.Clear(); }
public void Read(BinaryBuffer buf, PrefabFooter footer) { var typeLocalID = buf.ReadInt(); var typeGUID = footer.LocalToGuid(typeLocalID); var type = DeltaCore.Get <Type>(typeGUID); bindings = NodeBindings.GetBindings(type); var numFields = footer.collectionCounts.Pop(); if (numFields > 0) { fields = new FieldOverride[bindings.fields.Length]; } for (var iField = 0; iField < numFields; iField++) { var overrideIndex = buf.ReadInt(); var fieldSize = footer.fieldSizes.Dequeue(); //Index if the type matches if (footer.DoesFieldTypeMatch(typeLocalID, iField)) { fields[overrideIndex] = new FieldOverride { buf = buf, position = buf.position, length = fieldSize }; } buf.position += fieldSize; } var numChildren = footer.collectionCounts.Pop(); if (numChildren > 0) { children = new PrefabNode[numChildren]; } for (var iChild = 0; iChild < numChildren; iChild++) { var child = new PrefabNode(); children[iChild] = child; child.Read(buf, footer); } }
protected void ReadToVal(int parameterIndex = 0) { var attributeType = DeltaCore.GetAttributeType(typeArgs[parameterIndex]); if (attributeType == typeof(ResourceTypeAttribute)) { sb += $"var guid = buf.ReadGuid();"; sb += $"var p{parameterIndex} = {typeof(DeltaCore).Name}.Get<{typeArgs[parameterIndex]}>(guid);"; } else if (attributeType == typeof(SimpleTypeAttribute)) { sb += $"var p{parameterIndex} = buf.Read{capitalizedTypeArgs[parameterIndex]}();"; } else { sb += $"var p{parameterIndex} = ({capitalizedTypeArgs[parameterIndex]})buf.ReadNode(node);"; } }
public string Generate(string source) { var sb = new SourceBuilder(); foreach (var name in DeltaCore.GetNamespaces()) { sb += $"using {name};"; } var startLength = sb.Length; var root = CSharpSyntaxTree.ParseText(source).GetCompilationUnitRoot(); var classDeclarations = root.DescendantNodes().OfType <ClassDeclarationSyntax>(); foreach (var classDeclaration in classDeclarations) { GenerateClass(classDeclaration, sb); } return(startLength == sb.Length ? null : sb.ToString()); }
public NodeBindings(Type type) { this.type = type; var syncFields = new List <FieldBindings>(); var fieldInfos = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); foreach (var fieldInfo in fieldInfos) { var fieldType = fieldInfo.FieldType; if (!fieldType.IsGenericType) { continue; } var genericType = fieldInfo.FieldType.GetGenericTypeDefinition(); if (DeltaCore.GetAttributeType(genericType.Name) == typeof(SyncTypeAttribute)) { var fieldID = syncFields.Count; var metaField = new FieldBindings(type, fieldInfo, fieldID); syncFields.Add(metaField); } fields = ImmutableArray.CreateRange(syncFields); } construct = (Func <NodeBindings, Node>)Delegate.CreateDelegate(typeof(Func <NodeBindings, Node>), type, "Construct", false, false); if (construct == null) { throw new ArgumentException($"Failed to bind {nameof(Construct)} delegate for {type}"); } Destruct = (Action <Node>)Delegate.CreateDelegate(typeof(Action <Node>), type, "Destruct", false, false); if (Destruct == null) { throw new ArgumentException($"Failed to bind {nameof(Destruct)} delegate for {type}"); } }
//Parse type metadata in the footer so we can avoid indexing fields that no longer exist public void Read(BinaryBuffer buf) { collectionCounts.Clear(); var collectionCountCount = buf.ReadInt(); for (int i = 0; i < collectionCountCount; i++) { collectionCounts.Push(buf.ReadInt()); } fieldSizes.Clear(); var fieldSizesCount = buf.ReadInt(); for (int i = 0; i < fieldSizesCount; i++) { fieldSizes.Enqueue(buf.ReadInt()); } //Guids var typeTablePosition = buf.position + 5; buf.position = buf.ReadInt(); //Jump to guid table localIDToGuid.Clear(); var numGuids = buf.ReadInt(); for (int iGuid = 0; iGuid < numGuids; iGuid++) { localIDToGuid.Add(buf.ReadGuid()); } var currentPosition = buf.position; //Jump back to type table buf.position = typeTablePosition; fieldTypeMatchTable.Clear(); var numNodeTypes = buf.ReadInt(); for (int localID = 0; localID < numNodeTypes; localID++) { var type = DeltaCore.Get <Type>(localIDToGuid[localID]); var metaNode = NodeBindings.GetBindings(type); var oldFieldCount = buf.ReadInt(); var currentFieldCount = metaNode.fields.Length; var fieldTypeMatches = new bool[Math.Max(oldFieldCount, currentFieldCount)]; fieldTypeMatchTable.Add(fieldTypeMatches); for (int iField = 0; iField < fieldTypeMatches.Length; iField++) { if (iField >= oldFieldCount) { continue; } var oldSubTypeLength = buf.ReadInt(); var currentTypeUnits = TypeUnitUtility.GetTypeUnits(metaNode.fields[iField].type); var matches = true; if (oldSubTypeLength != currentTypeUnits.Length) { matches = false; } for (int iTypeUnit = 0; iTypeUnit < oldSubTypeLength; iTypeUnit++) { var currentGUID = DeltaCore.GetGUID(currentTypeUnits[iTypeUnit]); var previousGUID = localIDToGuid[buf.ReadInt()]; if (currentGUID != previousGUID) { matches = false; } } fieldTypeMatches[iField] = matches; } } buf.position = currentPosition; }
public static T Create <T>(string name) where T : Node { var guid = DeltaCore.ResolveString(name); return(Create(DeltaCore.Get <Prefab>(guid)) as T); }