using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.Windows.Forms; namespace Simulation { /// /// SimulationModel is the simulation engine "starter kit" class. /// It also provides a simple visual display of directed nodes built with objects /// from the SimNode and SimConnector classes. /// /// Mike Barnes 3/10/07 /// public abstract class SimulationModel : Form { /// boolean, true if directed edge is from left to right protected const bool leftToRight = true; /// boolean, false if directed edge is from right to left protected const bool rightToLeft = false; /// The enum state of the nodes. /// IDLE nodes are light blue /// BLOCKED nodes are light red /// BUSY nodes are light green /// protected enum state { IDLE, BLOCKED, BUSY }; /// Simulation model time protected int now; /// references the SimNode last selected with a left click protected SimNode activeSimNode; /// /// eventList holds the scheduled events. /// In starter kit this a generic Queue, but it should be a generic List ordered /// by schedule time for the event. /// eventListNode shows the server's with scheduled events. /// protected Queue eventList; protected SimNode eventListNode; /// SimNode [] the nodes in the simulation. protected SimNode [] serverNode, queueNode; /// List of nodes in the simulation. protected List nodes; /// List of connectors in the simulation. protected List connectors; /// The Queue collections in the simulation -- used to hold entites protected Queue [] queue; /// Dialog box describes this simulation demo and how to use it. protected About aboutDialog; /// Dialog box describes this simulation demo and how to use it. protected ReportStatistics reportDialog; /// MenuItems to start/pause the simulation and show usage information to user protected MenuItem SimulateItem, StepItem, ReportItem, AboutItem; /// Display messages to the user. Left click on SimNode to see its location. protected StatusBar statusBar; /// A random number generator protected Random random = new Random(); /// Timer, generates events to "demo" the simulation states. protected Timer timer; /// /// Construct the SimulationModel by creating: /// server and queue nodes with title, location, direction, and reference to self /// connector nodes with source and destination nodes and direction /// timer and timer interval /// menu items, statusbar, and help dialog /// public SimulationModel() { //describes usage of this model. Need to update about.rtf description. aboutDialog = new About(); //displays, or prints, statistics about this model. reportDialog = new ReportStatistics(); // display of information to user in window's status bar statusBar = new StatusBar(); statusBar.Location = new Point(0, 244); statusBar.Name = "statusBar"; statusBar.Size = new System.Drawing.Size(536, 22); statusBar.Parent = this; statusBar.Text = "Constructor"; // SimulationModel attributes AutoScaleBaseSize = new Size(5, 13); BackColor = Color.White; ClientSize = new Size(1000, 600); this.Text = "Simulation Model"; this.MouseUp += new MouseEventHandler(this.moveSimNode); // start / pause simulation and display aboutDialog menu items and event handlers SimulateItem = new MenuItem("&Simulate", new EventHandler(menuSimulateOnClick)); StepItem = new MenuItem("Step 0.5 sec", new EventHandler(menuStepOnClick)); ReportItem = new MenuItem("&Report statistics", new EventHandler(menuReportOnClick)); AboutItem = new MenuItem("&About", new EventHandler(menuAboutOnClick)); // set the menu bar Menu = new MainMenu(new MenuItem[] {SimulateItem, StepItem, ReportItem, AboutItem}); // use a timer, to step simulation of the model with its event handler timerTick method timer = new Timer(); timer.Interval= 500; // milliseconds timer.Tick += new EventHandler(Simulate); } // end SimulationModel /// /// Property refereces the currently selected SimNode. /// Set initiated by a left mouse down on a SimNode. /// SimNode's SimNodeMouseDown method handles left mouse down events. /// public SimNode ActiveSimNode { get { return activeSimNode; } set { activeSimNode = value; } } /// /// Start and pause the simulation of the model. /// /// SimulateItem /// EventArgs private void menuSimulateOnClick(object obj, EventArgs ea) { if ( ! timer.Enabled ) { timer.Start(); SimulateItem.Text = "Pause Simulation"; statusBar.Text = "Simulation running, click \"Pause Simulation\" to pause."; } else { timer.Stop(); SimulateItem.Text = "Simulate"; statusBar.Text = "Simulation paused, click \"Simulate\" to resume."; } } /// /// Toggle through simulation timer intervals. /// Displays current timer interval. /// /// AboutItem /// EventArgs private void menuStepOnClick(object obj, EventArgs ea) { if (timer.Enabled) { timer.Interval = (timer.Interval + 2000) % 7000; StepItem.Text = String.Format("Step {0:f1} sec", (float)timer.Interval/1000.0); } } /// /// Report, or print, stimulation statistics information to the user. /// /// ReportItem /// EventArgs private void menuReportOnClick(object obj, EventArgs ea) { reportDialog.Show(); } /// /// Display usage information to the user. /// /// AboutItem /// EventArgs private void menuAboutOnClick(object obj, EventArgs ea) { aboutDialog.Show(); } /// /// On Invalidates (repaints) calls OnPaint to redraw all the connectors /// /// protected override void OnPaint(PaintEventArgs pea) { foreach(SimConnector scm in connectors) scm.draw(pea); } /// /// The drag operation on a SimNode has concluded. Tell the morph to repostion itself. /// Reset the activeSimNode and redraw the display. /// /// /// private void moveSimNode(object sender, MouseEventArgs e) { if (ActiveSimNode != null) { ActiveSimNode.moveSimNode(new Point(e.X, e.Y)); statusBar.Text = "node " + ActiveSimNode.Text + " position is " + ActiveSimNode.Location.ToString(); ActiveSimNode = null; Invalidate(); } // redraw the display by implicitly calling OnPaint(). } /// /// Simulation is driven by Timer. /// Simulate should invokes the next event's Activity() /// to reflect the end of a service. /// /// The object sending the timer tick /// Event Arguments of the timer event protected abstract void Simulate(object obj, EventArgs ea); } }