Chain.cpp
1 /*---------------------------------------------------------------------------*\
2  *
3  * mimmo
4  *
5  * Copyright (C) 2015-2021 OPTIMAD engineering Srl
6  *
7  * -------------------------------------------------------------------------
8  * License
9  * This file is part of mimmo.
10  *
11  * mimmo is free software: you can redistribute it and/or modify it
12  * under the terms of the GNU Lesser General Public License v3 (LGPL)
13  * as published by the Free Software Foundation.
14  *
15  * mimmo is distributed in the hope that it will be useful, but WITHOUT
16  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18  * License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with mimmo. If not, see <http://www.gnu.org/licenses/>.
22  *
23 \*---------------------------------------------------------------------------*/
24 #include "Chain.hpp"
25 
26 namespace mimmo{
27 
28 uint8_t Chain::sm_chaincounter(1);
29 
36  m_objcounter = 0;
37  m_objects.clear();
38  m_idObjects.clear();
40  m_plotDebRes = false;
41  m_outputDebRes = ".";
42  m_log = &bitpit::log::cout(MIMMO_LOG_FILE);
43 };
44 
45 
50  clear();
52 };
53 
58 void Chain::swap(Chain & x) noexcept{
59  std::swap(m_id,x.m_id);
60  std::swap(m_objects,x.m_objects);
61  std::swap(m_idObjects,x.m_idObjects);
62  std::swap(m_objcounter,x.m_objcounter);
63  std::swap(m_plotDebRes,x.m_plotDebRes);
64  std::swap(m_outputDebRes,x.m_outputDebRes);
65 };
66 
71 std::unique_ptr<Chain> Chain::clone() const{
72 
73  std::unique_ptr<Chain> res(new Chain());
74  res->setOutputDebugResults(m_outputDebRes);
75  res->setPlotDebugResults(m_plotDebRes);
76 
77  int count(0);
78  for(BaseManipulation * pp : m_objects){
79  res->addObject(pp, m_idObjects[count]);
80  ++count;
81  }
82  return res;
83 };
84 
85 
89 void
91  m_objcounter = 0;
92  m_objects.clear();
93  m_idObjects.clear();
94 };
95 
100 uint32_t
102  return m_objects.size();
103 };
104 
109 uint8_t
111  return m_id;
112 };
113 
118 uint8_t
120  return sm_chaincounter;
121 };
122 
128 int
130  return m_idObjects[i];
131 };
132 
138 std::string
140  return m_objects[i]->getName();
141 };
142 
147 bool
149  bool cut = false;
150  std::vector<int>::iterator it = std::find(m_idObjects.begin(), m_idObjects.end(), idobj);
151  if (it != m_idObjects.end()){
152  int idx = std::distance(m_idObjects.begin(), it);
153  if (m_objects[idx]->getParent() != nullptr || m_objects[idx]->getNChild() != 0) cut = true;
154  m_objects.erase(m_objects.begin()+idx);
155  m_idObjects.erase(it);
156  }
157  return cut;
158 };
159 
169 int
171  int id = id_;
172  if (id_ < 0){
173  id = m_objcounter;
174  m_objcounter++;
175  }
176  if (m_objects.size() == 0){
177  m_objects.push_back(obj);
178  m_idObjects.push_back(id);
179  return 0;
180  }
181  std::vector<BaseManipulation*>::iterator itchild = m_objects.end();
182  std::vector<BaseManipulation*>::iterator itparent;
183  int idxchild = m_objects.size();
184  ivector1D idxparent(obj->getNParent(), -1);
185  if (obj->getNChild()>0){
186  for (int i=0; i<obj->getNChild(); i++){
187  itchild = std::find(m_objects.begin(), m_objects.end(), obj->getChild(i));
188  if (itchild != m_objects.end()){
189  idxchild = std::min(idxchild, int(std::distance(m_objects.begin(), itchild)));
190  }
191  }
192  }
193  if (obj->getNParent()>0){
194  for (int i=0; i<obj->getNParent(); i++){
195  if (obj->getParent(i) != nullptr){
196  itparent = std::find(m_objects.begin(), m_objects.end(), obj->getParent(i));
197  if (itparent != m_objects.end()){
198  idxparent[i] = std::distance(m_objects.begin(), itparent);
199  }
200  }
201  }
202  }
203  for (int i=0; i<obj->getNParent(); i++){
204  if (idxparent[i] == idxchild) return -1;
205  }
206 
207  bool parentsMinor = true;
208  for (int i=0; i<obj->getNParent(); i++){
209  if (idxparent[i] > idxchild){
210  parentsMinor = false;
211  }
212  }
213  if (!parentsMinor){
214  ivector1D idparent(obj->getNParent(), -1);
215  std::vector<BaseManipulation*> parent(obj->getNParent());
216  for (int i=0; i<obj->getNParent(); i++){
217  if (idxparent[i] > idxchild){
218  parent[i] = obj->getParent(i);
219  itparent = std::find(m_objects.begin(), m_objects.end(), parent[i]);
220  int idxtemp = std::distance(m_objects.begin(), itparent);
221  idparent[i] = m_idObjects[idxtemp];
222  m_objects.erase(itparent);
223  m_idObjects.erase(m_idObjects.begin()+idxtemp);
224  }
225  }
226  int idx = addObject(obj, id);
227  for (int i=0; i<obj->getNParent(); i++){
228  if (idxparent[i] > idxchild){
229  addObject(parent[i], idparent[i]);
230  parent[i] = nullptr;
231  }
232  }
233  return idx+1;
234  }else{
235  m_objects.insert(m_objects.begin()+idxchild, obj);
236  m_idObjects.insert(m_idObjects.begin()+idxchild, id);
237  return idxchild;
238  }
239  return 0;
240 }
241 
242 
248 void Chain::setPlotDebugResults(bool active){
249  m_plotDebRes = active;
250 }
251 
256 void Chain::setOutputDebugResults(std::string path){
257  m_outputDebRes = path;
258 }
259 
264  return m_plotDebRes;
265 }
266 
272  return m_outputDebRes;
273 }
274 
275 
283 void
284 Chain::exec(bool debug){
285 
286  std::vector<BaseManipulation*>::iterator it, itb = m_objects.begin();
287  std::vector<BaseManipulation*>::iterator itend = m_objects.end();
288  bitpit::log::Priority oldPriority = m_log->getPriority();
289  if(debug)
290  m_log->setPriority(bitpit::log::NORMAL);
291  (*m_log) << " " << std::endl;
292  (*m_log) << "--------------------------------------------------" << std::endl;
293  (*m_log) << " Execution of chain - "<< m_objcounter << " objects" << std::endl;
294  if(m_plotDebRes){
295  (*m_log) << "--------------------------------------------------" << std::endl;
296  (*m_log) << " Plotting of Debug Results is active"<< std::endl;
297  (*m_log) << " Results will be stored in the directory: "<<m_outputDebRes<< std::endl;
298  (*m_log) << "--------------------------------------------------" << std::endl;
299  }
300  (*m_log) << " " << std::endl;
301  checkLoops();
302  int i = 1;
303  for (it = itb; it != itend; ++it){
304  if(debug)
305  m_log->setPriority(bitpit::log::NORMAL);
306  (*m_log) << " execution object " << i << " : " << (*it)->getName() << std::endl;
307 
308  if(m_plotDebRes){
309  (*it)->setPlotInExecution(m_plotDebRes);
310  (*it)->setOutputPlot(m_outputDebRes);
311  }
312  (*it)->exec();
313  i++;
314  }
315 
316  (*m_log) << " " << std::endl;
317  (*m_log) << "--------------------------------------------------" << std::endl;
318  (*m_log) << " " << std::endl;
319  m_log->setPriority(oldPriority);
320 }
321 
326 void
327 Chain::exec(int idobj){
328  int idx = std::distance(m_idObjects.begin(), find(m_idObjects.begin(), m_idObjects.end(), idobj));
329  if (idx < (int)m_objects.size()) m_objects[idx]->exec();
330 }
331 
336 void
338  std::vector<BaseManipulation*>::iterator it, itb = m_objects.begin();
339  std::vector<BaseManipulation*>::iterator itend = m_objects.end();
340  int actualidx = 0;
341  for (it = itb; it != itend; ++it){
342  for (int i=0; i<(*it)->getNChild(); i++){
343  int idxchild = std::distance(m_objects.begin(), std::find(m_objects.begin(), m_objects.end(), (*it)->getChild(i)));
344  if (idxchild <= actualidx){
345  (*m_log) << " error : loop in chain : "<< (*it)->getName() << " linked to " << (*it)->getChild(i)->getName() << std::endl;
346  (*m_log) << " " << std::endl;
347  throw std::runtime_error ("loop in chain : " + (*it)->getName() + " linked to " + (*it)->getChild(i)->getName());
348  }
349  }
350  actualidx++;
351  }
352 }
353 
354 }
void exec(bool debug=false)
Definition: Chain.cpp:284
uint32_t m_objcounter
Definition: Chain.hpp:55
uint8_t getID()
Definition: Chain.cpp:110
uint8_t m_id
Definition: Chain.hpp:52
BaseManipulation * getChild(int i=0)
Chain is the class used to manage the chain execution of multiple executable blocks (manipulation obj...
Definition: Chain.hpp:48
uint32_t getNObjects()
Definition: Chain.cpp:101
void swap(Chain &x) noexcept
Definition: Chain.cpp:58
std::string m_outputDebRes
Definition: Chain.hpp:60
std::unique_ptr< Chain > clone() const
Definition: Chain.cpp:71
std::string getName(int i)
Definition: Chain.cpp:139
virtual ~Chain()
Definition: Chain.cpp:49
uint8_t getNChains()
Definition: Chain.cpp:119
std::vector< int > m_idObjects
Definition: Chain.hpp:54
BaseManipulation is the base class of any manipulation object of the library.
BaseManipulation * getParent(int i=0)
std::string getOutputDebugResults()
Definition: Chain.cpp:271
std::vector< int > ivector1D
bitpit::Logger * m_log
Definition: Chain.hpp:57
void clear()
Definition: Chain.cpp:90
void setOutputDebugResults(std::string path)
Definition: Chain.cpp:256
void setPlotDebugResults(bool active)
Definition: Chain.cpp:248
std::vector< BaseManipulation * > m_objects
Definition: Chain.hpp:53
static uint8_t sm_chaincounter
Definition: Chain.hpp:62
int addObject(BaseManipulation *obj, int id_=-1)
Definition: Chain.cpp:170
bool deleteObject(int idobj)
Definition: Chain.cpp:148
bool isPlottingDebugResults()
Definition: Chain.cpp:263
bool m_plotDebRes
Definition: Chain.hpp:59
void checkLoops()
Definition: Chain.cpp:337