public bool DoExecute(ActionBase ac) // execute if control state { return(execstate[execlevel] == ExecState.On || ac.Type >= ActionBase.ActionType.If); }
// true is reported on an error, or we need to get the next action. public bool LevelUp(int up, ActionBase action) // action may be null at end of program { while (up-- > 0) { if (execlevel == 0) { ReportError("Nested program level error, tring to move up while on level 0"); return(true); } if (IsExecutingType(ActionBase.ActionType.Do)) // DO needs a while at level -1.. { if (action != null && action.Type == ActionBase.ActionType.While) { if (action.LevelUp == 1) // only 1, otherwise its incorrectly nested { ActionWhile w = action as ActionWhile; if (w.ExecuteEndDo(this)) // if this indicates (due to true) we need to fetch next instruction { return(true); } else { RemoveLevel(); // else, just remove level.. } } else { ReportError("While incorrectly nested under Do"); return(true); } } else { ReportError("While missing after Do"); return(true); } } else if (IsExecutingType(ActionBase.ActionType.Loop)) // active loop, need to consider if we need to go back { // break may have cancelled this if (PushPos >= 0 && ((ActionLoop)GetStep(PushPos)).ExecuteEndLoop(this)) // if true, it wants to move back, so go back and get next value. { return(true); } else { RemoveLevel(); // else, just remove level.. } } else if (IsExecutingType(ActionBase.ActionType.ForEach)) // active For, need to consider if we need to go back { // break may have cancelled this if (PushPos >= 0 && ((ActionForEach)GetStep(PushPos)).ExecuteEndFor(this)) // if true, it wants to move back, so go back and get next value. { return(true); } else { RemoveLevel(); // else, just remove level.. } } else { // normal, just see if need to loop back int stepback = PushPos; RemoveLevel(); if (stepback >= 0) { Goto(stepback); return(true); } } } return(false); }
public void Add(ActionBase ap) { programsteps.Add(ap); }
public void Insert(int pos, ActionBase ap) { programsteps.Insert(pos, ap); }
public string Read(System.IO.TextReader sr, ref int lineno) // read from stream { string err = ""; programsteps = new List <ActionBase>(); Name = ""; List <int> indents = new List <int>(); List <int> level = new List <int>(); int indentpos = -1; int structlevel = 0; string completeline; int initiallineno = lineno; while ((completeline = sr.ReadLine()) != null) { lineno++; completeline = completeline.Replace("\t", " "); // detab, to spaces, tabs are worth 4. BaseUtils.StringParser p = new BaseUtils.StringParser(completeline); if (!p.IsEOL) { int curindent = p.Position; string cmd = ""; if (p.IsStringMoveOn("//")) // special, this is allowed to butt against text and still work { cmd = "//"; } else { cmd = p.NextWord(); } if (cmd.Equals("Else", StringComparison.InvariantCultureIgnoreCase)) { //System.Diagnostics.Debug.WriteLine("Else " + cmd + " " + p.LineLeft); if (p.IsStringMoveOn("If", StringComparison.InvariantCultureIgnoreCase)) // if Else followed by IF { cmd = "Else If"; } } string line = p.LineLeft; // and the rest of the line.. int commentpos = line.LastIndexOf("//"); string comment = ""; if (cmd != "//" && commentpos >= 0 && !line.InQuotes(commentpos)) // if not // command, and we have one.. { comment = line.Substring(commentpos + 2).Trim(); line = line.Substring(0, commentpos).TrimEnd(); //System.Diagnostics.Debug.WriteLine("Line <" + line + "> <" + comment + ">"); } if (cmd.Equals("PROGRAM", StringComparison.InvariantCultureIgnoreCase)) { Name = line; } else if (cmd.Equals("END", StringComparison.InvariantCultureIgnoreCase) && line.Equals("PROGRAM", StringComparison.InvariantCultureIgnoreCase)) { break; } else { ActionBase a = ActionBase.CreateAction(cmd, line, comment); string vmsg; if (a == null) { err += lineno + " " + Name + " Unrecognised command " + cmd + Environment.NewLine; } else if ((vmsg = a.VerifyActionCorrect()) != null) { err += lineno + " " + Name + ":" + vmsg + Environment.NewLine + " " + completeline.Trim() + Environment.NewLine; } else { //System.Diagnostics.Debug.WriteLine(indentpos + ":" + structlevel + ": Cmd " + cmd + " : " + line); if (indentpos == -1) { indentpos = curindent; } else if (curindent > indentpos) // more indented, up one structure { structlevel++; indentpos = curindent; } else if (curindent < indentpos) // deindented { int tolevel = -1; for (int i = indents.Count - 1; i >= 0; i--) // search up and find the entry with the indent.. { if (indents[i] <= curindent) { tolevel = i; break; } } if (tolevel >= 0) // if found, we have a statement to hook to.. { // while in DO loop, or Else/Elseif in IF if ((a.Type == ActionBase.ActionType.While && programsteps[tolevel].Type == ActionBase.ActionType.Do) || ((a.Type == ActionBase.ActionType.Else || a.Type == ActionBase.ActionType.ElseIf) && programsteps[tolevel].Type == ActionBase.ActionType.If)) { int reallevel = level[tolevel] + 1; // else, while are dedented, but they really are on level+1 a.LevelUp = structlevel - reallevel; structlevel = reallevel; indentpos = indents[tolevel] + 4; // and our indent should continue 4 in, so we don't match against this when we do indent } else { a.LevelUp = structlevel - level[tolevel]; structlevel = level[tolevel]; // if found, we are at that.. except.. indentpos = indents[tolevel]; // and back to this level } } } a.LineNumber = lineno; //System.Diagnostics.Debug.WriteLine(" >>>> " + indentpos + ":" + structlevel); indents.Add(indentpos); level.Add(structlevel); programsteps.Add(a); } } } else { if (programsteps.Count > 0) { programsteps[programsteps.Count - 1].Whitespace = 1; } } } if (programsteps.Count > 0) { programsteps[programsteps.Count - 1].Whitespace = 0; // last cannot have whitespace.. } progclass = Classify(); return(err); }
private void DoExecute() // MAIN thread only.. { executing = true; System.Diagnostics.Stopwatch timetaken = new System.Diagnostics.Stopwatch(); timetaken.Start(); while (true) { if (progcurrent != null) { if (progcurrent.GetErrorList != null) // any errors pending, handle { actioncontroller.LogLine("Error: " + progcurrent.GetErrorList + Environment.NewLine + StackTrace()); TerminateToCloseAtEnd(); // terminate up to a close at end entry, which would have started this stack } else if (progcurrent.IsProgramFinished) // if current program ran out, cancel it { // this catches a LOOP without a statement at the end.. or a DO without a WHILE at the end.. if (progcurrent.ExecLevel > 0 && progcurrent.LevelUp(progcurrent.ExecLevel, null)) // see if we have any pending LOOP (or a DO without a while) and continue.. { continue; // errors or movement causes it to go back.. errors will be picked up above } TerminateCurrent(); } } while (progcurrent == null && progqueue.Count > 0) // if no program,but something in queue { progcurrent = progqueue[0]; progqueue.RemoveAt(0); if (progcurrent.variables != null) // if not null, its because its just been restarted after a call.. reset globals { progcurrent.Add(actioncontroller.Globals); // in case they have been updated... progcurrent.Add(progcurrent.ActionFile.FileVariables); // in case they have been updated... } else { progcurrent.PrepareToRun( new Variables(progcurrent.inputvariables, actioncontroller.Globals, progcurrent.ActionFile.FileVariables), new FunctionPersistentData(), new Dictionary <string, ExtendedControls.ConfigurableForm>(), true); // with new file handles and close at end.. } if (progcurrent.IsProgramFinished) // reject empty programs.. { TerminateCurrent(); continue; // and try again } } if (progcurrent == null) // Still nothing, game over { break; } ActionBase ac = progcurrent.GetNextStep(); // get the step. move PC on. // System.Diagnostics.Debug.WriteLine((Environment.TickCount % 10000).ToString("00000") + " " + timetaken.ElapsedMilliseconds + " @ " + progcurrent.Location + " Lv " + progcurrent.ExecLevel + " e " + (progcurrent.IsExecuteOn ? "1" : "0") + " up " + ac.LevelUp + " " + progcurrent.PushPos + " " + ac.Name); if (ac.LevelUp > 0 && progcurrent.LevelUp(ac.LevelUp, ac)) // level up.. { //System.Diagnostics.Debug.WriteLine((Environment.TickCount % 10000).ToString("00000") + " Abort Lv" + progcurrent.ExecLevel + " e " + (progcurrent.IsExecuteOn ? "1" : "0") + " up " + ac.LevelUp + ": " + progcurrent.StepNumber + " " + ac.Name + " " + ac.DisplayedUserData); continue; } if (logtologline || logger != null) { string t = (Environment.TickCount % 10000).ToString("00000") + " "; string index = string.Concat(Enumerable.Repeat(". ", progcurrent.ExecLevel)); string s = progcurrent.GetLastStep().LineNumber.ToString() + (progcurrent.IsExecuteOn ? "+" : "-") + ":" + index + ac.Name + " " + ac.DisplayedUserData; System.Diagnostics.Debug.WriteLine(t + s); if (logtologline) { actioncontroller.LogLine(t + s); } if (logger != null) { logger.WriteLine(s); } } if (progcurrent.DoExecute(ac)) // execute is on.. { if (ac.Type == ActionBase.ActionType.Call) // Call needs to pass info back up thru to us, need a different call { ActionCall acall = ac as ActionCall; string prog; Variables paravars; if (acall.ExecuteCallAction(progcurrent, out prog, out paravars)) // if execute ok { //System.Diagnostics.Debug.WriteLine("Call " + prog + " with " + paravars.ToString()); Tuple <ActionFile, ActionProgram> ap = actionfilelist.FindProgram(prog, progcurrent.ActionFile); // find program using this name, prefer this action file first if (ap != null) { Run(true, ap.Item1, ap.Item2, paravars, progcurrent.Functions.persistentdata, progcurrent.Dialogs, false); // run now with these para vars } else { progcurrent.ReportError("Call cannot find " + prog); } } } else if (ac.Type == ActionBase.ActionType.Return) // Return needs to pass info back up thru to us, need a different call { ActionReturn ar = ac as ActionReturn; string retstr; if (ar.ExecuteActionReturn(progcurrent, out retstr)) { TerminateCurrent(); // if a new program is queued, but not prepared, and this program returns to finish, make sure we don't // screw up since the variables are not preparred yet - they will be above in PrepareToRun if (progqueue.Count > 0 && progqueue[0].variables != null) // pass return value if program is there AND its prepared { progqueue[0]["ReturnValue"] = retstr; } continue; // back to top, next action from returned function. } } else if (!ac.ExecuteAction(progcurrent)) // if execute says, stop, i'm waiting for something { return; // exit, with executing set true. ResumeAfterPause will restart it. } } if (AsyncMode && timetaken.ElapsedMilliseconds > 150) // no more than ms per go to stop the main thread being blocked { System.Diagnostics.Debug.WriteLine((Environment.TickCount % 10000).ToString("00000") + " *** SUSPEND Actions at " + timetaken.ElapsedMilliseconds); restarttick.Start(); break; } } executing = false; }
string RepositionGroups(bool calcminsize = true) { SuspendLayout(); panelVScroll.SuspendLayout(); string errlist = curprog.CalculateLevels(); int panelwidth = Math.Max(panelVScroll.Width - panelVScroll.ScrollBarWidth, 10); int voff = panelheightmargin; int actstep = 0; toolTip1.RemoveAll(); foreach (Group g in groups) { int indentlevel = 0; int whitespace = 0; int lineno = 0; ActionBase act = curprog.GetStep(actstep++); if (act != null) { System.Diagnostics.Debug.Assert(Object.ReferenceEquals(g.checkit, act)); g.left.Enabled = act.calcAllowLeft; g.right.Enabled = act.calcAllowRight; indentlevel = act.calcDisplayLevel; whitespace = act.Whitespace; lineno = act.LineNumber; g.prog.Visible = act.Type == ActionBase.ActionType.Call & EditProgram != null; g.config.Visible = act.ConfigurationMenuInUse; } else { g.left.Enabled = g.right.Enabled = false; g.prog.Visible = false; g.config.Visible = false; } g.panel.SuspendLayout(); g.panel.Location = new Point(panelleftmargin, voff + panelVScroll.ScrollOffset); g.panel.Size = new Size(panelwidth, panelheight + ((whitespace > 0) ? (panelheight / 2) : 0)); g.stepname.Location = new Point(g.right.Right + 8 + 8 * indentlevel, panelheightmargin); g.stepname.Size = new Size(140 - Math.Max((indentlevel - 4) * 8, 0), controlsize); g.value.Location = new Point(g.right.Right + 140 + 8 + 8 * 4 + 8, panelheightmargin * 2); // 8 spacing, allow 8*4 to indent int valuewidth = panelwidth - 350; g.value.Size = new Size(valuewidth, controlsize); g.config.Location = new Point(g.value.Right + 4, panelheightmargin); // 8 spacing, allow 8*4 to indent g.up.Location = new Point(g.config.Right + 4, panelheightmargin); g.prog.Location = new Point(g.up.Right + 4, panelheightmargin); g.up.Visible = groups.IndexOf(g) > 0; g.panel.ResumeLayout(); string tt1 = "Step " + actstep; if (indentlevel > 0) { tt1 += " Lv " + indentlevel; } if (lineno > 0) { tt1 += " Ln " + lineno; } if (act != null) { tt1 += " SL " + act.calcStructLevel + " LU" + act.LevelUp; } toolTip1.SetToolTip(g.stepname, tt1); toolTip1.SetToolTip(g.stepname.GetInternalSystemControl, tt1); if (act != null && act.Comment.Length > 0) { toolTip1.SetToolTip(g.value, "Comment: " + act.Comment); } //DEBUG Keep this useful for debugging structure levels // if (g.programstep != null) // g.value.Enabled = false; g.value.Text = structlevel.ToString() + " ^ " + g.levelup + " UD: " + g.programstep.DisplayedUserData;g.value.Enabled = true; voff += g.panel.Height; } buttonMore.Location = new Point(panelleftmargin, voff + panelVScroll.ScrollOffset); buttonMore.Size = new Size(controlsize, controlsize); Rectangle screenRectangle = RectangleToScreen(this.ClientRectangle); int titleHeight = screenRectangle.Top - this.Top; // Beware Visible - it does not report back the set state, only the visible state.. hence use Enabled. voff += buttonMore.Height + titleHeight + panelName.Height + ((panelTop.Enabled) ? (panelTop.Height + statusStripCustom.Height) : 8) + 16 + panelOK.Height; if (calcminsize) { this.MinimumSize = new Size(600, voff); this.MaximumSize = new Size(Screen.FromControl(this).WorkingArea.Width - 100, Screen.FromControl(this).WorkingArea.Height - 100); if (Bottom > Screen.FromControl(this).WorkingArea.Height) { Top = Screen.FromControl(this).WorkingArea.Height - Height - 50; } } panelVScroll.ResumeLayout(); ResumeLayout(); return(errlist); }
Group CreateStep(int insertpos, ActionBase step = null) { SuspendLayout(); panelVScroll.SuspendLayout(); Group g = new Group(); g.checkit = step; g.panel = new Panel(); g.panel.SuspendLayout(); g.panel.MouseUp += panelVScroll_MouseUp; g.panel.MouseDown += panelVScroll_MouseDown; g.panel.MouseMove += panelVScroll_MouseMove; g.panel.ContextMenuStrip = contextMenuStrip1; g.left = new ExtendedControls.ButtonExt(); g.left.Location = new Point(0, panelheightmargin); // 8 spacing, allow 8*4 to indent g.left.Size = new Size(controlsize, controlsize); g.left.Text = "<"; g.left.Click += Left_Clicked; g.panel.Controls.Add(g.left); g.right = new ExtendedControls.ButtonExt(); g.right.Location = new Point(g.left.Right + 2, panelheightmargin); // 8 spacing, allow 8*4 to indent g.right.Size = new Size(controlsize, controlsize); g.right.Text = ">"; g.right.Click += Right_Clicked; g.panel.Controls.Add(g.right); g.stepname = new ExtendedControls.ComboBoxCustom(); g.stepname.Items.AddRange(ActionBase.GetActionNameList()); g.stepname.DropDownHeight = 400; if (step != null) { g.stepname.Text = step.Name; } g.stepname.SelectedIndexChanged += Stepname_SelectedIndexChanged; g.panel.Controls.Add(g.stepname); g.value = new ExtendedControls.TextBoxBorder(); SetValue(g.value, step); g.value.TextChanged += Value_TextChanged; g.value.Click += Value_Click; g.panel.Controls.Add(g.value); // must be next g.config = new ExtendedControls.ButtonExt(); g.config.Text = "C"; g.config.Size = new Size(controlsize, controlsize); g.config.Click += ActionConfig_Clicked; g.panel.Controls.Add(g.config); // must be next g.up = new ExtendedControls.ButtonExt(); g.up.Size = new Size(controlsize, controlsize); g.up.Text = "^"; g.up.Click += Up_Clicked; g.panel.Controls.Add(g.up); g.prog = new ExtendedControls.ButtonExt(); g.prog.Size = new Size(controlsize, controlsize); g.prog.Text = ">"; g.prog.Click += Prog_Clicked; g.panel.Controls.Add(g.prog); g.config.Tag = g.stepname.Tag = g.up.Tag = g.value.Tag = g.left.Tag = g.right.Tag = g.prog.Tag = g; ExtendedControls.ThemeableFormsInstance.Instance.ApplyToControls(g.panel, SystemFonts.DefaultFont); panelVScroll.Controls.Add(g.panel); if (insertpos == -1) { groups.Add(g); } else { groups.Insert(insertpos, g); } g.panel.ResumeLayout(); panelVScroll.ResumeLayout(); ResumeLayout(); return(g); }
Group CreateStep(int insertpos, ActionBase step = null) { SuspendLayout(); panelVScroll.SuspendLayout(); Group g = new Group(); // layout sizes as if its in 12 point, then its scaled. g.checkit = step; g.panel = new Panel(); g.panel.SuspendLayout(); g.panel.MouseUp += panelVScroll_MouseUp; g.panel.MouseDown += panelVScroll_MouseDown; g.panel.MouseMove += panelVScroll_MouseMove; g.panel.ContextMenuStrip = contextMenuStrip1; int controlsize = 22; // for a 12 point layout.. g.left = new ExtendedControls.ExtButton(); g.left.Location = new Point(0, panelheightmargin); g.left.Size = new Size(controlsize, controlsize); g.left.Text = "<"; g.left.Click += Left_Clicked; g.panel.Controls.Add(g.left); g.right = new ExtendedControls.ExtButton(); g.right.Location = new Point(g.left.Right + 2, panelheightmargin); g.right.Size = new Size(controlsize, controlsize); g.right.Text = ">"; g.right.Click += Right_Clicked; g.panel.Controls.Add(g.right); g.stepname = new ExtendedControls.ExtComboBox(); g.stepname.Size = new Size(10, controlsize); // width set by positioning g.stepname.Items.AddRange(ActionBase.GetActionNameList()); if (step != null) { g.stepname.Text = step.Name; } g.stepname.SelectedIndexChanged += Stepname_SelectedIndexChanged; g.panel.Controls.Add(g.stepname); g.value = new ExtendedControls.ExtTextBox(); g.value.Location = new Point(200, panelheightmargin); // fixed ref point in 12 point space g.value.Size = new Size(10, controlsize); // width set by positioning SetValue(g.value, step); g.value.TextChanged += Value_TextChanged; g.value.Click += Value_Click; g.panel.Controls.Add(g.value); // must be next g.config = new ExtendedControls.ExtButton(); g.config.Text = "C"; g.config.Size = new Size(controlsize, controlsize); g.config.Click += ActionConfig_Clicked; g.panel.Controls.Add(g.config); // must be next g.up = new ExtendedControls.ExtButton(); g.up.Size = new Size(controlsize, controlsize); g.up.Text = "^"; g.up.Click += Up_Clicked; g.panel.Controls.Add(g.up); g.prog = new ExtendedControls.ExtButton(); g.prog.Size = new Size(controlsize, controlsize); g.prog.Text = ">"; g.prog.Click += Prog_Clicked; g.panel.Controls.Add(g.prog); g.config.Tag = g.stepname.Tag = g.up.Tag = g.value.Tag = g.left.Tag = g.right.Tag = g.prog.Tag = g; ExtendedControls.Theme.Current.ApplyDialog(g.panel); g.panel.Scale(this.CurrentAutoScaleFactor()); panelVScroll.Controls.Add(g.panel); if (insertpos == -1) { groups.Add(g); } else { groups.Insert(insertpos, g); } g.panel.ResumeLayout(); panelVScroll.ResumeLayout(); ResumeLayout(); return(g); }