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