public GameStateMap Pop(PlaybackSpot playbackSpot) { var spotFound = false; var node = rollbackList.First; while (node != null) { if (node.Value.PlaybackSpot == playbackSpot) { spotFound = true; break; } node = node.Next; } if (!spotFound) { return(null); } while (rollbackList.First != node) { Pop(); } return(Pop()); }
/// <summary> /// Initializes the backlog message. /// </summary> /// <param name="message">Text of the message.</param> /// <param name="author">Actor ID of the message author.</param> /// <param name="voiceClipNames">Voice replay clip names associated with the message. Provide null to disable voice replay.</param> /// <param name="rollbackSpot">Rollback spot associated with the message. Provide <see cref="PlaybackSpot.Invalid"/> to disable rollback.</param> public virtual void Initialize(string message, string author, IReadOnlyCollection <string> voiceClipNames, PlaybackSpot rollbackSpot) { SetMessage(message); SetAuthor(author); this.voiceClipNames.Clear(); if (voiceClipNames?.Count > 0) { this.voiceClipNames.AddRange(voiceClipNames); if (PlayVoiceButton) { PlayVoiceButton.gameObject.SetActive(true); } } else { if (PlayVoiceButton) { PlayVoiceButton.gameObject.SetActive(false); } } this.rollbackSpot = rollbackSpot; var canRollback = rollbackSpot.Valid && stateManager.CanRollbackTo(s => s.PlaybackSpot == rollbackSpot); if (RollbackButton) { RollbackButton.gameObject.SetActive(canRollback); } }
public BacklogMessageState(string messageText, string actorNameText, IEnumerable <string> voiceClipNames, PlaybackSpot rollbackSpot) { this.messageText = messageText; this.actorNameText = actorNameText; this.voiceClipNames = voiceClipNames?.ToArray(); this.rollbackSpot = rollbackSpot; }
public int IndexOf(PlaybackSpot playbackSpot) { for (int i = 0; i < Count; i++) { if (this[i].PlaybackSpot == playbackSpot) { return(i); } } return(-1); }
/// <summary> /// Attempts to rollback (revert) all the engine services to a state they had at the provided playback spot. /// Has no effect when the rollback feature is disabled. /// </summary> /// <param name="playbackSpot">The playback spot to revert to.</param> /// <returns>Whether the provided playback spot was found in the rollback stack and the operation succeeded.</returns> public async Task <bool> RollbackAsync(PlaybackSpot playbackSpot) { var state = rollbackStateStack.Pop(playbackSpot); if (state is null) { return(false); } await RollbackToStateAsync(state); return(true); }
/// <summary> /// Initializes the backlog message. /// </summary> /// <param name="message">Text of the message.</param> /// <param name="authorName">Name of the message author.</param> /// <param name="voiceClipNames">Voice replay clip names associated with the message. Provide null to disable voice replay.</param> /// <param name="rollbackSpot">Rollback spot associated with the message. Provide <see cref="PlaybackSpot.Invalid"/> to disable rollback.</param> public virtual void Initialize(string message, string authorName, List <string> voiceClipNames, PlaybackSpot rollbackSpot) { MessageText.text = message; if (string.IsNullOrWhiteSpace(authorName)) { ActorNameText.text = null; ActorNameText.transform.parent.gameObject.SetActive(false); } else { ActorNameText.text = authorName; ActorNameText.transform.parent.gameObject.SetActive(true); } this.voiceClipNames.Clear(); if (voiceClipNames?.Count > 0) { this.voiceClipNames.AddRange(voiceClipNames); if (PlayVoiceButton) { PlayVoiceButton.gameObject.SetActive(true); } } else { if (PlayVoiceButton) { PlayVoiceButton.gameObject.SetActive(false); } } this.rollbackSpot = rollbackSpot; var canRollback = rollbackSpot.Valid && stateManager.CanRollbackTo(s => s.PlaybackSpot == rollbackSpot); if (RollbackButton) { RollbackButton.gameObject.SetActive(canRollback); } }
public static string GetAutoVoiceClipPath(PlaybackSpot playbackSpot) { return(string.Format(AutoVoiceClipNameTemplate, playbackSpot.ScriptName, playbackSpot.LineNumber, playbackSpot.InlineIndex)); }
public DynamicValue(PlaybackSpot playbackSpot, string valueText, IEnumerable <string> expressions) { PlaybackSpot = playbackSpot; ValueText = valueText; Expressions = expressions.ToArray(); }
/// <summary> /// Depending on whether the provided <paramref name="lineIndex"/> being before or after currently played command' line index, /// performs a fast-forward playback or state rollback of the currently loaded script. /// </summary> /// <param name="lineIndex">The line index to rewind at.</param> /// <param name="inlineIndex">The inline index to rewind at.</param> /// <param name="resumePlayback">Whether to resume script playback after the rewind.</param> /// <returns>Whether the <paramref name="lineIndex"/> has been reached.</returns> public async Task <bool> RewindAsync(int lineIndex, int inlineIndex = 0, bool resumePlayback = true) { if (IsPlaying) { Stop(); } if (PlayedCommand is null) { Debug.LogError("Script player failed to rewind: played command is not valid."); if (resumePlayback) { Play(); } return(false); } var targetCommand = Playlist.GetFirstCommandAfterLine(lineIndex, inlineIndex); if (targetCommand is null) { Debug.LogError($"Script player failed to rewind: target line index ({lineIndex}) is not valid for `{PlayedScript.Name}` script."); if (resumePlayback) { Play(); } return(false); } var targetPlaylistIndex = Playlist.IndexOf(targetCommand); if (targetPlaylistIndex == PlayedIndex) { if (resumePlayback) { Play(); } return(true); } DisableAutoPlay(); DisableSkip(); DisableWaitingForInput(); playRoutineCTS = new CancellationTokenSource(); var cancellationToken = playRoutineCTS.Token; bool result; if (targetPlaylistIndex > PlayedIndex) { result = await FastForwardRoutineAsync(cancellationToken, targetPlaylistIndex); } else { var targetSpot = new PlaybackSpot(PlayedScript.Name, lineIndex, inlineIndex); result = await stateManager.RollbackAsync(targetSpot); } if (resumePlayback) { Play(); } else { Stop(); } return(result); }