void SegmentReactor::onActiveShipmentNew(Shipment::Ptr _ptr) { Activity::Ptr forwardActivity_ = activityManagerInstance()->activityNew(_ptr->name()); ForwardActivityReactor * reactor = new ForwardActivityReactor(forwardActivity_, fleet_, stats_, notifier(), _ptr); float speed = 1; float length = segment_->length().value(); // Truck segment TruckSegment* truckPtr = dynamic_cast<TruckSegment *>(segment_.ptr()); if (truckPtr) speed = fleet_->truckSpeed().value(); // Boat segment BoatSegment* boatPtr = dynamic_cast<BoatSegment *>(segment_.ptr()); if (boatPtr) speed = fleet_->boatSpeed().value(); // Plane segment PlaneSegment* planePtr = dynamic_cast<PlaneSegment *>(segment_.ptr()); if (planePtr) speed = fleet_->planeSpeed().value(); int numPackages = _ptr->numPackages().value(); int capacity = segment_->capacity().value(); int numTrips = ceil((float)numPackages/(float)capacity); forwardActivity_->nextTimeIs(activityManagerInstance()->now().value() + (float)numTrips*length/speed); forwardActivity_->lastNotifieeIs(reactor); forwardActivity_->statusIs(Activity::queued); }
void Segment::queuedShipmentIs(Shipment::Ptr _ptr) { if(activeShipments() < (U32)capacity_.value()) { activeShipmentIs(_ptr); } else if (this->queuedShipment(_ptr->name()) == NULL) { shipmentQueue_.push_back(_ptr); ++shipmentsRefused_; } }
void Segment::readyForShipmentIs(bool b) { if (b == false || shipmentQ_.empty()) return; Activity::Manager::Ptr manager = activityManagerInstance(); string name = "forward shipment #"; ostringstream oss; oss << rand() << rand() << rand(); name.append(oss.str()); Activity::Ptr fwd = manager->activityNew(name); ShipmentQueue shipments; NumVehicles currentVehicles(capacity()); Fleet::Ptr fleet = engine_->fleet(); NumPackages vehicleCapacity(fleet->capacity(mode()).value()); NumPackages totalCapacity( currentVehicles.value() * vehicleCapacity.value()); NumPackages packageCount(0); NumVehicles vehicles(0); Dollar costPerTrip = this->length().value()*this->difficulty().value()*fleet->speed(mode()).value(); for (Shipment::Ptr s = shipmentQ_.front(); !shipmentQ_.empty() && packageCount < totalCapacity; ) { NumPackages load = s->load(); if (load.value() > totalCapacity.value()) { // split shipment ++shipmentsFragmented_; s->loadIs(load.value() - totalCapacity.value()); load = totalCapacity; shipmentQ_.push_front( Shipment::ShipmentNew( s->name(), s->source(), s->destination(), s->origSize(), load, s->timeShipped() )); } // now we're guaranteed to have at least one shipment at the // front of the queue that we can send off Shipment::Ptr shipment = shipmentQ_.front(); shipment->costIs(shipment->cost().value() + costPerTrip.value()); shipments.push_front(shipment); shipmentQ_.pop_front(); packageCount = packageCount.value() + load.value(); totalCapacity = totalCapacity.value() - load.value(); } vehicles = packageCount.value() / vehicleCapacity.value() + ((packageCount.value() % vehicleCapacity.value() > 0) ? 1 : 0); capacity_ = capacity_.value() - vehicles.value(); fwd->lastNotifieeIs(new ForwardShipmentReactor(manager, fwd.ptr(), 0, this, shipments, vehicles)); Time timeTaken = this->length().value() / fleet->speed(mode()).value(); fwd->nextTimeIs(manager->now().value() + timeTaken.value()); fwd->statusIs(Activity::nextTimeScheduled); }
void Segment::activeShipmentIs(Shipment::Ptr _ptr) { ++shipmentsReceived_; Fwk::String name = _ptr->name(); Shipment::Ptr m = activeShipment_[name]; if(m) { throw Fwk::NameInUseException(name); } else { m = _ptr; activeShipment_.newMember(m); } if(notifiee_) { try { notifiee_->onActiveShipmentNew(_ptr); } catch(...) {} } }