public void Load(Stream stream) { objects.Clear(); Dictionary <int, int> localToGlobal = new Dictionary <int, int>(); StateFormatter bf = new StateFormatter(); int rootId = (int)bf.Deserialize(stream); while (stream.Position < stream.Length - 1) { StateObject obj = (StateObject)bf.Deserialize(stream); StateContainer.SetManager(obj, this); obj.AfterDeserialization(); if (obj.ID == -1) { localToGlobal.Add(obj.localID, objects.Add(obj)); } else { objects.Add(obj); } } root = objects[rootId] as WorldState; objects.Resolve(localToGlobal); UpdateDebugInfo(); }
public StateObject Clone() { // simple clone value type members StateObject obj = this.MemberwiseClone() as StateObject; Type type = obj.GetType(); // state link lists need to be cloned manually FieldInfo[] infos = type.GetFields(BindingFlags.Default | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public); foreach (FieldInfo info in infos) { if (typeof(IStateLinkList).IsAssignableFrom(info.FieldType) && typeof(ICloneable).IsAssignableFrom(info.FieldType)) { ICloneable list = (ICloneable)info.GetValue(obj); // clone if non-null if (list != null) { info.SetValue(obj, list.Clone()); } } } StateContainer.SetManager(obj, container); // run custom after deserialization/clone initializing obj.AfterDeserialization(); return(obj); }
public void Synchronize(bool resetChangeRecord) { if (resetChangeRecord) { if (added.Count != 0) { throw new BurntimeLogicException(); // DEBUG } // swap change record changeRecord.Dequeue(); // garbage collection changeRecord.Add(objects.CollectGarbage(root, externalReferences)); // save back up syncCopy = objects.Clone(); } objects.Add(added, externalReferences); added.Clear(); if (!resetChangeRecord) { changeRecord.Add(objects.Compare(syncCopy)); } UpdateDebugInfo(); }
public StateManager(ResourceManager resourceManager, bool manageGlobalAddressing, string debugName) { this.resourceManager = resourceManager; this.debugName = debugName; this.manageGlobalAddressing = manageGlobalAddressing; objects = new StateContainer(false, this); syncCopy = new StateContainer(false, this); added = new StateContainer(true, this); UpdateDebugInfo(); }
public StateManager(ResourceManager resourceManager) { this.resourceManager = resourceManager; this.debugName = "main"; this.manageGlobalAddressing = true; objects = new StateContainer(false, this); syncCopy = new StateContainer(false, this); added = new StateContainer(true, this); UpdateDebugInfo(); }
public StateContainer Clone() { StateContainer container = new StateContainer(localAddressing, stateManager); container.nextKey = nextKey; foreach (StateObject obj in objects.Values) { container.objects.Add(localAddressing ? obj.localID : obj.ID, obj.Clone()); } return(container); }
public SyncObject[] Compare(StateContainer right) { List <SyncObject> changed = new List <SyncObject>(); foreach (int key in right.objects.Keys) { if (!objects.ContainsKey(key)) { changed.Add(new SyncObject(key, SyncCode.Delete)); Burntime.Platform.Log.Debug("compare delete: " + key); } else { if (!objects[key].CompareTo(right.objects[key])) { if (objects[key].ID != -1) { changed.Add(new SyncObject(objects[key].ID, SyncCode.Update)); } else { throw new Exception("invalid ID"); } } } } foreach (int key in objects.Keys) { if (!right.objects.ContainsKey(key)) { changed.Add(new SyncObject(key, SyncCode.New)); Burntime.Platform.Log.Debug("compare new: " + key); } } return(changed.ToArray()); }
public void Add(StateContainer container, List <IStateReference> externalReferences) { if (localAddressing || !container.localAddressing) { throw new InvalidCastException(); } Dictionary <int, int> localToGlobal = new Dictionary <int, int>(); foreach (StateObject obj in container.objects.Values) { localToGlobal.Add(obj.localID, Add(obj)); } Resolve(localToGlobal); for (int i = 0; i < externalReferences.Count; i++) { if (externalReferences[i].ID == -1) { externalReferences[i].ID = localToGlobal[externalReferences[i].localID]; } } }
void SetContainerLinks(StateObject obj) { StateContainer.SetManager(obj, this); }
public void MonitorChanges() { syncCopy = objects.Clone(); }