using UnityEngine;
using System;
using System.Collections.Generic;
namespace UnityConsole
{
///
/// Utility for caching and navigating recently executed console commands.
///
public class ConsoleInputHistory
{
// Input history from most recent to oldest
private List inputHistory;
public int maxCapacity;
// The go-to input entry index. The one to navigate to when first navigating up. It's usually the one most recently navigated-to.
private int currentInput;
private bool isNavigating;
public ConsoleInputHistory(int maxCapacity)
{
inputHistory = new List(maxCapacity);
this.maxCapacity = maxCapacity;
}
///
/// Navigates up or down the input history
///
/// The navigated-to input entry
public string Navigate(bool up)
{
bool down = !up;
// When first navigating up (if there is an input entry), navigate to the go-to input entry (we actually are already there)
// If navigating up again, navigate to the input entry ABOVE (if there is one) the go-to input entry
// If navigating down at any time, navigate to the input entry BELOW (if there is one) the go-to input entry
if (!isNavigating)
isNavigating = (up && inputHistory.Count > 0) || (down && currentInput > 0);
else if (up)
currentInput++;
if (down)
currentInput--;
currentInput = Mathf.Clamp(currentInput, 0, inputHistory.Count - 1);
// Return the navigated-to input entry
if (isNavigating)
return inputHistory[currentInput];
else
return "";
}
///
/// Add a new input entry to the input history.
///
public void AddNewInputEntry(string input)
{
// Give the opportunity to "first" navigate up again, so that we can resume navigating up from the go-to input entry
isNavigating = false;
// Don't add the same input twice in a row
if (inputHistory.Count > 0 && input.Equals(inputHistory[0], StringComparison.OrdinalIgnoreCase))
return;
// If we went over capacity, remove the oldest input entry to make room for a new one
if (inputHistory.Count == maxCapacity)
inputHistory.RemoveAt(maxCapacity - 1);
// Insert the new input entry
inputHistory.Insert(0, input);
// If the go-to input entry was removed for capacity reasons, then the new input entry becomes go-to input entry
if (currentInput == maxCapacity - 1)
currentInput = 0;
// Otherwise make sure the go-to input entry remains the same by shifting the index
// Note that if there was no input entry before, then the go-to input entry index remains 0 which is the new input entry
else
currentInput = Mathf.Clamp(++currentInput, 0, inputHistory.Count - 1);
// If the new input entry is different than the go-to input entry, then it becomes the go-to input entry
if (!input.Equals(inputHistory[currentInput], StringComparison.OrdinalIgnoreCase))
currentInput = 0;
}
public void Clear()
{
inputHistory.Clear();
currentInput = 0;
isNavigating = false;
}
}
}