public void Pause() { lock (pausingSync) { switch (state) { case State.Paused: return; case State.NotStarted: goto case State.Paused; } LocalTimeSource.Pause(); foreach (var ownLife in ownLifes.OrderBy(x => x is ICPU ? 0 : 1)) { var ownLifeName = GetNameForOwnLife(ownLife); this.NoisyLog("Pausing {0}.", ownLifeName); ownLife.Pause(); this.NoisyLog("{0} paused.", ownLifeName); } state = State.Paused; var machinePaused = StateChanged; if (machinePaused != null) { machinePaused(this, new MachineStateChangedEventArgs(MachineStateChangedEventArgs.State.Paused)); } this.Log(LogLevel.Info, "Machine paused."); } }
public void Start() { lock (pausingSync) { switch (state) { case State.Started: return; case State.Paused: Resume(); return; } machineStartedAt = CustomDateTime.Now; foreach (var ownLife in ownLifes.OrderBy(x => x is ICPU ? 1 : 0)) { this.NoisyLog("Starting {0}.", GetNameForOwnLife(ownLife)); ownLife.Start(); } LocalTimeSource.Resume(); this.Log(LogLevel.Info, "Machine started."); state = State.Started; var machineStarted = StateChanged; if (machineStarted != null) { machineStarted(this, new MachineStateChangedEventArgs(MachineStateChangedEventArgs.State.Started)); } } }
private void ReportForeignEventInner(Action <TimeInterval, bool> recordMethod, Action handlerMethod, bool timeDomainInternalEvent) { LocalTimeSource.ExecuteInNearestSyncedState(ts => { recordMethod?.Invoke(ts.TimeElapsed, timeDomainInternalEvent); handlerMethod(); }, true); }
public void HandleTimeDomainEvent <T1, T2>(Action <T1, T2> handler, T1 handlerArgument1, T2 handlerArgument2, TimeStamp eventTime, Action postAction = null) { LocalTimeSource.ExecuteInSyncedState(ts => { HandleTimeDomainEvent(handler, handlerArgument1, handlerArgument2, ts.Domain == LocalTimeSource.Domain); postAction?.Invoke(); }, eventTime); }
private void Resume() { lock (pausingSync) { LocalTimeSource.Resume(); foreach (var ownLife in ownLifes.OrderBy(x => x is ICPU ? 1 : 0)) { this.NoisyLog("Resuming {0}.", GetNameForOwnLife(ownLife)); ownLife.Resume(); } this.Log(LogLevel.Info, "Machine resumed."); state = State.Started; var machineStarted = StateChanged; if (machineStarted != null) { machineStarted(this, new MachineStateChangedEventArgs(MachineStateChangedEventArgs.State.Started)); } } }
public void Dispose() { lock (disposedSync) { if (alreadyDisposed) { return; } alreadyDisposed = true; } Pause(); if (recorder != null) { recorder.Dispose(); } if (player != null) { player.Dispose(); LocalTimeSource.SyncHook -= player.Play; } // ordering below is due to the fact that the CPU can use other peripherals, e.g. Memory so it should be disposed last foreach (var peripheral in GetPeripheralsOfType <IDisposable>().OrderBy(x => x is ICPU ? 0 : 1)) { this.DebugLog("Disposing {0}.", GetAnyNameOrTypeName((IPeripheral)peripheral)); peripheral.Dispose(); } LocalTimeSource.Dispose(); this.Log(LogLevel.Info, "Disposed."); var disposed = StateChanged; if (disposed != null) { disposed(this, new MachineStateChangedEventArgs(MachineStateChangedEventArgs.State.Disposed)); } EmulationManager.Instance.CurrentEmulation.BackendManager.HideAnalyzersFor(this); }
private void Register(IPeripheral peripheral, IRegistrationPoint registrationPoint, IPeripheral parent) { using (ObtainPausedState()) { Action executeAfterLock = null; lock (collectionSync) { var parentNode = registeredPeripherals.GetNode(parent); parentNode.AddChild(peripheral, registrationPoint); var ownLife = peripheral as IHasOwnLife; if (ownLife != null) { ownLifes.Add(ownLife); if (state == State.Paused) { executeAfterLock = delegate { ownLife.Start(); ownLife.Pause(); }; } } } if (executeAfterLock != null) { executeAfterLock(); } if (peripheral is ITimeSink timeSink) { LocalTimeSource.RegisterSink(timeSink); } } OnMachinePeripheralsChanged(peripheral, PeripheralsChangedEventArgs.PeripheralChangeType.Addition); EmulationManager.Instance.CurrentEmulation.BackendManager.TryCreateBackend(peripheral); }