示例#1
0
文件: load.cpp 项目: DwBu/frePPLe
DECLARE_EXPORT Load::~Load()
{
  // Set a flag to make sure the level computation is triggered again
  HasLevel::triggerLazyRecomputation();

  // Delete existing loadplans
  if (getOperation() && getResource())
  {
    // Loop over operationplans
    for(OperationPlan::iterator i(getOperation()); i != OperationPlan::end(); ++i)
      // Loop over loadplans
      for(OperationPlan::LoadPlanIterator j = i->beginLoadPlans(); j != i->endLoadPlans(); )
        if (j->getLoad() == this) j.deleteLoadPlan();
        else ++j;
  }

  // Delete the load from the operation and resource
  if (getOperation())
    getOperation()->loaddata.erase(this);
  if (getResource())
    getResource()->loads.erase(this);
}
示例#2
0
DECLARE_EXPORT Load::~Load()
{
  // Set a flag to make sure the level computation is triggered again
  HasLevel::triggerLazyRecomputation();

  // Delete existing loadplans
  if (getOperation() && getResource())
  {
    // Loop over operationplans
    for(OperationPlan::iterator i(getOperation()); i != OperationPlan::end(); ++i)
      // Loop over loadplans
      for(OperationPlan::LoadPlanIterator j = i->beginLoadPlans(); j != i->endLoadPlans(); )
        if (j->getLoad() == this) j.deleteLoadPlan();
        else ++j;
  }

  // Delete the load from the operation and resource
  if (getOperation()) getOperation()->loaddata.erase(this);
  if (getResource()) getResource()->loads.erase(this);

  // Clean up alternate loads
  if (hasAlts)
  {
    // The load has alternates.
    // Make a new load the leading one. Or if there is only one alternate
    // present it is not marked as an alternate any more.
    unsigned short cnt = 0;
    int minprio = INT_MAX;
    Load* newLeader = NULL;
    for (Operation::loadlist::iterator i = getOperation()->loaddata.begin();
        i != getOperation()->loaddata.end(); ++i)
      if (i->altLoad == this)
      {
        cnt++;
        if (i->priority < minprio)
        {
          newLeader = &*i;
          minprio = i->priority;
        }
      }
    if (cnt < 1)
      throw LogicException("Alternate loads update failure");
    else if (cnt == 1)
      // No longer an alternate any more
      newLeader->altLoad = NULL;
    else
    {
      // Mark a new leader load
      newLeader->hasAlts = true;
      newLeader->altLoad = NULL;
      for (Operation::loadlist::iterator i = getOperation()->loaddata.begin();
          i != getOperation()->loaddata.end(); ++i)
        if (i->altLoad == this) i->altLoad = newLeader;
    }
  }
  if (altLoad)
  {
    // The load is an alternate of another one.
    // If it was the only alternate, then the hasAlts flag on the parent
    // load needs to be set back to false
    bool only_one = true;
    for (Operation::loadlist::iterator i = getOperation()->loaddata.begin();
        i != getOperation()->loaddata.end(); ++i)
      if (i->altLoad == altLoad)
      {
        only_one = false;
        break;
      }
    if (only_one) altLoad->hasAlts = false;
  }
}
示例#3
0
DECLARE_EXPORT void LoadPlan::setResource(Resource* newres, bool check)
{
  // Nothing to do
  if (res == newres) return;

  // Validate the argument
  if (!newres) throw DataException("Can't switch to NULL resource");
  if (check)
  {
    // New resource must be a subresource of the load's resource.
    bool ok = false;
    for (const Resource* i = newres; i && !ok; i = i->getOwner())
      if (i == getLoad()->getResource()) ok = true;
    if (!ok)
      throw DataException("Resource isn't matching the resource specified on the load");

    // New resource must have the required skill
    if (getLoad()->getSkill())
    {
      ok = false;
      for(Resource::skilllist::const_iterator s = newres->getSkills().begin();
        s != newres->getSkills().end() && !ok; s++)
        if (s->getSkill() == getLoad()->getSkill()) ok = true;
      if (!ok)
        throw DataException("Resource misses the skill specified on the load");
    }
  }

  // Mark entities as changed
  if (oper) oper->getOperation()->setChanged();
  if (res && res!=newres) res->setChanged();
  newres->setChanged();

  // Update also the setup operationplans
  if (oper && oper->getOperation() != OperationSetup::setupoperation)
  {
    bool oldHasSetup = ld && !ld->getSetup().empty()  // TODO not fully correct. If the load is changed, it is still possible that the old load had a setup, while ld doesn't have one any more...
        && res && res->getSetupMatrix();
    bool newHasSetup = ld && !ld->getSetup().empty()
        && newres->getSetupMatrix();
    OperationPlan *setupOpplan = NULL;
    if (oldHasSetup)
    {
      for (OperationPlan::iterator i(oper); i != oper->end(); ++i)
        if (i->getOperation() == OperationSetup::setupoperation)
        {
          setupOpplan = &*i;
          break;
        }
      if (!setupOpplan) oldHasSetup = false;
    }
    if (oldHasSetup)
    {
      if (newHasSetup)
      {
        // Case 1: Both the old and new load require a setup
        LoadPlan *setupLdplan = NULL;
        for (OperationPlan::LoadPlanIterator j = setupOpplan->beginLoadPlans();
            j != setupOpplan->endLoadPlans(); ++j)
          if (j->getLoad() == ld)
          {
            setupLdplan = &*j;
            break;
          }
        if (!setupLdplan)
          throw LogicException("Can't find loadplan on setup operationplan");
        // Update the loadplan
        setupOpplan->setEnd(setupOpplan->getDates().getEnd());
      }
      else
      {
        // Case 2: Delete the old setup which is not required any more
        oper->eraseSubOperationPlan(setupOpplan);
      }
    }
    else
    {
      if (newHasSetup)
      {
        // Case 3: Create a new setup operationplan
        OperationSetup::setupoperation->createOperationPlan(
          1, Date::infinitePast, oper->getDates().getEnd(), NULL, oper);
      }
      //else:
      // Case 4: No setup for the old or new load
    }
  }

  // Find the loadplan before the setup
  LoadPlan *prevldplan = NULL;
  if (getOperationPlan()->getOperation() == OperationSetup::setupoperation)
  {
    for (TimeLine<LoadPlan>::const_iterator i = getResource()->getLoadPlans().begin(isStart() ? getOtherLoadPlan() : this);
        i != getResource()->getLoadPlans().end(); --i)
    {
      const LoadPlan *l = dynamic_cast<const LoadPlan*>(&*i);
      if (l && l->getOperationPlan() != getOperationPlan()
          && l->getOperationPlan() != getOperationPlan()->getOwner()
          && !l->isStart())
      {
        prevldplan = const_cast<LoadPlan*>(l);
        break;
      }
    }
    if (!prevldplan)
    {
      for (TimeLine<LoadPlan>::const_iterator i = getResource()->getLoadPlans().begin(isStart() ? getOtherLoadPlan() : this);
          i != getResource()->getLoadPlans().end(); ++i)
      {
        const LoadPlan *l = dynamic_cast<const LoadPlan*>(&*i);
        if (l && l->getOperationPlan() != getOperationPlan()
            && l->getOperationPlan() != getOperationPlan()->getOwner()
            && !l->isStart())
        {
          prevldplan = const_cast<LoadPlan*>(l);
          break;
        }
      }
    }
  }

  // Change this loadplan and its brother
  for (LoadPlan *ldplan = getOtherLoadPlan(); true; )
  {
    // Remove from the old resource, if there is one
    if (res)
    {
      res->loadplans.erase(ldplan);
      res->setChanged();
    }

    // Insert in the new resource.
    // This code assumes the date and quantity of the loadplan don't change
    // when a new resource is assigned.
    ldplan->res = newres;
    newres->loadplans.insert(
      ldplan,
      ld->getLoadplanQuantity(ldplan),
      ld->getLoadplanDate(ldplan)
    );

    // Repeat for the brother loadplan or exit
    if (ldplan != this) ldplan = this;
    else break;
  }

  // Update the setups on the old resource
  if (prevldplan) prevldplan->res->updateSetups(prevldplan);

  // Change the resource
  newres->setChanged();
}