Last active
January 14, 2016 16:05
-
-
Save meetwudi/bc63370afd912a86e6cd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
init: function(elevators, floors) { | |
function Tour (pickupRequest, direction, startFloorNum) { | |
this.pickingUp = !!pickupRequest; | |
this.pickupRequest = pickupRequest; | |
this.direction = direction; // either 'up' or 'down' | |
this.startFloorNum = startFloorNum; | |
} | |
function Controller (elevator) { | |
var currentController = this; | |
this.elevator = elevator; | |
this.tour = null; | |
this.elevator.on('stopped_at_floor', function (floorNum) { | |
console.log('stopped at floor: ', floorNum); | |
console.log('when stopped, destinationQueue: ', currentController.elevator.destinationQueue); | |
if (currentController.tour | |
&& currentController.elevator.destinationQueue.length === 0 | |
&& floorNum != currentController.tour.startFloorNum) { | |
currentController.finishTour(); | |
} | |
}); | |
this.elevator.on('idle', function () { | |
console.log('idle'); | |
if (currentController.tour) { | |
currentController.finishTour(); | |
} | |
}); | |
this.elevator.on('floor_button_pressed', function (floorNum) { | |
currentController.goToFloor(floorNum); | |
}); | |
} | |
Controller.prototype.canAcceptExternalRequest = function (request) { | |
return !(this.tour | |
&& this.tour.direction === 'up' | |
&& this.elevator.currentFloor() >= request.floorNum) | |
&& !(this.tour | |
&& this.tour.direction === 'down' | |
&& this.elevator.currentFloor() <= request.floorNum) | |
&& !(this.tour | |
&& this.tour.direction === 'up' | |
&& request.direction === 'down') | |
&& !(this.tour | |
&& this.tour.direction === 'down' | |
&& request.direction === 'up') | |
&& !(this.elevator.loadFactor() === 1.0) | |
&& !(this.tour | |
&& this.elevator.currentFloor === request.floorNum); | |
}; | |
Controller.prototype.goToFloor = function (floorNum) { | |
this.elevator.goToFloor(floorNum); | |
this.rearrangeDestinations(); | |
}; | |
Controller.prototype.rearrangeDestinations = function () { | |
var currentController = this; | |
if (currentController.tour) { | |
this.elevator.destinationQueue.sort( | |
function (lhs, rhs) { | |
return currentController.tour.direction === 'up' ? lhs > rhs : lhs < rhs; | |
}); | |
this.elevator.checkDestinationQueue(); | |
} | |
}; | |
Controller.prototype.acceptExternalRequest = function (request) { | |
var currentFloor = this.elevator.currentFloor(); | |
if (this.tour) { | |
// The request is going to join the tour | |
this.goToFloor(request.floorNum); | |
} | |
else { | |
// The request is going to start a new tour | |
if (request.floorNum !== currentFloor) { | |
console.log('start a new pick up tour'); | |
this.startTour(new Tour(request, | |
request.floorNum > currentFloor ? 'up' : 'down', | |
currentFloor)); | |
this.goToFloor(request.floorNum); | |
} | |
else { | |
console.log('start a new tour'); | |
this.startTour(new Tour(null, request.direction, currentFloor)); | |
} | |
} | |
}; | |
Controller.prototype.startTour = function (tour) { | |
console.log('tour start', tour); | |
this.tour = tour; | |
this.elevator.goingUpIndicator(tour.direction === 'up'); | |
this.elevator.goingDownIndicator(tour.direction === 'down'); | |
} | |
Controller.prototype.finishTour = function () { | |
var currentController = this; | |
console.log('tour finished'); | |
if (this.tour.pickingUp) { | |
setTimeout(function () { | |
currentController.startTour(new Tour(null, | |
currentController.tour.pickupRequest.direction, | |
currentController.elevator.currentFloor())); | |
currentController.goToFloor( | |
currentController.elevator.currentFloor()) | |
}, 0); | |
} | |
else { | |
this.elevator.goingUpIndicator(false); | |
this.elevator.goingDownIndicator(false); | |
this.tour = null; | |
} | |
}; | |
Controller.prototype.evaluatePriorityIndex = function (request) { | |
return - 1 * this.elevator.loadFactor() - | |
Math.abs(this.elevator.currentFloor() - request.floorNum); | |
}; | |
function ExternalRequest (floorNum, direction) { | |
this.floorNum = floorNum; | |
this.direction = direction; | |
} | |
function Scheduler (elevators, floors) { | |
var currentScheduler = this; | |
this.controllers = elevators.map(function (elevator) { | |
return new Controller(elevator); | |
}); | |
this.requestPoll = []; | |
floors.forEach(function (floor) { | |
floor.on('up_button_pressed', function () { | |
console.log('up_button_pressed'); | |
setTimeout(function () { | |
currentScheduler.dispatchExternalRequest(new ExternalRequest( | |
floor.floorNum(), 'up')); | |
}, 500); | |
}); | |
floor.on('down_button_pressed', function () { | |
console.log('down_button_pressed'); | |
setTimeout(function () { | |
currentScheduler.dispatchExternalRequest(new ExternalRequest( | |
floor.floorNum(), 'down')) | |
}, 500); | |
}); | |
}); | |
setTimeout(function drainPolledRequests() { | |
var requestPollClone = currentScheduler.requestPoll.map(function (_) { | |
return _; | |
}); | |
currentScheduler.requestPoll = []; | |
while (requestPollClone.length > 0) { | |
currentScheduler.dispatchExternalRequest( | |
requestPollClone.pop()); | |
} | |
// I just don't like setInterval | |
setTimeout(drainPolledRequests, 13); | |
}, 13); | |
} | |
Scheduler.prototype.dispatchExternalRequest = function (request) { | |
var viableControllers = this.controllers.filter(function (controller) { | |
return controller.canAcceptExternalRequest(request); | |
}).map(function (controller) { | |
return { | |
// The higher the priorityIndex the higher the priority | |
priorityIndex: controller.evaluatePriorityIndex(request), | |
controller: controller | |
}; | |
}).sort(function (lhs, rhs) { | |
return lhs.priorityIndex > rhs.priorityIndex; // descending order | |
}).map(function (_) { | |
return _.controller; | |
}); | |
if (!viableControllers.length) { | |
this.pollExternalRequest(request); | |
return; | |
} | |
var chosenController = viableControllers[0]; | |
chosenController.acceptExternalRequest(request); | |
}; | |
Scheduler.prototype.pollExternalRequest = function (request) { | |
this.requestPoll.push(request); | |
}; | |
new Scheduler(elevators, floors); | |
}, | |
update: function(dt, elevators, floors) { | |
// We normally don't need to do anything here | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment