private Compound FromStream() { var compoundID = _r.ReadUInt32(); // write compoundType var compoundType = CompoundSpec <TEngine> .GetTypeByID(_r.ReadUInt32()); var spec = CompoundSpec <TEngine> .GetSpec(compoundType); if (_r.ReadUInt16() != spec.Length) { throw new Exception(); } _s.Seek(spec.Length * sizeof(long), SeekOrigin.Current); var compoundElements = new CompoundItem[spec.Length][]; for (int specIndex = 0; specIndex < spec.Length; specIndex++) { var elementSpec = ElementSpec <TEngine> .GetSpec(spec.Types[specIndex]); var sizeOfElement = ElementSpec <TEngine> .SizeOfElement; var stateSizeInBytes = elementSpec.StateSizeInBytes; if (_r.ReadUInt32() != elementSpec.TotalSizeInBytes) { throw new Exception(); } var elementLength = _r.ReadUInt32(); var elements = new CompoundItem[elementLength]; for (int elementIndex = 0; elementIndex < elementLength; elementIndex++) { elements[elementIndex].ID = _r.ReadUInt32(); _s.Seek(sizeOfElement, SeekOrigin.Current); var remainingPitch = (long)stateSizeInBytes; var dataSizeInBytes = elementSpec.DataSizeInBytes; if (dataSizeInBytes > 0) { elements[elementIndex].Data = _r.ReadBytes(dataSizeInBytes); remainingPitch -= dataSizeInBytes; } if (remainingPitch < 0) { throw new OverflowException("Data larger then StateSize"); } if (remainingPitch > 0) { _s.Seek(remainingPitch, SeekOrigin.Current); } } compoundElements[specIndex] = elements; } return(new Compound { ID = compoundID, Elements = compoundElements, Type = compoundType, }); }
private void ToStream(Compound compound, Dictionary <uint, CompoundInfo> localCompounds, Dictionary <ElementSpec <TEngine>, List <ulong> > localEverys) { _w.Write(compound.ID); // write compoundType var spec = CompoundSpec <TEngine> .GetSpec(compound.Type); _w.Write(spec.TypeID); _w.Write(spec.Length); // #arrayLength var compoundAddress = (ulong)_s.Position; localCompounds.Add(compound.ID, new CompoundInfo { Address = compoundAddress, Compound = compound }); var specSIndexs = new long[spec.Length]; var specArraySIndex = _s.Position; _s.Seek(spec.Length * sizeof(ulong), SeekOrigin.Current); for (int specIndex = 0; specIndex < spec.Length; specIndex++) { var elementSpec = ElementSpec <TEngine> .GetSpec(spec.Types[specIndex]); var sizeOfElement = ElementSpec <TEngine> .SizeOfElement; var stateSizeInBytes = elementSpec.StateSizeInBytes; GetElementTypeHead(elementSpec.TypeID); // var elements = compound.Elements[specIndex]; _w.Write(elementSpec.TotalSizeInBytes); // #arrayPitch _w.Write((uint)elements.Length); // #arrayLength specSIndexs[specIndex] = _s.Position; foreach (var element in elements) { _w.Write(element.ID); var elementAddress = (ulong)_s.Position; // check for schedule-everys if (elementSpec.ScheduleStyleEvery) { List <ulong> everyAddresses; if (!localEverys.TryGetValue(elementSpec, out everyAddresses)) { localEverys.Add(elementSpec, everyAddresses = new List <ulong>()); } everyAddresses.Add(elementAddress); } _s.Seek(sizeOfElement, SeekOrigin.Current); var remainingPitch = (long)stateSizeInBytes; var dataSizeInBytes = elementSpec.DataSizeInBytes; if (dataSizeInBytes > 0) { var data = element.Data; if (data != null) { _w.Write(data); remainingPitch -= data.Length; } } if (remainingPitch < 0) { throw new OverflowException("Data larger then StateSize"); } if (remainingPitch > 0) { _s.Seek(remainingPitch, SeekOrigin.Current); } } } // replace specSIndex var lastSIndex = _s.Position; _s.Seek(specArraySIndex, SeekOrigin.Begin); foreach (var specSIndex in specSIndexs) { _adjustSIndexs.Add(_s.Position); _w.Write((ulong)specSIndex); } _s.Position = lastSIndex; }