f3080e40e8304aad95e8147702134d95c6a6ecac
[scilab.git] / scilab / modules / scicos / src / cpp / model / Block.hxx
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
4  *
5  *  This file must be used under the terms of the CeCILL.
6  *  This source file is licensed as described in the file COPYING, which
7  *  you should have received as part of this distribution.  The terms
8  *  are also available at
9  *  http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
10  *
11  */
12
13 #ifndef BLOCK_HXX_
14 #define BLOCK_HXX_
15
16 #include <string>
17 #include <vector>
18
19 #include "utilities.hxx"
20 #include "Model.hxx"
21 #include "model/BaseObject.hxx"
22
23 namespace org_scilab_modules_scicos
24 {
25 namespace model
26 {
27
28 struct Parameter
29 {
30     std::vector<double> rpar;
31     std::vector<int> ipar;
32     std::vector<double> opar;
33
34     // opar default value is an empty list encoded by var2vec()
35     Parameter() : rpar(), ipar(), opar{22, 0} {}
36 };
37
38 struct State
39 {
40     std::vector<double> state;
41     std::vector<double> dstate;
42     std::vector<double> odstate;
43
44     // odstate default value is an empty list encoded by var2vec()
45     State() : state(), dstate(), odstate{22, 0} {}
46 };
47
48 /**
49  * Mask list for all possible block scheduling descriptor from the simulator point of view.
50  *
51  * Examples:
52  *  * CONST_m == 0
53  *  * SUMMATION == DEP_U
54  *  * CLR == DEP_T
55  *  * SWITCH_f == DEP_U | DEP_T
56  */
57 enum dep_ut_t
58 {
59     DEP_U       = 1 << 0, //!< y=f(u)
60     DEP_T       = 1 << 1, //!< y=f(x)
61 };
62
63 enum blocktype_t
64 {
65     BLOCKTYPE_C = 'c', //!< N/A ; dummy value used to represent a 'c' blocktype (eg. not 'd')
66     BLOCKTYPE_D = 'd', //!< N/A ; dummy value used to represent a 'd' blocktype (eg. not 'c')
67     BLOCKTYPE_H = 'h', //!< N/A ; used to represent blocks composed by blocks
68     BLOCKTYPE_L = 'l', //!< synchronization block ; ifthenelse and eselect
69     BLOCKTYPE_M = 'm', //!< memorization block ; see the Scicos original paper
70     BLOCKTYPE_X = 'x', //!< derivable block without state ; these blocks will be treated as if they contain a state.
71     BLOCKTYPE_Z = 'z', //!< zero-crossing block ; see the Scicos original paper.
72 };
73
74 struct Descriptor
75 {
76     std::string functionName;
77     int functionApi;
78
79     char dep_ut;            //!< dep_ut_t masked value
80     char blocktype;         //!< one of blocktype_t value
81
82     Descriptor() : functionName(), functionApi(0), dep_ut(0), blocktype(BLOCKTYPE_C) {}
83 };
84
85 /*
86  * Flip and theta
87  */
88 struct Angle
89 {
90     bool flip;
91     double theta;
92
93     Angle() : flip(true), theta(0) {};
94     Angle(const Angle& a) : flip(a.flip), theta(a.theta) {};
95     Angle(const std::vector<double>& a) : flip((a[0] == 0) ? false : true), theta(a[1]) {};
96
97     void fill(std::vector<double>& a) const
98     {
99         a.resize(2);
100         a[0] = (flip == false) ? 0 : 1;
101         a[1] = theta;
102     }
103     bool operator==(const Angle& a) const
104     {
105         return flip == a.flip && theta == a.theta;
106     }
107 };
108
109 class Block: public BaseObject
110 {
111 public:
112     Block() : BaseObject(BLOCK), m_parentDiagram(ScicosID()), m_interfaceFunction(), m_geometry(), m_angle(),
113         m_exprs{12, 2, 0, 0, 0}, m_label(), m_style(), m_nzcross{0}, m_nmode{0}, m_equations(), m_uid(), m_sim(), m_in(), m_out(), m_ein(), m_eout(),
114         m_parameter(), m_state(), m_parentBlock(ScicosID()), m_children(), m_childrenColor{ -1, 1}, m_portReference(ScicosID()) {};
115     Block(const Block& o) : BaseObject(BLOCK), m_parentDiagram(o.m_parentDiagram), m_interfaceFunction(o.m_interfaceFunction), m_geometry(o.m_geometry),
116         m_angle(o.m_angle), m_exprs(o.m_exprs), m_label(o.m_label), m_style(o.m_style), m_nzcross(o.m_nzcross), m_nmode(o.m_nmode), m_equations(o.m_equations), m_uid(o.m_uid),
117         m_sim(o.m_sim), m_in(o.m_in), m_out(o.m_out), m_ein(o.m_ein), m_eout(o.m_eout), m_parameter(o.m_parameter), m_state(o.m_state), m_parentBlock(o.m_parentBlock),
118         m_children(o.m_children), m_childrenColor(o.m_childrenColor), m_portReference(o.m_portReference) {};
119     ~Block() = default;
120
121 private:
122     friend class ::org_scilab_modules_scicos::Model;
123
124     void getChildren(std::vector<ScicosID>& v) const
125     {
126         v = this->m_children;
127     }
128
129     update_status_t setChildren(const std::vector<ScicosID>& children)
130     {
131         if (children == this->m_children)
132         {
133             return NO_CHANGES;
134         }
135
136         this->m_children = children;
137         return SUCCESS;
138     }
139
140     void getChildrenColor(std::vector<int>& data) const
141     {
142         data = this->m_childrenColor;
143     }
144
145     update_status_t setChildrenColor(const std::vector<int>& data)
146     {
147         if (data == this->m_childrenColor)
148         {
149             return NO_CHANGES;
150         }
151
152         this->m_childrenColor = data;
153         return SUCCESS;
154     }
155
156     void getGeometry(std::vector<double>& v) const
157     {
158         m_geometry.fill(v);
159     }
160
161     update_status_t setGeometry(const std::vector<double>& v)
162     {
163         if (v.size() != 4)
164         {
165             return FAIL;
166         }
167
168         Geometry g = Geometry(v);
169         if (g == m_geometry)
170         {
171             return NO_CHANGES;
172         }
173
174         m_geometry = g;
175         return SUCCESS;
176     }
177
178     void getAngle(std::vector<double>& data) const
179     {
180         m_angle.fill(data);
181     }
182
183     update_status_t setAngle(const std::vector<double>& data)
184     {
185         if (data.size() != 2)
186         {
187             return FAIL;
188         }
189
190         Angle a = Angle(data);
191         if (a == m_angle)
192         {
193             return NO_CHANGES;
194         }
195
196         m_angle = a;
197         return SUCCESS;
198     }
199
200     void getExprs(std::vector<double>& data) const
201     {
202         data = m_exprs;
203     }
204
205     update_status_t setExprs(const std::vector<double>& data)
206     {
207         if (data == m_exprs)
208         {
209             return NO_CHANGES;
210         }
211
212         m_exprs = data;
213         return SUCCESS;
214     }
215
216     void getLabel(std::string& data) const
217     {
218         data = m_label;
219     }
220
221     update_status_t setLabel(const std::string& data)
222     {
223         if (data == m_label)
224         {
225             return NO_CHANGES;
226         }
227
228         m_label = data;
229         return SUCCESS;
230     }
231
232     void getIn(std::vector<ScicosID>& v) const
233     {
234         v = m_in;
235     }
236
237     update_status_t setIn(const std::vector<ScicosID>& in)
238     {
239         if (in == this->m_in)
240         {
241             return NO_CHANGES;
242         }
243
244         this->m_in = in;
245         return SUCCESS;
246     }
247
248     void getInterfaceFunction(std::string& fun) const
249     {
250         fun = m_interfaceFunction;
251     }
252
253     update_status_t setInterfaceFunction(const std::string& fun)
254     {
255         if (fun == m_interfaceFunction)
256         {
257             return NO_CHANGES;
258         }
259
260         m_interfaceFunction = fun;
261         return SUCCESS;
262     }
263
264     void getOut(std::vector<ScicosID>& v) const
265     {
266         v = m_out;
267     }
268
269     update_status_t setOut(const std::vector<ScicosID>& out)
270     {
271         if (out == this->m_out)
272         {
273             return NO_CHANGES;
274         }
275
276         this->m_out = out;
277         return SUCCESS;
278     }
279
280     void getEin(std::vector<ScicosID>& v) const
281     {
282         v = m_ein;
283     }
284
285     update_status_t setEin(const std::vector<ScicosID>& ein)
286     {
287         if (ein == this->m_ein)
288         {
289             return NO_CHANGES;
290         }
291
292         this->m_ein = ein;
293         return SUCCESS;
294     }
295
296     void getEout(std::vector<ScicosID>& v) const
297     {
298         v = m_eout;
299     }
300
301     update_status_t setEout(const std::vector<ScicosID>& eout)
302     {
303         if (eout == this->m_eout)
304         {
305             return NO_CHANGES;
306         }
307
308         this->m_eout = eout;
309         return SUCCESS;
310     }
311
312     const Parameter& getParameter() const
313     {
314         return m_parameter;
315     }
316
317     void setParameter(const Parameter& parameter)
318     {
319         this->m_parameter = parameter;
320     }
321
322     void getParentBlock(ScicosID& v) const
323     {
324         v = m_parentBlock;
325     }
326
327     update_status_t setParentBlock(ScicosID parentBlock)
328     {
329         if (parentBlock == this->m_parentBlock)
330         {
331             return NO_CHANGES;
332         }
333
334         this->m_parentBlock = parentBlock;
335         return SUCCESS;
336     }
337
338     void getParentDiagram(ScicosID& v) const
339     {
340         v = m_parentDiagram;
341     }
342
343     update_status_t setParentDiagram(const ScicosID v)
344     {
345         if (v == m_parentDiagram)
346         {
347             return NO_CHANGES;
348         }
349
350         m_parentDiagram = v;
351         return SUCCESS;
352     }
353
354     void getPortReference(ScicosID& v) const
355     {
356         v = m_portReference;
357     }
358
359     update_status_t setPortReference(const ScicosID v)
360     {
361         if (v == m_portReference)
362         {
363             return NO_CHANGES;
364         }
365
366         m_portReference = v;
367         return SUCCESS;
368     }
369
370     const Descriptor& getSim() const
371     {
372         return m_sim;
373     }
374
375     void setSim(const Descriptor& sim)
376     {
377         this->m_sim = sim;
378     }
379
380     void getStyle(std::string& data) const
381     {
382         data = m_style;
383     }
384
385     update_status_t setStyle(const std::string& data)
386     {
387         if (data == m_style)
388         {
389             return NO_CHANGES;
390         }
391
392         m_style = data;
393         return SUCCESS;
394     }
395
396     void getNZcross(std::vector<int>& data) const
397     {
398         data = m_nzcross;
399     }
400
401     update_status_t setNZcross(const std::vector<int>& data)
402     {
403         if (data == m_nzcross)
404         {
405             return NO_CHANGES;
406         }
407
408         m_nzcross = data;
409         return SUCCESS;
410     }
411
412     void getNMode(std::vector<int>& data) const
413     {
414         data = m_nmode;
415     }
416
417     update_status_t setNMode(const std::vector<int>& data)
418     {
419         if (data == m_nmode)
420         {
421             return NO_CHANGES;
422         }
423
424         m_nmode = data;
425         return SUCCESS;
426     }
427
428     void getEquations(std::vector<std::string>& data) const
429     {
430         data = m_equations;
431     }
432
433     update_status_t setEquations(const std::vector<std::string>& data)
434     {
435         if (data == m_equations)
436         {
437             return NO_CHANGES;
438         }
439
440         m_equations = data;
441         return SUCCESS;
442     }
443
444     void getUID(std::string& data) const
445     {
446         data = m_uid;
447     }
448
449     update_status_t setUID(const std::string& data)
450     {
451         if (data == m_uid)
452         {
453             return NO_CHANGES;
454         }
455
456         m_uid = data;
457         return SUCCESS;
458     }
459
460     void getRpar(std::vector<double>& data) const
461     {
462         data = m_parameter.rpar;
463     }
464
465     update_status_t setRpar(const std::vector<double>& data)
466     {
467         if (data == m_parameter.rpar)
468         {
469             return NO_CHANGES;
470         }
471
472         m_parameter.rpar = data;
473         return SUCCESS;
474     }
475
476     void getIpar(std::vector<int>& data) const
477     {
478         data = m_parameter.ipar;
479     }
480
481     update_status_t setIpar(const std::vector<int>& data)
482     {
483         if (data == m_parameter.ipar)
484         {
485             return NO_CHANGES;
486         }
487
488         m_parameter.ipar = data;
489         return SUCCESS;
490     }
491
492     void getOpar(std::vector<double>& data) const
493     {
494         data = m_parameter.opar;
495     }
496
497     update_status_t setOpar(const std::vector<double>& data)
498     {
499         if (data == m_parameter.opar)
500         {
501             return NO_CHANGES;
502         }
503
504         m_parameter.opar = data;
505         return SUCCESS;
506     }
507
508     void getSimFunctionName(std::string& data) const
509     {
510         data = m_sim.functionName;
511     }
512
513     update_status_t setSimFunctionName(const std::string& data)
514     {
515         if (data == m_sim.functionName)
516         {
517             return NO_CHANGES;
518         }
519
520         m_sim.functionName = data;
521         return SUCCESS;
522     }
523
524     void getSimFunctionApi(int& data) const
525     {
526         data = m_sim.functionApi;
527     }
528
529     update_status_t setSimFunctionApi(const int data)
530     {
531         if (data == m_sim.functionApi)
532         {
533             return NO_CHANGES;
534         }
535
536         m_sim.functionApi = data;
537         return SUCCESS;
538     }
539
540     void getSimBlocktype(std::string& data) const
541     {
542         data = std::string(1, m_sim.blocktype);
543     }
544
545     update_status_t setSimBlocktype(const std::string data)
546     {
547         if (data.size() != 1)
548         {
549             return FAIL;
550         }
551
552         char c = *(data.c_str());
553
554         if (c == m_sim.blocktype)
555         {
556             return NO_CHANGES;
557         }
558
559         switch (c)
560         {
561             case BLOCKTYPE_C:
562             case BLOCKTYPE_D:
563             case BLOCKTYPE_H:
564             case BLOCKTYPE_L:
565             case BLOCKTYPE_M:
566             case BLOCKTYPE_X:
567             case BLOCKTYPE_Z:
568                 m_sim.blocktype = c;
569                 return SUCCESS;
570             default:
571                 return FAIL;
572         }
573     }
574
575     void getSimDepUT(std::vector<int>& data) const
576     {
577         data.resize(2, 0);
578         switch (m_sim.dep_ut)
579         {
580             case DEP_U & DEP_T:
581                 // data is already set to [0 0] here.
582                 break;
583             case DEP_U:
584                 data[0] = 1;
585                 break;
586             case DEP_T:
587                 data[1] = 1;
588                 break;
589             case DEP_U | DEP_T:
590                 data[0] = 1;
591                 data[1] = 1;
592                 break;
593             default:
594                 break;
595         }
596     }
597
598     update_status_t setSimDepUT(const std::vector<int>& data)
599     {
600         if (data.size() != 2)
601         {
602             return FAIL;
603         }
604
605         int dep = DEP_U & DEP_T;
606         if (data[0])
607         {
608             if (data[1])
609             {
610                 dep = DEP_U | DEP_T;
611             }
612             else
613             {
614                 dep = DEP_U;
615             }
616         }
617         else if (data[1])
618         {
619             dep = DEP_T;
620         }
621
622         if (dep == m_sim.dep_ut)
623         {
624             return NO_CHANGES;
625         }
626
627         m_sim.dep_ut = dep;
628         return SUCCESS;
629     }
630
631     void getState(std::vector<double>& data) const
632     {
633         data = m_state.state;
634     }
635
636     update_status_t setState(const std::vector<double>& data)
637     {
638         if (data == m_state.state)
639         {
640             return NO_CHANGES;
641         }
642
643         m_state.state = data;
644         return SUCCESS;
645     }
646
647     void getDState(std::vector<double>& data) const
648     {
649         data = m_state.dstate;
650     }
651
652     update_status_t setDState(const std::vector<double>& data)
653     {
654         if (data == m_state.dstate)
655         {
656             return NO_CHANGES;
657         }
658
659         m_state.dstate = data;
660         return SUCCESS;
661     }
662
663     void getODState(std::vector<double>& data) const
664     {
665         data = m_state.odstate;
666     }
667
668     update_status_t setODState(const std::vector<double>& data)
669     {
670         if (data == m_state.odstate)
671         {
672             return NO_CHANGES;
673         }
674
675         m_state.odstate = data;
676         return SUCCESS;
677     }
678
679 private:
680     ScicosID m_parentDiagram;
681     std::string m_interfaceFunction;
682     Geometry m_geometry;
683     Angle m_angle;
684     std::vector<double> m_exprs;
685     std::string m_label;
686     std::string m_style;
687     std::vector<int> m_nzcross;
688     std::vector<int> m_nmode;
689     std::vector<std::string> m_equations;
690     std::string m_uid;
691
692     Descriptor m_sim;
693
694     std::vector<ScicosID> m_in;
695     std::vector<ScicosID> m_out;
696     std::vector<ScicosID> m_ein;
697     std::vector<ScicosID> m_eout;
698
699     Parameter m_parameter;
700     State m_state;
701
702     /**
703      * SuperBlock: the blocks, links and so on contained into this block
704      */
705     ScicosID m_parentBlock;
706     std::vector<ScicosID> m_children;
707     std::vector<int> m_childrenColor;
708
709     /**
710      * I/O Blocks: the corresponding parent port
711      */
712     ScicosID m_portReference;
713 };
714
715 } /* namespace model */
716 } /* namespace org_scilab_modules_scicos */
717
718 #endif /* BLOCK_HXX_ */