static Script BuildScriptTree(List <IScriptCommand> commands) { Stack <List <IScriptCommand> > context = new Stack <List <IScriptCommand> >(); foreach (IScriptCommand command in commands) { if (context.Count() == 0) { context.Push(new List <IScriptCommand>()); } ; if (command.Type.Equals("basic") && command.GetType() != typeof(LoopStartCommand) && command.GetType() != typeof(LoopEndCommand)) { context.Peek().Add(command); } if (command.GetType() == typeof(LoopStartCommand)) { List <IScriptCommand> newContext = new List <IScriptCommand>(); newContext.Add(command); context.Push(newContext); } if (command.GetType() == typeof(LoopEndCommand)) { List <IScriptCommand> currentContext = context.Pop(); LoopStartCommand loopStart = (LoopStartCommand)currentContext[0]; currentContext.RemoveAt(0); LoopCommand loop = new LoopCommand(loopStart, currentContext, (LoopEndCommand)command); context.Peek().Add(loop); } } return(new Script(context.Pop())); }
private void startDisplayLoop(LoopCommand loopCommand) { foreach (var builders in displayValueBuilders) { builders.Value.StartDisplayLoop(loopCommand); } }
public LoopCommand StartLoopGroup(double startTime, int loopCount) { var loopCommand = new LoopCommand(startTime, loopCount); addCommand(loopCommand); startDisplayLoop(loopCommand); return(loopCommand); }
public IEnumerable <Command> Parse(IEnumerable <string> data_arr) { LoopCommand command = new LoopCommand(); command.StartTime = data_arr.ElementAt(1).ToInt(); command.LoopCount = data_arr.ElementAt(2).ToInt(); yield return(command); }
public void LoopCommandObjectCreatedIsSameAsAConstructedObject(LoopType loopType) { ILoopCommand commandFromFactory = (LoopCommand)commandFactory.NewLoopCommand(loopType); ILoopCommand commandConstructedDirectly = new LoopCommand(loopType); Assert.IsNotNull(commandFromFactory); Assert.AreEqual(typeof(LoopCommand), commandFromFactory.GetType()); Assert.AreEqual(commandConstructedDirectly.CommandType, commandFromFactory.CommandType); Assert.AreEqual(commandConstructedDirectly.LoopType, commandFromFactory.LoopType); }
public void VisitLoop(LoopCommand Loop) { Loop.Start.Accept(this); for (int i = 0; i < Loop.Start.Loops.Value; i++) { foreach (IScriptCommand command in Loop.Commands) { command.Accept(this); } } Loop.End.Accept(this); }
public LoopSubTimelineCommand(LoopCommand loop_command, Event bind_event) { this.loop_command = loop_command; Event = bind_event; timeline = loop_command.SubCommands[bind_event]; var offset = loop_command.SubCommands.SelectMany(l => l.Value).Min(x => x.StartTime); CostTime = loop_command.CostTime - offset; StartTime = loop_command.StartTime + offset; EndTime = StartTime + CostTime * loop_command.LoopCount; RelativeLine = loop_command.RelativeLine; }
public void StartDisplayLoop(LoopCommand loopCommand) { if (composite != null) { throw new InvalidOperationException("Cannot start loop: already inside a loop or trigger"); } decorate = (command) => { if (loopCommand.CommandsStartTime != 0) { throw new InvalidOperationException($"Commands in a loop must start at 0ms, but start at {loopCommand.CommandsStartTime}ms"); } return(new LoopDecorator <TValue>(command, loopCommand.StartTime, loopCommand.CommandsDuration, loopCommand.LoopCount)); }; composite = new CompositeCommand <TValue>(); }
private void AddLoopCommand(LoopCommand loop_command) { if (Setting.EnableLoopCommandUnrolling) { //将Loop命令各个类型的子命令时间轴封装成一个命令,并添加到物件本体各个时间轴上 foreach (var cmd in loop_command.SubCommandExpand()) { AddCommand(cmd); } } else { //将Loop命令里面的子命令展开 foreach (var @event in loop_command.SubCommands.Keys) { var sub_command_wrapper = new LoopSubTimelineCommand(loop_command, @event); AddCommand(sub_command_wrapper); } } }
public void Update(LoopCommand command, int?slotIndex = null) { // Cannot use loop player while networked var skipLoopsBecauseNetwork = false; if (IsNetworked != null && IsNetworked()) { LoopStopAllRecording(); LoopStopPlaying(); skipLoopsBecauseNetwork = true; } if (command.HasFlag(LoopCommand.RecordHasFocus)) { for (var i = 0; i < loopSlots.Length; i++) { if (slotIndex.HasValue && slotIndex.Value == i) { // Record the loop (can't record to the playing loop!) if (command.HasFlag(LoopCommand.Record) && !(playingLoop.HasValue && i == playingLoop.Value)) { // If we were already recording on that slot, stop recording - this closes the file so we can re-open it! if (loopSlots[i] != null) { loopSlots[i].StopRecording(); } var saveState = Serialize(); loopSlots[i] = Loop.StartRecording(string.Format("loop{0}.bin", i), saveState, definitionHash, ""); if (command.HasFlag(LoopCommand.SnapshotOnly) || skipLoopsBecauseNetwork) { loopSlots[i].StopRecording(); // <- just the snapshot } } SelectedLoop = i; } } } if (skipLoopsBecauseNetwork) { return; } if (droppedLoopFilename != null) { if (command.HasFlag(LoopCommand.NextLoop) || command.HasFlag(LoopCommand.PreviousLoop)) { var dir = Path.GetDirectoryName(droppedLoopFilename); var files = Directory.GetFiles(dir, "*.bin", SearchOption.TopDirectoryOnly); Array.Sort(files, new NaturalStringComparer()); var index = Array.IndexOf(files, droppedLoopFilename); if (index >= 0) { if (command == LoopCommand.NextLoop) { index += 1; } else { index += files.Length - 1; } index %= files.Length; HandleDroppedLoop(files[index]); } } } if (command.HasFlag(LoopCommand.Stop)) { LoopStopAllRecording(); LoopStopPlaying(); } if (command.HasFlag(LoopCommand.StartPlaying)) { // Lazy-load from working directory: if (loopSlots[SelectedLoop] == null) { var filename = "loop" + SelectedLoop + ".bin"; if (File.Exists(filename)) { loopSlots[SelectedLoop] = Loop.TryLoadFromFile(filename, ref definitionHash); } } LoopStartPlaying(SelectedLoop); } }
private static void ProcessCommands(Command[] commands, ref int currentCommandIndex, int depth) { if (depth > Constants.MaxProcessingStack) { throw new Exception(Resources.ProcessingStackOverflow); } if (depth < 0) { throw new ArgumentOutOfRangeException(nameof(depth)); } while (currentCommandIndex < commands.Length) { Command currentCommand = commands[currentCommandIndex]; //Console.WriteLine(currentCommand.Name); if (currentCommand.Name.Equals(Constants.StartDefinition)) { currentCommandIndex++; ParseDefinition(commands, ref currentCommandIndex, false); } else if (currentCommand.Name.Equals(Constants.RedefineDefinition)) { currentCommandIndex++; ParseDefinition(commands, ref currentCommandIndex, true); } else if (currentCommand is IfCommand) { IfCommand ifCommand = currentCommand as IfCommand; FInteger intValue = new FInteger(BitConverter.ToInt32(Stack.Pop().Bytes, 0)); if (intValue.Value == Constants.True) { int ifCommandIndex = 0; ProcessCommands(ifCommand.IfCommands.ToArray(), ref ifCommandIndex, depth + 1); } else { int elseCommandIndex = 0; ProcessCommands(ifCommand.ElseCommands.ToArray(), ref elseCommandIndex, depth + 1); } } else if (currentCommand.Name.Equals(Constants.Else)) { } else if (currentCommand.Name.Equals(Constants.EndIf)) { } else if (currentCommand is RepeatCommand) { RepeatCommand repeatCommand = currentCommand as RepeatCommand; FInteger fInteger; do { int repeatCommandIndex = 0; ProcessCommands(repeatCommand.RepeatCommands.ToArray(), ref repeatCommandIndex, depth + 1); fInteger = new FInteger(BitConverter.ToInt32(Stack.Pop().Bytes, 0)); } while (fInteger.Value == Constants.False); } else if (currentCommand.Name.Equals(Constants.Until)) { } else if (currentCommand is LoopCommand) { LoopCommand loopCommand = currentCommand as LoopCommand; FInteger incrementor = new FInteger(BitConverter.ToInt32(Stack.Pop().Bytes, 0)); FInteger currentValue = new FInteger(BitConverter.ToInt32(Stack.Pop().Bytes, 0)); FInteger targetValue = new FInteger(BitConverter.ToInt32(Stack.Pop().Bytes, 0)); while (currentValue.Value != targetValue.Value) { Stack.Push(new Cell(targetValue.GetBytes())); Stack.Push(new Cell(currentValue.GetBytes())); Stack.Push(new Cell(incrementor.GetBytes())); int loopCommandIndex = 0; ProcessCommands(loopCommand.LoopCommands.ToArray(), ref loopCommandIndex, depth + 1); incrementor = new FInteger(BitConverter.ToInt32(Stack.Pop().Bytes, 0)); currentValue = new FInteger(BitConverter.ToInt32(Stack.Pop().Bytes, 0)); targetValue = new FInteger(BitConverter.ToInt32(Stack.Pop().Bytes, 0)); currentValue.Value += incrementor.Value; } } else if (currentCommand.Name.Equals(Constants.EndLoop)) { } else { if ((_ioMode == IoModeEnum.Hex) && (IsHexInteger(currentCommand.Name))) { int intValue; if (!int.TryParse(currentCommand.Name, System.Globalization.NumberStyles.HexNumber, null, out intValue)) { throw new Exception(string.Format(Resources.InvalidHexInteger, currentCommand)); } FInteger intConstant = new FInteger(intValue); Stack.Push(new Cell(intConstant.GetBytes())); } else if ((_ioMode == IoModeEnum.Decimal) && (IsInteger(currentCommand.Name))) { int intValue; if (!int.TryParse(currentCommand.Name, out intValue)) { throw new Exception(string.Format(Resources.InvalidInteger, currentCommand)); } FInteger intConstant = new FInteger(intValue); Stack.Push(new Cell(intConstant.GetBytes())); } else { float floatValue; if ((_ioMode == IoModeEnum.Fraction) && (IsFloat(currentCommand.Name))) { if (!float.TryParse(currentCommand.Name, out floatValue)) { throw new Exception(string.Format(Resources.InvalidFloat, currentCommand)); } FFloat intConstant = new FFloat(floatValue); Stack.Push(new Cell(intConstant.GetBytes())); } else if ((_ioMode == IoModeEnum.Char) && (IsChar(currentCommand.Name))) { string subString = currentCommand.Name.Substring(Constants.StartChar.Length, currentCommand.Name.Length - Constants.EndChar.Length - 1); char ch; if (!char.TryParse(subString, out ch)) { throw new Exception(string.Format(Resources.InvalidCharacter, subString)); } FInteger intConstant = new FInteger(ch); Stack.Push(new Cell(intConstant.GetBytes())); } else if (IsString(currentCommand.Name)) { string subString = currentCommand.Name.Substring(Constants.StartString.Length, currentCommand.Name.Length - Constants.EndString.Length - 2); Console.Write(subString); } else if (IsVariable(currentCommand.Name)) { Stack.Push(new Cell(new FInteger(Objects[currentCommand.Name].Item2).GetBytes())); } else if (IsValue(currentCommand.Name)) { byte[] bytes = new byte[Constants.CellSize]; Array.Copy(Memory, Objects[currentCommand.Name].Item2, bytes, 0, Constants.CellSize); Stack.Push(new Cell(bytes)); } else if (IsConstant(currentCommand.Name)) { byte[] bytes = new byte[Constants.CellSize]; Array.Copy(Memory, Objects[currentCommand.Name].Item2, bytes, 0, Constants.CellSize); Stack.Push(new Cell(bytes)); } else if (IsDefinition(currentCommand.Name)) { int definitionTokenIndex = 0; ProcessCommands(Definitions[currentCommand.Name].ToArray(), ref definitionTokenIndex, depth + 1); } else if (currentCommand.Name.Equals(Constants.ViewDefinitions)) { Console.WriteLine(); foreach (string key in Definitions.Keys) { Console.Write(Resources.Executor_ProcessCommands__StartDefinition, Constants.StartDefinition); Console.Write(string.Format(Resources.Executor_ProcessCommands__Key, key).PadRight(18, ' ')); foreach (Command command in Definitions[key]) { Console.Write(string.Format("{0} ", command.Name)); } Console.WriteLine(string.Format("{0}", Constants.EndDefinition)); } } else if (currentCommand.Name.Equals(Constants.ViewObjects)) { Console.WriteLine(); foreach (string key in Objects.Keys) { Console.Write(string.Format("{0}", key).PadRight(20, ' ')); Console.Write(string.Format("{0}\t", Objects[key].Item1)); Console.Write(string.Format("{0}\t", Objects[key].Item2)); byte[] bytes = FetchFromMemory(new FInteger(Objects[key].Item2)); Console.WriteLine(string.Format("{0}", GetOutputValue(bytes))); } } else if (currentCommand.Name.Equals(Constants.Help)) { Console.WriteLine(); foreach (string command in Constants.ValidCommands) { Console.WriteLine(command); } } else if (currentCommand.Name.Equals(Constants.Variable)) { if (currentCommandIndex >= commands.Length - 1) { throw new Exception(Resources.ExpectedAName); } currentCommandIndex++; string variableName = commands[currentCommandIndex].Name; if (IsAlreadyDefined(variableName)) { throw new Exception(string.Format(Resources.AlreadyDefined, variableName)); } AddObject(variableName, MemoryEntryEnum.Variable); } else if (currentCommand.Name.Equals(Constants.Value)) { if (currentCommandIndex >= commands.Length - 1) { throw new Exception(Resources.ExpectedAName); } currentCommandIndex++; string variableName = commands[currentCommandIndex].Name; if (IsAlreadyDefined(variableName)) { throw new Exception(string.Format(Resources.AlreadyDefined, variableName)); } AddObject(variableName, MemoryEntryEnum.Value, Stack.Pop().Bytes); } else if (currentCommand.Name.Equals(Constants.Constant)) { if (currentCommandIndex >= commands.Length - 1) { throw new Exception(Resources.ExpectedAName); } currentCommandIndex++; string variableName = commands[currentCommandIndex].Name; if (IsAlreadyDefined(variableName)) { throw new Exception(string.Format(Resources.AlreadyDefined, variableName)); } AddObject(variableName, MemoryEntryEnum.Constant, Stack.Pop().Bytes); } else if (currentCommand.Name.Equals(Constants.Store)) { FInteger memoryLocation = new FInteger(BitConverter.ToInt32(Stack.Pop().Bytes, 0)); FInteger intValue = new FInteger(BitConverter.ToInt32(Stack.Pop().Bytes, 0)); StoreToMemory(intValue, memoryLocation); } else if (currentCommand.Name.Equals(Constants.Fetch)) { FInteger memoryLocation = new FInteger(BitConverter.ToInt32(Stack.Pop().Bytes, 0)); byte[] bytes = FetchFromMemory(memoryLocation); FInteger intValue = new FInteger(BitConverter.ToInt32(bytes, 0)); Stack.Push(new Cell(intValue.GetBytes())); } else if (currentCommand.Name.Equals(Constants.To)) { if (currentCommandIndex >= commands.Length - 1) { throw new Exception(Resources.ExpectedAName); } currentCommandIndex++; string valueName = commands[currentCommandIndex].Name; if (!IsValue(valueName)) { throw new Exception(string.Format(Resources.NameIsNotAValue, valueName)); } SetObject(Objects[valueName].Item2, Stack.Pop().Bytes); } else if (currentCommand.Name.Equals(Constants.Cell)) { Stack.Push(new Cell(new FInteger(Constants.CellSize).GetBytes())); } else if (currentCommand.Name.Equals(Constants.Here)) { Stack.Push(new Cell(new FInteger(_memoryPointer).GetBytes())); } else if (currentCommand.Name.Equals(Constants.Allot)) { FInteger memoryAllocBytes = new FInteger(BitConverter.ToInt32(Stack.Pop().Bytes, 0)); if (_memoryPointer + memoryAllocBytes.Value < 0) { throw new Exception(Resources.MemoryUnderflow); } else if (_memoryPointer + memoryAllocBytes.Value > Constants.MemorySize) { throw new Exception(Resources.MemoryOverflow); } _memoryPointer += memoryAllocBytes.Value; } else if (currentCommand.Name.Equals(Constants.Decimal)) { _ioMode = IoModeEnum.Decimal; } else if (currentCommand.Name.Equals(Constants.Hex)) { _ioMode = IoModeEnum.Hex; } else if (currentCommand.Name.Equals(Constants.Fractional)) { _ioMode = IoModeEnum.Fraction; } else if (currentCommand.Name.Equals(Constants.Char)) { _ioMode = IoModeEnum.Char; } else if (currentCommand.Name.Equals(Constants.Period)) { OutputValue(Stack.Pop().Bytes); } else if (currentCommand.Name.Equals(Constants.Dup)) { Stack.Dup(); } else if (currentCommand.Name.Equals(Constants.Swap)) { Stack.Swap(); } else if (currentCommand.Name.Equals(Constants.Drop)) { Stack.Drop(); } else if (currentCommand.Name.Equals(Constants.Rot)) { Stack.Rot(); } else if (currentCommand.Name.Equals(Constants.Over)) { Stack.Over(); } else if (currentCommand.Name.Equals(Constants.Tuck)) { Stack.Tuck(); } else if (currentCommand.Name.Equals(Constants.Roll)) { Stack.Roll(); } else if (currentCommand.Name.Equals(Constants.Pick)) { Stack.Pick(); } else if (currentCommand.Name.Equals(Constants.Cr)) { Console.WriteLine(); } else if ( currentCommand.Name.Equals(Constants.Add) || currentCommand.Name.Equals(Constants.Subtract) || currentCommand.Name.Equals(Constants.Multiply) || currentCommand.Name.Equals(Constants.Modulus) || currentCommand.Name.Equals(Constants.Divide) || currentCommand.Name.Equals(Constants.GreaterThan) || currentCommand.Name.Equals(Constants.LessThan) || currentCommand.Name.Equals(Constants.GreaterThanOrEqual) || currentCommand.Name.Equals(Constants.LessThanOrEqual) || currentCommand.Name.Equals(Constants.Equal) || currentCommand.Name.Equals(Constants.NotEqual) || currentCommand.Name.Equals(Constants.And) || currentCommand.Name.Equals(Constants.Or) || currentCommand.Name.Equals(Constants.Not) ) { if (_ioMode == IoModeEnum.Fraction) { Stack.FloatMaths(currentCommand.Name); } else { Stack.IntMaths(currentCommand.Name); } } else { throw new Exception(string.Format(Resources.UnknownItem, currentCommand.Name)); } } } // Increment to next token currentCommandIndex++; } }
/// <summary> /// Main Parser function. Takes string of tokens and parses into Command elements. /// Most Commands will just be plain strings, but some ('if', 'loop' etc. will be /// dedicated commands with properties specifying the sub-commands to be executed) /// </summary> /// <param name="tokens">Array of tokens to parse</param> /// <param name="tokenIndex">Initial token index</param> /// <param name="stopTokens">Array of stop-tokens. E.g. 'If' parsing should stop on 'else' or 'endif'</param> /// <returns>Array of Command objects</returns> public static Command[] Parse(string[] tokens, ref int tokenIndex, string[] stopTokens) { List <Command> parsedTokens = new List <Command>(); while (tokenIndex < tokens.Length) { string token = tokens[tokenIndex]; if (token.Equals(Constants.If)) { IfCommand ifCommand = new IfCommand(); tokenIndex++; ifCommand.IfCommands.AddRange(Parse(tokens, ref tokenIndex, new[] { Constants.Else, Constants.EndIf })); // Only parse the following tokens in our 'if' statement if the next token after the 'then' phase is *not* // 'endif'. This is to handle 'else-less' 'if's where we are only programmed to handle what happens when // the 'if' evaluation is true, and to do nothing when the 'if' evaluation is false. if (tokenIndex >= 1 && !tokens[tokenIndex - 1].Equals(Constants.EndIf)) { ifCommand.ElseCommands.AddRange(Parse(tokens, ref tokenIndex, new[] { Constants.EndIf })); } parsedTokens.Add(ifCommand); } else if (token.Equals(Constants.Loop)) { LoopCommand loopCommand = new LoopCommand(); tokenIndex++; loopCommand.LoopCommands.AddRange(Parse(tokens, ref tokenIndex, new[] { Constants.EndLoop })); parsedTokens.Add(loopCommand); } else if (token.Equals(Constants.Repeat)) { RepeatCommand repeatCommand = new RepeatCommand(); tokenIndex++; repeatCommand.RepeatCommands.AddRange(Parse(tokens, ref tokenIndex, new[] { Constants.Until })); parsedTokens.Add(repeatCommand); } else { // For anything that's not an 'if', or loop, just add the string as a command. // The executor can handle if it's not an actual command parsedTokens.Add(new Command(token)); if ((stopTokens != null) && (stopTokens.Contains(token))) { tokenIndex++; return(parsedTokens.ToArray()); } tokenIndex++; } } if (stopTokens != null) { // If we get here then 'stopTokens' was set to something that should terminate a sequence of commands, // but wasn't found. E.G. An 'if' without an 'endif'. throw new Exception(string.Format(Resources.Expected_, string.Join("/", stopTokens))); } return(parsedTokens.ToArray()); }