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