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