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