loadplan.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #define FREPPLE_CORE
00029 #include "frepple/model.h"
00030
00031 namespace frepple
00032 {
00033
00034 DECLARE_EXPORT const MetaCategory* LoadPlan::metadata;
00035
00036
00037 int LoadPlan::initialize()
00038 {
00039
00040 metadata = new MetaCategory("loadplan", "loadplans");
00041
00042
00043 PythonType& x = FreppleCategory<LoadPlan>::getType();
00044 x.setName("loadplan");
00045 x.setDoc("frePPLe loadplan");
00046 x.supportgetattro();
00047 const_cast<MetaCategory*>(metadata)->pythonClass = x.type_object();
00048 return x.typeReady();
00049 }
00050
00051
00052 DECLARE_EXPORT LoadPlan::LoadPlan(OperationPlan *o, const Load *r)
00053 {
00054 assert(o);
00055 ld = const_cast<Load*>(r);
00056 oper = o;
00057 start_or_end = START;
00058
00059
00060 nextLoadPlan = NULL;
00061 if (o->firstloadplan)
00062 {
00063
00064 LoadPlan *c = o->firstloadplan;
00065 while (c->nextLoadPlan) c = c->nextLoadPlan;
00066 c->nextLoadPlan = this;
00067 }
00068 else
00069
00070 o->firstloadplan = this;
00071
00072
00073 r->getResource()->loadplans.insert(
00074 this,
00075 ld->getLoadplanQuantity(this),
00076 ld->getLoadplanDate(this)
00077 );
00078
00079
00080 initType(metadata);
00081
00082
00083 new LoadPlan(o, r, this);
00084
00085
00086
00087 r->getResource()->setChanged();
00088 r->getOperation()->setChanged();
00089 }
00090
00091
00092 DECLARE_EXPORT LoadPlan::LoadPlan(OperationPlan *o, const Load *r, LoadPlan *lp)
00093 {
00094 ld = const_cast<Load*>(r);
00095 oper = o;
00096 start_or_end = END;
00097
00098
00099 nextLoadPlan = NULL;
00100 if (o->firstloadplan)
00101 {
00102
00103 LoadPlan *c = o->firstloadplan;
00104 while (c->nextLoadPlan) c = c->nextLoadPlan;
00105 c->nextLoadPlan = this;
00106 }
00107 else
00108
00109 o->firstloadplan = this;
00110
00111
00112 r->getResource()->loadplans.insert(
00113 this,
00114 ld->getLoadplanQuantity(this),
00115 ld->getLoadplanDate(this)
00116 );
00117
00118
00119 initType(metadata);
00120 }
00121
00122
00123 DECLARE_EXPORT LoadPlan* LoadPlan::getOtherLoadPlan() const
00124 {
00125 for (LoadPlan *i = oper->firstloadplan; i; i = i->nextLoadPlan)
00126 if (i->ld == ld && i != this) return i;
00127 throw LogicException("No matching loadplan found");
00128 }
00129
00130
00131 DECLARE_EXPORT void LoadPlan::update()
00132 {
00133
00134 ld->getResource()->getLoadPlans().update(
00135 this,
00136 ld->getLoadplanQuantity(this),
00137 ld->getLoadplanDate(this)
00138 );
00139
00140
00141 if (!isStart()) ld->getResource()->updateSetups(this);
00142
00143
00144
00145 ld->getResource()->setChanged();
00146 ld->getOperation()->setChanged();
00147 }
00148
00149
00150 DECLARE_EXPORT const string& LoadPlan::getSetup(bool current) const
00151 {
00152
00153 static string nosetup;
00154 assert(ld);
00155 if (!ld->getResource()->getSetupMatrix()) return nosetup;
00156
00157
00158 if (!ld->getSetup().empty() && current) return ld->getSetup();
00159
00160
00161 for (Resource::loadplanlist::const_iterator i(this);
00162 i != getResource()->getLoadPlans().end(); --i)
00163 {
00164 const LoadPlan* j = dynamic_cast<const LoadPlan*>(&*i);
00165 if (j && !j->getLoad()->getSetup().empty() && (current || j != this))
00166 return j->getLoad()->getSetup();
00167 }
00168
00169
00170 return ld->getResource()->getSetup();
00171 }
00172
00173
00174 DECLARE_EXPORT LoadPlan::~LoadPlan()
00175 {
00176 ld->getResource()->setChanged();
00177 LoadPlan *prevldplan = NULL;
00178 if (!isStart() && oper->getOperation() == OperationSetup::setupoperation)
00179 {
00180 for (TimeLine<LoadPlan>::const_iterator i = getResource()->getLoadPlans().begin(isStart() ? getOtherLoadPlan() : this);
00181 i != getResource()->getLoadPlans().end(); --i)
00182 {
00183 const LoadPlan *l = dynamic_cast<const LoadPlan*>(&*i);
00184 if (l && l->getOperationPlan() != getOperationPlan()
00185 && l->getOperationPlan() != getOperationPlan()->getOwner()
00186 && !l->isStart())
00187 {
00188 prevldplan = const_cast<LoadPlan*>(l);
00189 break;
00190 }
00191 }
00192 if (!prevldplan)
00193 {
00194 for (TimeLine<LoadPlan>::const_iterator i = getResource()->getLoadPlans().begin(isStart() ? getOtherLoadPlan() : this);
00195 i != getResource()->getLoadPlans().end(); ++i)
00196 {
00197 const LoadPlan *l = dynamic_cast<const LoadPlan*>(&*i);
00198 if (l && l->getOperationPlan() != getOperationPlan()
00199 && l->getOperationPlan() != getOperationPlan()->getOwner()
00200 && !l->isStart())
00201 {
00202 prevldplan = const_cast<LoadPlan*>(l);
00203 break;
00204 }
00205 }
00206 }
00207 }
00208 ld->getResource()->loadplans.erase(this);
00209 if (prevldplan) ld->getResource()->updateSetups(prevldplan);
00210 }
00211
00212
00213 DECLARE_EXPORT void LoadPlan::setLoad(const Load* newld)
00214 {
00215
00216 if (newld == ld) return;
00217
00218
00219 if (!newld) throw LogicException("Can't switch to NULL load");
00220 if (ld && ld->getOperation() != newld->getOperation())
00221 throw LogicException("Only switching to a load on the same operation is allowed");
00222
00223
00224 if (oper) oper->getOperation()->setChanged();
00225 if (ld) ld->getResource()->setChanged();
00226 newld->getResource()->setChanged();
00227
00228
00229 if (oper && oper->getOperation() != OperationSetup::setupoperation)
00230 {
00231 bool oldHasSetup = ld && !ld->getSetup().empty()
00232 && ld->getResource()->getSetupMatrix();
00233 bool newHasSetup = !newld->getSetup().empty()
00234 && newld->getResource()->getSetupMatrix();
00235 OperationPlan *setupOpplan = NULL;
00236 if (oldHasSetup)
00237 {
00238 for (OperationPlan::iterator i(oper); i != oper->end(); ++i)
00239 if (i->getOperation() == OperationSetup::setupoperation)
00240 {
00241 setupOpplan = &*i;
00242 break;
00243 }
00244 if (!setupOpplan) oldHasSetup = false;
00245 }
00246 if (oldHasSetup)
00247 {
00248 if (newHasSetup)
00249 {
00250
00251 LoadPlan *setupLdplan = NULL;
00252 for (OperationPlan::LoadPlanIterator j = setupOpplan->beginLoadPlans();
00253 j != setupOpplan->endLoadPlans(); ++j)
00254 if (j->getLoad() == ld)
00255 {
00256 setupLdplan = &*j;
00257 break;
00258 }
00259 if (!setupLdplan)
00260 throw LogicException("Can't find loadplan on setup operationplan");
00261
00262 setupLdplan->setLoad(newld);
00263 setupOpplan->setEnd(setupOpplan->getDates().getEnd());
00264 }
00265 else
00266 {
00267
00268 oper->eraseSubOperationPlan(setupOpplan);
00269 }
00270 }
00271 else
00272 {
00273 if (newHasSetup)
00274 {
00275
00276 OperationSetup::setupoperation->createOperationPlan(
00277 1, Date::infinitePast, oper->getDates().getEnd(), NULL, oper);
00278 }
00279
00280
00281 }
00282 }
00283
00284
00285 LoadPlan *prevldplan = NULL;
00286 if (getOperationPlan()->getOperation() == OperationSetup::setupoperation)
00287 {
00288 for (TimeLine<LoadPlan>::const_iterator i = getResource()->getLoadPlans().begin(isStart() ? getOtherLoadPlan() : this);
00289 i != getResource()->getLoadPlans().end(); --i)
00290 {
00291 const LoadPlan *l = dynamic_cast<const LoadPlan*>(&*i);
00292 if (l && l->getOperationPlan() != getOperationPlan()
00293 && l->getOperationPlan() != getOperationPlan()->getOwner()
00294 && !l->isStart())
00295 {
00296 prevldplan = const_cast<LoadPlan*>(l);
00297 break;
00298 }
00299 }
00300 if (!prevldplan)
00301 {
00302 for (TimeLine<LoadPlan>::const_iterator i = getResource()->getLoadPlans().begin(isStart() ? getOtherLoadPlan() : this);
00303 i != getResource()->getLoadPlans().end(); ++i)
00304 {
00305 const LoadPlan *l = dynamic_cast<const LoadPlan*>(&*i);
00306 if (l && l->getOperationPlan() != getOperationPlan()
00307 && l->getOperationPlan() != getOperationPlan()->getOwner()
00308 && !l->isStart())
00309 {
00310 prevldplan = const_cast<LoadPlan*>(l);
00311 break;
00312 }
00313 }
00314 }
00315 }
00316
00317
00318 for (LoadPlan *ldplan = getOtherLoadPlan(); true; )
00319 {
00320
00321 if (ldplan->ld)
00322 ldplan->ld->getResource()->loadplans.erase(ldplan);
00323
00324
00325 ldplan->ld = newld;
00326 newld->getResource()->loadplans.insert(
00327 ldplan,
00328 newld->getLoadplanQuantity(ldplan),
00329 newld->getLoadplanDate(ldplan)
00330 );
00331
00332
00333 if (ldplan != this) ldplan = this;
00334 else break;
00335 }
00336
00337
00338 if (prevldplan)
00339 prevldplan->ld->getResource()->updateSetups(prevldplan);
00340 }
00341
00342
00343 PyObject* LoadPlan::getattro(const Attribute& attr)
00344 {
00345 if (attr.isA(Tags::tag_operationplan))
00346 return PythonObject(getOperationPlan());
00347 if (attr.isA(Tags::tag_quantity))
00348 return PythonObject(getQuantity());
00349 if (attr.isA(Tags::tag_startdate))
00350 return PythonObject(getDate());
00351 if (attr.isA(Tags::tag_enddate))
00352 return PythonObject(getOtherLoadPlan()->getDate());
00353 if (attr.isA(Tags::tag_resource))
00354 return PythonObject(getLoad()->getResource());
00355 if (attr.isA(Tags::tag_load))
00356 return PythonObject(getLoad());
00357 if (attr.isA(Tags::tag_setup))
00358 return PythonObject(getSetup());
00359 return NULL;
00360 }
00361
00362
00363 int LoadPlanIterator::initialize()
00364 {
00365
00366 PythonType& x = PythonExtension<LoadPlanIterator>::getType();
00367 x.setName("loadplanIterator");
00368 x.setDoc("frePPLe iterator for loadplan");
00369 x.supportiter();
00370 return x.typeReady();
00371 }
00372
00373
00374 PyObject* LoadPlanIterator::iternext()
00375 {
00376 LoadPlan* ld;
00377 if (resource_or_opplan)
00378 {
00379
00380 while (*resiter != res->getLoadPlans().end() && (*resiter)->getQuantity()<=0.0)
00381 ++(*resiter);
00382 if (*resiter == res->getLoadPlans().end()) return NULL;
00383
00384
00385 ld = const_cast<LoadPlan*>(static_cast<const LoadPlan*>(&*((*resiter)++)));
00386 }
00387 else
00388 {
00389 while (*opplaniter != opplan->endLoadPlans() && (*opplaniter)->getQuantity()==0.0)
00390 ++(*opplaniter);
00391 if (*opplaniter == opplan->endLoadPlans()) return NULL;
00392 ld = static_cast<LoadPlan*>(&*((*opplaniter)++));
00393 }
00394 Py_INCREF(ld);
00395 return const_cast<LoadPlan*>(ld);
00396 }
00397
00398 }