private void SetCurrentEvent(HistoryEvent historyEvent) { if (historyEvent is BookmarkHistoryEvent bookmarkHistoryEvent) { Core core = Core.Create(Core.LatestVersion, bookmarkHistoryEvent.Bookmark.State.GetBytes()); SetCore(core); Display.GetFromBookmark(bookmarkHistoryEvent.Bookmark); Auditors?.Invoke(CoreAction.LoadCore(historyEvent.Ticks, bookmarkHistoryEvent.Bookmark.State)); } else if (historyEvent is RootHistoryEvent rootHistoryEvent) { Core core = Core.Create(Core.LatestVersion, Core.Type.CPC6128); SetCore(core); Display.GetFromBookmark(null); Auditors?.Invoke(CoreAction.Reset(rootHistoryEvent.Ticks)); } else { throw new Exception("Can't set current event to an event that isn't the root or doesn't have a bookmark."); } _history.CurrentEvent = historyEvent; }
public void ReceiveCoreAction(CoreAction coreAction) { if (_core == null) { Close(); return; } Auditors?.Invoke(coreAction); _core.PushRequest(coreAction); }
/// <summary> /// Delegate for logging core actions. /// </summary> /// <param name="core">The core the request was made for.</param> /// <param name="request">The original request.</param> /// <param name="action">The action taken.</param> private void RequestProcessed(Core core, CoreRequest request, CoreAction action) { Auditors?.Invoke(action); }
/// <summary> /// Delegate for logging core actions. /// </summary> /// <param name="core">The core the request was made for.</param> /// <param name="request">The original request.</param> /// <param name="action">The action taken.</param> private void RequestProcessed(Core core, CoreRequest request, CoreAction action) { if (core == _core) { if (action != null) { Auditors?.Invoke(action); if (action.Type != CoreAction.Types.CreateSnapshot && action.Type != CoreAction.Types.DeleteSnapshot && action.Type != CoreAction.Types.RevertToSnapshot) { HistoryEvent e = _history.AddCoreAction(action); switch (action.Type) { case CoreRequest.Types.LoadDisc: Status = (action.MediaBuffer.GetBytes() != null) ? "Loaded disc" : "Ejected disc"; break; case CoreRequest.Types.LoadTape: Status = (action.MediaBuffer.GetBytes() != null) ? "Loaded tape" : "Ejected tape"; break; case CoreRequest.Types.Reset: Status = "Reset"; break; } } if (action.Type == CoreAction.Types.RunUntil) { lock (_snapshots) { SnapshotInfo newSnapshot = _snapshots.LastOrDefault(); if (newSnapshot != null && action.AudioSamples != null) { newSnapshot.AudioBuffer.Write(action.AudioSamples); } } } else if (action.Type == CoreAction.Types.RevertToSnapshot) { HistoryEvent historyEvent = ((SnapshotInfo)request.UserData).HistoryEvent; if (_history.CurrentEvent != historyEvent) { _history.CurrentEvent = historyEvent; } Display.CopyScreenAsync(); } else if (action.Type == CoreAction.Types.CreateSnapshot) { lock (_snapshots) { // Figure out what history event should be set as current if we revert to this snapshot. // If the current event is a RunUntil, it may not be "finalized" yet (i.e. it may still // be updated), so go with its parent. HistoryEvent historyEvent = _history.MostRecentClosedEvent(_history.CurrentEvent); SnapshotInfo newSnapshot = new SnapshotInfo(action.SnapshotId, historyEvent); _snapshots.Add(newSnapshot); while (_snapshots.Count > _snapshotLimit) { SnapshotInfo snapshot = _snapshots[0]; _snapshots.RemoveAt(0); _core.PushRequest(CoreRequest.DeleteSnapshot(snapshot.Id)); } } } } } }
private bool ProcessNextRequest() { bool success = true; CoreRequest firstRequest = FirstRequest(); bool removeFirst = true; CoreRequest request = firstRequest; CoreAction action = null; if (request == null) { removeFirst = false; if (IdleRequest != null) { request = IdleRequest(); } if (request == null) { _requestQueueNonEmpty.WaitOne(20); return(false); } } UInt64 ticks = Ticks; switch (request.Type) { case CoreRequest.Types.KeyPress: lock (_lockObject) { if (_coreCLR.KeyPress(request.KeyCode, request.KeyDown)) { action = CoreAction.KeyPress(ticks, request.KeyCode, request.KeyDown); } } break; case CoreRequest.Types.Reset: lock (_lockObject) { _coreCLR.Reset(); } action = CoreAction.Reset(ticks); break; case CoreRequest.Types.LoadDisc: lock (_lockObject) { _coreCLR.LoadDisc(request.Drive, request.MediaBuffer.GetBytes()); } action = CoreAction.LoadDisc(ticks, request.Drive, request.MediaBuffer); break; case CoreRequest.Types.LoadTape: lock (_lockObject) { _coreCLR.LoadTape(request.MediaBuffer.GetBytes()); } action = CoreAction.LoadTape(ticks, request.MediaBuffer); break; case CoreRequest.Types.RunUntil: { action = RunForAWhile(request.StopTicks); success = (request.StopTicks <= Ticks); } break; case CoreRequest.Types.CoreVersion: lock (_lockObject) { byte[] state = GetState(); ICore newCore = Core.CreateVersionedCore(request.Version); newCore.LoadState(state); newCore.SetScreen(Display.Pitch, Display.Height, Display.Width); _coreCLR.Dispose(); _coreCLR = newCore; } break; case CoreRequest.Types.LoadCore: lock (_lockObject) { _coreCLR.LoadState(request.CoreState.GetBytes()); } action = CoreAction.LoadCore(ticks, request.CoreState); break; case CoreRequest.Types.CreateSnapshot: lock (_lockObject) { action = CreateSnapshot(request.SnapshotId); } break; case CoreRequest.Types.DeleteSnapshot: lock (_lockObject) { action = DeleteSnapshot(request.SnapshotId); } break; case CoreRequest.Types.RevertToSnapshot: lock (_lockObject) { action = RevertToSnapshot(request.SnapshotId); } break; default: Diagnostics.Trace("Unknown core request type {0}. Ignoring request.", request.Type); break; } if (removeFirst && success) { RemoveFirstRequest(); } Auditors?.Invoke(this, request, action); return(false); }