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