More work on the RecordingInputSystem.
This commit is contained in:
parent
a54acf8f6f
commit
027e823254
@ -3,6 +3,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
|
||||
#endregion
|
||||
|
||||
@ -58,16 +59,44 @@ namespace ANX.InputSystem.Windows.Recording
|
||||
/// <summary>
|
||||
/// Abstract Class. Classes derived from this class allow recording and Playback of Inputs.
|
||||
/// </summary>
|
||||
abstract class RecordableDevice
|
||||
public abstract class RecordableDevice
|
||||
{
|
||||
protected Stream recordStream; //The stream where the input is written to
|
||||
protected int nullStateCounter; //Used to sum up frames with no input.
|
||||
|
||||
public RecordingState RecordingState { get; protected set; }
|
||||
|
||||
public event EventHandler EndOfPlaybackReached;
|
||||
|
||||
/// <summary>
|
||||
/// How many bytes this Instance requires per Frame. Must never change!
|
||||
/// </summary>
|
||||
public int FramePacketLenght { get; protected set; }
|
||||
|
||||
public RecordableDevice()
|
||||
{
|
||||
RecordingState = RecordingState.None;
|
||||
}
|
||||
|
||||
public void StartRecording()
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the Device using a new
|
||||
/// MemoryStream for input-buffering.
|
||||
/// </summary>
|
||||
public virtual void Initialize()
|
||||
{
|
||||
Initialize(new MemoryStream());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the Device using the specified stream
|
||||
/// for input-buffering.
|
||||
/// </summary>
|
||||
public virtual void Initialize(Stream bufferStream)
|
||||
{
|
||||
recordStream = bufferStream;
|
||||
}
|
||||
|
||||
public virtual void StartRecording()
|
||||
{
|
||||
if (RecordingState == RecordingState.Recording)
|
||||
return;
|
||||
@ -75,7 +104,7 @@ namespace ANX.InputSystem.Windows.Recording
|
||||
RecordingState = RecordingState.Recording;
|
||||
}
|
||||
|
||||
public void StopRecording()
|
||||
public virtual void StopRecording()
|
||||
{
|
||||
if (RecordingState != RecordingState.Recording)
|
||||
throw new InvalidOperationException("Recording wasn't started for this device!");
|
||||
@ -83,7 +112,7 @@ namespace ANX.InputSystem.Windows.Recording
|
||||
RecordingState = RecordingState.None;
|
||||
}
|
||||
|
||||
public void StartPlayback()
|
||||
public virtual void StartPlayback()
|
||||
{
|
||||
if (RecordingState == RecordingState.Recording)
|
||||
throw new InvalidOperationException("Recording is currently running for this device.");
|
||||
@ -91,9 +120,78 @@ namespace ANX.InputSystem.Windows.Recording
|
||||
RecordingState = RecordingState.Playback;
|
||||
}
|
||||
|
||||
public void StopPlayback()
|
||||
public virtual void StopPlayback()
|
||||
{
|
||||
RecordingState = RecordingState.None;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the current input state to the buffering stream. Pass null
|
||||
/// for state, if no input is done (no keys down etc.).
|
||||
/// Must be called once per Frame!
|
||||
/// </summary>
|
||||
protected virtual void WriteState(byte[] state)
|
||||
{
|
||||
if (state == null)
|
||||
{
|
||||
nullStateCounter++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (state.Length != FramePacketLenght)
|
||||
throw new InvalidOperationException("The passed state's lenght does not match the speficed FramePaketLenght.");
|
||||
|
||||
if (nullStateCounter > 0) //Note how many packets we had nothing
|
||||
{
|
||||
recordStream.WriteByte((byte)PacketType.NullFrameCounter);
|
||||
recordStream.Write(BitConverter.GetBytes(nullStateCounter), 0, 4);
|
||||
}
|
||||
|
||||
recordStream.WriteByte((byte)PacketType.InputData);
|
||||
recordStream.Write(state, 0, state.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the next input-state from the buffering stream. Might
|
||||
/// return null, if no input was made in this frame.
|
||||
/// Must be called once per Frame!
|
||||
/// </summary>
|
||||
protected virtual byte[] ReadState()
|
||||
{
|
||||
if (nullStateCounter > 0) //we have null-states pending
|
||||
{
|
||||
nullStateCounter--;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (recordStream.Position == recordStream.Length)
|
||||
{
|
||||
OnEndOfPlaybackReached();
|
||||
return null; //TODO: Better switch to RecordingState.None here?
|
||||
}
|
||||
|
||||
PacketType type = (PacketType)recordStream.ReadByte();
|
||||
switch (type)
|
||||
{
|
||||
case PacketType.NullFrameCounter:
|
||||
byte[] buffer = new byte[4];
|
||||
recordStream.Read(buffer, 0, 4);
|
||||
nullStateCounter = BitConverter.ToInt32(buffer, 0) - 1;
|
||||
return null;
|
||||
case PacketType.InputData:
|
||||
byte[] buffer2 = new byte[FramePacketLenght];
|
||||
recordStream.Read(buffer2, 0, FramePacketLenght);
|
||||
return buffer2;
|
||||
default:
|
||||
throw new NotImplementedException("The PaketType " + Enum.GetName(typeof(PacketType), type) + "is not supported.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected virtual void OnEndOfPlaybackReached()
|
||||
{
|
||||
if (EndOfPlaybackReached != null)
|
||||
EndOfPlaybackReached(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ namespace ANX.InputSystem.Windows.Recording
|
||||
/// <summary>
|
||||
/// Wrapper arround another IGamePad, will record all inputs and allows playback.
|
||||
/// </summary>
|
||||
class RecordingGamePad : RecordableDevice,IGamePad
|
||||
public class RecordingGamePad : RecordableDevice, IGamePad
|
||||
{
|
||||
public GamePadCapabilities GetCapabilities(PlayerIndex playerIndex)
|
||||
{
|
||||
|
@ -55,7 +55,7 @@ using System.Text;
|
||||
|
||||
namespace ANX.InputSystem.Windows.Recording
|
||||
{
|
||||
enum RecordingState
|
||||
public enum RecordingState
|
||||
{
|
||||
/// <summary>
|
||||
/// This device is recording input.
|
||||
@ -70,11 +70,18 @@ namespace ANX.InputSystem.Windows.Recording
|
||||
/// </summary>
|
||||
None
|
||||
}
|
||||
|
||||
enum PacketType : byte
|
||||
{
|
||||
NullFrameCounter = 0,
|
||||
InputData = 1
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Static Helper-class containing some recording related stuff.
|
||||
/// </summary>
|
||||
static class RecordingHelper
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ namespace ANX.InputSystem.Windows.Recording
|
||||
/// <summary>
|
||||
/// Wrapper arround another IKeyboard, will record all inputs and allows playback.
|
||||
/// </summary>
|
||||
class RecordingKeyboard : RecordableDevice, IKeyboard
|
||||
public class RecordingKeyboard : RecordableDevice, IKeyboard
|
||||
{
|
||||
public IntPtr WindowHandle { get; set; }
|
||||
|
||||
|
@ -61,7 +61,7 @@ namespace ANX.InputSystem.Windows.Recording
|
||||
/// <summary>
|
||||
/// Wrapper aroung another IMotionSensingDevice, will record all inputs and allows playback.
|
||||
/// </summary>
|
||||
class RecordingMotionSensingDevice : RecordableDevice,IMotionSensingDevice
|
||||
public class RecordingMotionSensingDevice : RecordableDevice, IMotionSensingDevice
|
||||
{
|
||||
public GraphicsDevice GraphicsDevice
|
||||
{
|
||||
|
@ -5,6 +5,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using ANX.Framework.NonXNA;
|
||||
using ANX.Framework.Input;
|
||||
using System.IO;
|
||||
|
||||
#endregion
|
||||
|
||||
@ -57,10 +58,28 @@ using ANX.Framework.Input;
|
||||
|
||||
namespace ANX.InputSystem.Windows.Recording
|
||||
{
|
||||
[Flags]
|
||||
public enum MouseRecordInfo : byte
|
||||
{
|
||||
LeftButton = 1,
|
||||
RightButton = 2,
|
||||
MiddleButton = 4,
|
||||
X1Button = 8,
|
||||
X2Button = 16,
|
||||
ScrollWheel = 32,
|
||||
XPosition = 64,
|
||||
YPosition = 128,
|
||||
LRMButtons = LeftButton | RightButton | MiddleButton,
|
||||
XButtons = X1Button | X2Button,
|
||||
AllButtons = LRMButtons | XButtons,
|
||||
Position = XPosition | YPosition,
|
||||
All = AllButtons | Position | ScrollWheel
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wrapper arround another IGamePad, will record all inputs and allows playback.
|
||||
/// </summary>
|
||||
class RecordingMouse : RecordableDevice,IMouse
|
||||
public class RecordingMouse : RecordableDevice, IMouse
|
||||
{
|
||||
public IntPtr WindowHandle { get; set; }
|
||||
|
||||
@ -73,5 +92,39 @@ namespace ANX.InputSystem.Windows.Recording
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Initialize(MouseRecordInfo info)
|
||||
{
|
||||
base.Initialize();
|
||||
}
|
||||
|
||||
public void Initialize(MouseRecordInfo info, Stream bufferStream)
|
||||
{
|
||||
base.Initialize(bufferStream);
|
||||
}
|
||||
|
||||
private int GetPaketSize(MouseRecordInfo info)
|
||||
{
|
||||
int ret = 0; //TODO: Pack the bools in one byte to save space sizeof(bool) == sizeof(byte)!
|
||||
if (info.HasFlag(MouseRecordInfo.LeftButton))
|
||||
ret += sizeof(bool);
|
||||
if (info.HasFlag(MouseRecordInfo.RightButton))
|
||||
ret += sizeof(bool);
|
||||
if (info.HasFlag(MouseRecordInfo.MiddleButton))
|
||||
ret += sizeof(bool);
|
||||
if (info.HasFlag(MouseRecordInfo.X1Button))
|
||||
ret += sizeof(bool);
|
||||
if (info.HasFlag(MouseRecordInfo.X2Button))
|
||||
ret += sizeof(bool);
|
||||
|
||||
if (info.HasFlag(MouseRecordInfo.XPosition))
|
||||
ret += sizeof(int);
|
||||
if (info.HasFlag(MouseRecordInfo.YPosition))
|
||||
ret += sizeof(int);
|
||||
if (info.HasFlag(MouseRecordInfo.ScrollWheel))
|
||||
ret += sizeof(int);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user