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);
}
}