using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace Lift_Controller { public enum Direction { Up, Down } public delegate void sensorStateChangeDelegate(); public delegate void positionChangeDelegate(); public class LiftController { public LiftController(int numFloors, int position, int[] fps) { numberOfFloors = numFloors; currentPosition = position; floorPositions = fps; currentFloor = getFloor(currentPosition); liftDelay = 10; // Initialize the sensors liftButtonSensors = new LiftButtonSensor[numberOfFloors]; floorUpButtonSensors = new FloorButtonSensor[numberOfFloors]; floorDownButtonSensors = new FloorButtonSensor[numberOfFloors]; upSensor = new LiftUpSensor(this); downSensor = new LiftDownSensor(this); // Allocate appropritate button sensors at each floor for (int f = 0; f < numberOfFloors; f++) { floorUpButtonSensors[f] = new FloorButtonSensor(f, Direction.Up, this); floorDownButtonSensors[f] = new FloorButtonSensor(f, Direction.Down, this); liftButtonSensors[f] = new LiftButtonSensor(f, this); } } public int LiftDelay { get { return liftDelay; } set { liftDelay = value; } } public int CurrentPosition { get { return currentPosition; } set { if (currentPosition != value) { currentPosition = value; // Fire position change event positionChangeEvent(); } } } public int CurrentFloor { get { return getFloor(currentPosition); } set { if (currentFloor != value) { currentFloor = value; newFloor(currentFloor); } } } public FloorButtonSensor[] FloorUpButtonSensors { get { return floorUpButtonSensors; } } public FloorButtonSensor[] FloorDownButtonSensors { get { return floorDownButtonSensors; } } public LiftButtonSensor[] LiftButtonSensors { get { return liftButtonSensors; } } public LiftUpSensor UpSensor { get { return upSensor; } } public LiftDownSensor DownSensor { get { return downSensor; } } public void startLift(int toFloor) { // Sets initial lift direction if ((currentFloor > toFloor) && (toFloor >= 0)) { downSensor.On = true; // Start lift moving down serviceLiftRequests(); } else if ((currentFloor < toFloor) && (toFloor >= 0)) { upSensor.On = true; // Start lift moving up serviceLiftRequests(); } } public void serviceLiftRequests() { // Service all lift requests do { if (upSensor.On) { Thread.Sleep(liftDelay); CurrentPosition -= 2; int f = getFloor(currentPosition); if (f >= 0) CurrentFloor = f; } else if (downSensor.On) { Thread.Sleep(liftDelay); CurrentPosition += 2; int f = getFloor(currentPosition); if (f >= 0) CurrentFloor = f; } } while ((downSensor.On) || (upSensor.On)); // Set lift controller sensor states FloorUpButtonSensors[currentFloor].On = false; FloorDownButtonSensors[currentFloor].On = false; LiftButtonSensors[currentFloor].On = false; } public event sensorStateChangeDelegate SensorStateChangeEvent { add { sensorStateChangeEvent += value; } remove { sensorStateChangeEvent -= value; } } public event positionChangeDelegate PositionChangeEvent { add { positionChangeEvent += value; } remove { positionChangeEvent -= value; } } public void fireStateChangeEvent() { // Fire sensor state change event sensorStateChangeEvent(); } private void newFloor(int floor) { // Update lift direction by checking status of floor and lift buttons above and below bool upEventAbove = false; bool downEventAbove = false; bool upEventBelow = false; bool downEventBelow = false; // Check above for floor buttons events for (int f = (floor + 1); f < numberOfFloors; f++) { upEventAbove = upEventAbove || floorUpButtonSensors[f].On; downEventAbove = downEventAbove || floorDownButtonSensors[f].On; } // Include lift button events for (int f = (floor + 1); f < numberOfFloors; f++) upEventAbove = upEventAbove || liftButtonSensors[f].On; // Check below for floor button events for (int f = (floor - 1); f >= 0; f--) { upEventBelow = upEventBelow || floorUpButtonSensors[f].On; downEventBelow = downEventBelow || floorDownButtonSensors[f].On; } // Include lift button events for (int f = (floor - 1); f >= 0; f--) downEventBelow = downEventBelow || liftButtonSensors[f].On; // Check for no events if (!(upEventAbove || upEventBelow || downEventAbove || downEventBelow)) { upSensor.On = false; downSensor.On = false; return; } if (downSensor.On) { if ((floorDownButtonSensors[floor].On) || (liftButtonSensors[floor].On)) // Will always pause lift and service this request { pauseLift(); // Set lift controller sensor states floorDownButtonSensors[floor].On = false; liftButtonSensors[floor].On = false; if ((floor == 0) && (floorUpButtonSensors[floor].On)) { floorUpButtonSensors[floor].On = false; } // Update direction if ((!(upEventBelow || downEventBelow)) && (upEventAbove || downEventAbove)) { downSensor.On = false; upSensor.On = true; } return; } if (floorUpButtonSensors[floor].On) { // Check to see if there are no more service requests on lower floors if (!(upEventBelow || downEventBelow)) { pauseLift(); // Set lift controller sensor states floorUpButtonSensors[floor].On = false; upSensor.On = true; downSensor.On = false; return; } } } else if (upSensor.On) { if ((floorUpButtonSensors[floor].On) || (liftButtonSensors[floor].On)) // Will always pause lift and service this request { pauseLift(); // Set lift controller sensor states floorUpButtonSensors[floor].On = false; liftButtonSensors[floor].On = false; if ((floor == (numberOfFloors - 1)) && (floorDownButtonSensors[floor].On)) { floorDownButtonSensors[floor].On = false; } // Update direction if ((!(upEventAbove || downEventAbove)) && (upEventBelow || downEventBelow)) { downSensor.On = true; upSensor.On = false; } return; } if (floorDownButtonSensors[floor].On) { // Check to see if there are no more service requests on upper floors if (!(upEventAbove || downEventAbove)) { pauseLift(); // Set lift controller sensor states floorDownButtonSensors[floor].On = false; upSensor.On = false; downSensor.On = true; return; } } } } private void pauseLift() { Thread.Sleep(3000); } private int getFloor(int position) { for (int f = 0; f < numberOfFloors; f++) if (position == floorPositions[f]) return f; return -1; } private event sensorStateChangeDelegate sensorStateChangeEvent; private event positionChangeDelegate positionChangeEvent; private int numberOfFloors, currentFloor; private int[] floorPositions; private int currentPosition; private int liftDelay; private LiftUpSensor upSensor; private LiftDownSensor downSensor; private FloorButtonSensor[] floorUpButtonSensors, floorDownButtonSensors; private LiftButtonSensor[] liftButtonSensors; } public class LiftStateSensor { private bool on; private LiftController liftController; public LiftStateSensor(LiftController lc) { on = false; liftController = lc; } public bool On { get { return on; } set { if (on != value) { on = value; sensorStateChangeEvent(); } } } public void sensorStateChangeEvent() { liftController.fireStateChangeEvent(); } } public class FloorButtonSensor:LiftStateSensor { private int floor; private Direction direction; public FloorButtonSensor(int f, Direction d, LiftController lc):base(lc) { floor = f; direction = d; } } public class LiftButtonSensor:LiftStateSensor { private int floor; public LiftButtonSensor(int f, LiftController lc):base(lc) { floor = f; } } public class LiftUpSensor:LiftStateSensor { public LiftUpSensor(LiftController lc) : base(lc) {} } public class LiftDownSensor : LiftStateSensor { public LiftDownSensor(LiftController lc) : base(lc) {} } }