public IGameSnapshot TakeSnapshot() { string snapshotJson = SerializationHelpers.Serialize(GetRawSnapshot(), RequiredConverters.GetConverters(), RequiredConverters.GetContextObjects(Maybe <GameEngine> .Empty)); var restored = GameSnapshotRestorer.Restore(snapshotJson, _templateJson, Maybe <GameEngine> .Empty); return(restored.GameSnapshot); }
/// <summary> /// Loads an IGameSnapshot from the given JSON and the given template group. The JSON should /// have been generated by calling SaveSnapshot. /// </summary> /// <exception cref="DeserializationException">An error loading the snapshot /// occurred.</exception> public static IGameSnapshot LoadSnapshot(string snapshotJson, string templateJson) { try { var restorer = GameSnapshotRestorer.Restore(snapshotJson, templateJson, Maybe <GameEngine> .Empty); return(restorer.GameSnapshot); } catch (Exception e) { throw new DeserializationException("snapshot=" + snapshotJson + ", template=" + templateJson, e); } }
public GameEngine(string snapshotJson, string templateJson) { _templateJson = templateJson; // Create our own little island of references with its own set of templates GameSnapshotRestorer restorer = GameSnapshotRestorer.Restore( snapshotJson, templateJson, Maybe.Just(this)); GameSnapshot snapshot = restorer.GameSnapshot; EntityIdGenerator = snapshot.EntityIdGenerator; _systems = snapshot.Systems; _entityIndex = new EntityIndex(); // TODO: ensure that when correctly restore UpdateNumber //UpdateNumber = updateNumber; _globalEntity = (RuntimeEntity)snapshot.GlobalEntity; EventNotifier.Submit(EntityAddedEvent.Create(_globalEntity)); foreach (var entity in snapshot.AddedEntities) { AddEntity((RuntimeEntity)entity); } foreach (var entity in snapshot.ActiveEntities) { RuntimeEntity runtimeEntity = (RuntimeEntity)entity; // add the entity InternalAddEntity(runtimeEntity); // TODO: verify that if the modification notifier is already triggered, we can // ignore this //if (((ContentEntity)entity).HasModification) { // runtimeEntity.ModificationNotifier.Notify(); //} // done via InternalAddEntity //if (deserializedEntity.HasStateChange) { // deserializedEntity.Entity.DataStateChangeNotifier.Notify(); //} } foreach (var entity in snapshot.RemovedEntities) { RuntimeEntity runtimeEntity = (RuntimeEntity)entity; // add the entity InternalAddEntity(runtimeEntity); // TODO: verify that if the modification notifier is already triggered, we can // ignore this //if (((ContentEntity)entity).HasModification) { // runtimeEntity.ModificationNotifier.Notify(); //} // done via InternalAddEntity //if (deserializedEntity.HasStateChange) { // deserializedEntity.Entity.DataStateChangeNotifier.Notify(); //} RemoveEntity(runtimeEntity); } TemplateIndex templateIndex = new TemplateIndex(restorer.Templates.Templates); _executionGroups = new List <ExecutionGroup>(); var executionGroups = SystemExecutionGroup.GetExecutionGroups(snapshot.Systems); foreach (var executionGroup in executionGroups) { List <MultithreadedSystem> multithreadedSystems = new List <MultithreadedSystem>(); foreach (var system in executionGroup.Systems) { MultithreadedSystem multithreaded = CreateMultithreadedSystem(system, templateIndex); multithreadedSystems.Add(multithreaded); } _executionGroups.Add(new ExecutionGroup(multithreadedSystems)); } _nextState = GameEngineNextState.SynchronizeState; SynchronizeState().Wait(); // call of the engine loaded systems foreach (var group in _executionGroups) { foreach (var system in group.Systems) { var onLoaded = system.System as Trigger.OnEngineLoaded; if (onLoaded != null) { onLoaded.OnEngineLoaded(EventNotifier); // TODO: verify that OnEngineLoaded didn't change any state (via hashing) } } } }