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* PeggingIterator::metadata;
00035
00036
00037 int PeggingIterator::initialize()
00038 {
00039
00040 PeggingIterator::metadata = new MetaCategory("pegging","peggings");
00041
00042
00043 PythonType& x = PythonExtension<PeggingIterator>::getType();
00044 x.setName("peggingIterator");
00045 x.setDoc("frePPLe iterator for demand pegging");
00046 x.supportgetattro();
00047 x.supportiter();
00048 const_cast<MetaCategory*>(PeggingIterator::metadata)->pythonClass = x.type_object();
00049 return x.typeReady();
00050 }
00051
00052
00053 DECLARE_EXPORT PeggingIterator::PeggingIterator(const Demand* d)
00054 : downstream(false), firstIteration(true)
00055 {
00056
00057 first = false;
00058 for (Demand::OperationPlan_list::const_iterator opplaniter = d->getDelivery().begin();
00059 opplaniter != d->getDelivery().end(); ++opplaniter)
00060 followPegging(*opplaniter, 0, (*opplaniter)->getQuantity(), 1.0);
00061
00062
00063 initType(metadata);
00064 }
00065
00066
00067 DECLARE_EXPORT void PeggingIterator::updateStack
00068 (short l, double q, double f, const FlowPlan* fc, const FlowPlan* fp, bool p)
00069 {
00070
00071 if (q < 0.1) return;
00072
00073 if (first)
00074 {
00075
00076 state& t = states.top();
00077 t.cons_flowplan = fc;
00078 t.prod_flowplan = fp;
00079 t.qty = q;
00080 t.factor = f;
00081 t.level = l;
00082 t.pegged = p;
00083 first = false;
00084 }
00085 else
00086
00087 states.push(state(l, q, f, fc, fp, p));
00088 }
00089
00090
00091 DECLARE_EXPORT PeggingIterator& PeggingIterator::operator++()
00092 {
00093
00094 if (states.empty())
00095 throw LogicException("Incrementing the iterator beyond it's end");
00096 if (!downstream)
00097 throw LogicException("Incrementing a downstream iterator");
00098 state& st = states.top();
00099
00100
00101 if (!st.pegged)
00102 {
00103 states.pop();
00104 return *this;
00105 }
00106
00107
00108 first = true;
00109
00110
00111 if (st.cons_flowplan)
00112 followPegging(st.cons_flowplan->getOperationPlan()->getTopOwner(),
00113 st.level-1, st.qty, st.factor);
00114
00115
00116 if (first) states.pop();
00117
00118 return *this;
00119 }
00120
00121
00122 DECLARE_EXPORT PeggingIterator& PeggingIterator::operator--()
00123 {
00124
00125 if (states.empty())
00126 throw LogicException("Incrementing the iterator beyond it's end");
00127 if (downstream)
00128 throw LogicException("Decrementing an upstream iterator");
00129 state& st = states.top();
00130
00131
00132 if (!st.pegged)
00133 {
00134 states.pop();
00135 return *this;
00136 }
00137
00138
00139 first = true;
00140
00141
00142 if (st.prod_flowplan)
00143 followPegging(st.prod_flowplan->getOperationPlan()->getTopOwner(),
00144 st.level+1, st.qty, st.factor);
00145
00146
00147 if (first) states.pop();
00148
00149 return *this;
00150 }
00151
00152
00153 DECLARE_EXPORT void PeggingIterator::followPegging
00154 (const OperationPlan* op, short nextlevel, double qty, double factor)
00155 {
00156
00157
00158 bool noFlowPlans = true;
00159 if (downstream)
00160 for (OperationPlan::FlowPlanIterator i = op->beginFlowPlans();
00161 i != op->endFlowPlans(); ++i)
00162 {
00163
00164
00165 if (i->getQuantity()>ROUNDING_ERROR)
00166 {
00167 i->getFlow()->getBuffer()->followPegging(*this, &*i, nextlevel, qty, factor);
00168 noFlowPlans = false;
00169 }
00170 }
00171 else
00172 for (OperationPlan::FlowPlanIterator i = op->beginFlowPlans();
00173 i != op->endFlowPlans(); ++i)
00174 {
00175
00176
00177 if (i->getQuantity()<-ROUNDING_ERROR)
00178 {
00179 i->getFlow()->getBuffer()->followPegging(*this, &*i, nextlevel, qty, factor);
00180 noFlowPlans = false;
00181 }
00182 }
00183
00184
00185
00186
00187
00188 for (OperationPlan::iterator j(op); j != OperationPlan::end(); ++j)
00189 followPegging(&*j, nextlevel, qty, factor);
00190 }
00191
00192
00193 DECLARE_EXPORT PyObject* PeggingIterator::iternext()
00194 {
00195 if (firstIteration)
00196 firstIteration = false;
00197 else
00198 operator--();
00199 if (!operator bool()) return NULL;
00200 Py_INCREF(this);
00201 return static_cast<PyObject*>(this);
00202 }
00203
00204
00205 DECLARE_EXPORT PyObject* PeggingIterator::getattro(const Attribute& attr)
00206 {
00207 if (attr.isA(Tags::tag_level))
00208 return PythonObject(getLevel());
00209 if (attr.isA(Tags::tag_consuming))
00210 return PythonObject(getConsumingOperationplan());
00211 if (attr.isA(Tags::tag_producing))
00212 return PythonObject(getProducingOperationplan());
00213 if (attr.isA(Tags::tag_buffer))
00214 return PythonObject(getBuffer());
00215 if (attr.isA(Tags::tag_quantity_demand))
00216 return PythonObject(getQuantityDemand());
00217 if (attr.isA(Tags::tag_quantity_buffer))
00218 return PythonObject(getQuantityBuffer());
00219 if (attr.isA(Tags::tag_pegged))
00220 return PythonObject(getPegged());
00221 if (attr.isA(Tags::tag_consuming_date))
00222 return PythonObject(getConsumingDate());
00223 if (attr.isA(Tags::tag_producing_date))
00224 return PythonObject(getProducingDate());
00225 return NULL;
00226 }
00227
00228
00229 }