ff68b26ec2bbe62801bf3da6becdfeaebb6cba3e
[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(0), 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         this->in = in;
227         return SUCCESS;
228     }
229
230     const std::string& getInterfaceFunction() const
231     {
232         return interfaceFunction;
233     }
234
235     void setInterfaceFunction(const std::string& interfaceFunction)
236     {
237         this->interfaceFunction = interfaceFunction;
238     }
239
240     void getOut(std::vector<ScicosID>& v) const
241     {
242         v = out;
243     }
244
245     update_status_t setOut(const std::vector<ScicosID>& out)
246     {
247         if (out == this->out)
248         {
249             return NO_CHANGES;
250         }
251         this->out = out;
252         return SUCCESS;
253     }
254
255     void getEin(std::vector<ScicosID>& v) const
256     {
257         v = ein;
258     }
259
260     update_status_t setEin(const std::vector<ScicosID>& ein)
261     {
262         if (ein == this->ein)
263         {
264             return NO_CHANGES;
265         }
266         this->ein = ein;
267         return SUCCESS;
268     }
269
270     void getEout(std::vector<ScicosID>& v) const
271     {
272         v = eout;
273     }
274
275     update_status_t setEout(const std::vector<ScicosID>& eout)
276     {
277         if (eout == this->eout)
278         {
279             return NO_CHANGES;
280         }
281         this->eout = eout;
282         return SUCCESS;
283     }
284
285     const Parameter& getParameter() const
286     {
287         return parameter;
288     }
289
290     void setParameter(const Parameter& parameter)
291     {
292         this->parameter = parameter;
293     }
294
295     ScicosID getParentBlock() const
296     {
297         return parentBlock;
298     }
299
300     void setParentBlock(ScicosID parentBlock)
301     {
302         this->parentBlock = parentBlock;
303     }
304
305     ScicosID getParentDiagram() const
306     {
307         return parentDiagram;
308     }
309
310     void setParentDiagram(ScicosID parentDiagram)
311     {
312         this->parentDiagram = parentDiagram;
313     }
314
315     ScicosID getPortReference() const
316     {
317         return portReference;
318     }
319
320     void setPortReference(ScicosID portReference)
321     {
322         this->portReference = portReference;
323     }
324
325     const Descriptor& getSim() const
326     {
327         return sim;
328     }
329
330     void setSim(const Descriptor& sim)
331     {
332         this->sim = sim;
333     }
334
335     void getStyle(std::string& data) const
336     {
337         data = style;
338     }
339
340     update_status_t setStyle(const std::string& data)
341     {
342         if (data == style)
343         {
344             return NO_CHANGES;
345         }
346
347         style = data;
348         return SUCCESS;
349     }
350
351     void getNZcross(int& data) const
352     {
353         data = nzcross;
354     }
355
356     update_status_t setNZcross(const int data)
357     {
358         if (data == nzcross)
359         {
360             return NO_CHANGES;
361         }
362
363         nzcross = data;
364         return SUCCESS;
365     }
366
367     void getNMode(int& data) const
368     {
369         data = nmode;
370     }
371
372     update_status_t setNMode(const int data)
373     {
374         if (data == nmode)
375         {
376             return NO_CHANGES;
377         }
378
379         nmode = data;
380         return SUCCESS;
381     }
382
383     void getUID(std::string& data) const
384     {
385         data = uid;
386     }
387
388     update_status_t setUID(const std::string& data)
389     {
390         if (data == uid)
391         {
392             return NO_CHANGES;
393         }
394
395         uid = data;
396         return SUCCESS;
397     }
398
399     void getRpar(std::vector<double>& data) const
400     {
401         data = parameter.rpar;
402     }
403
404     update_status_t setRpar(const std::vector<double>& data)
405     {
406         if (data == parameter.rpar)
407         {
408             return NO_CHANGES;
409         }
410
411         parameter.rpar = data;
412         return SUCCESS;
413     }
414
415     void getIpar(std::vector<int>& data) const
416     {
417         data = parameter.ipar;
418     }
419
420     update_status_t setIpar(const std::vector<int>& data)
421     {
422         if (data == parameter.ipar)
423         {
424             return NO_CHANGES;
425         }
426
427         parameter.ipar = data;
428         return SUCCESS;
429     }
430
431     void getSimFunctionName(std::string& data) const
432     {
433         data = sim.functionName;
434     }
435
436     update_status_t setSimFunctionName(const std::string& data)
437     {
438         if (data == sim.functionName)
439         {
440             return NO_CHANGES;
441         }
442
443         sim.functionName = data;
444         return SUCCESS;
445     }
446
447     void getSimFunctionApi(int& data) const
448     {
449         data = sim.functionApi;
450     }
451
452     update_status_t setSimFunctionApi(const int data)
453     {
454         if (data == sim.functionApi)
455         {
456             return NO_CHANGES;
457         }
458
459         sim.functionApi = data;
460         return SUCCESS;
461     }
462
463     void getSimBlocktype(int& data) const
464     {
465         data = sim.blocktype;
466     }
467
468     update_status_t setSimBlocktype(const int data)
469     {
470         if (data == sim.blocktype)
471         {
472             return NO_CHANGES;
473         }
474
475         switch (data)
476         {
477             case BLOCKTYPE_C:
478             case BLOCKTYPE_D:
479             case BLOCKTYPE_H:
480             case BLOCKTYPE_L:
481             case BLOCKTYPE_M:
482             case BLOCKTYPE_X:
483             case BLOCKTYPE_Z:
484                 sim.blocktype = data;
485                 return SUCCESS;
486             default:
487                 return FAIL;
488         }
489     }
490
491     void getSimDepUT(std::vector<int>& data) const
492     {
493         data.resize(2, 0);
494         switch (sim.dep_ut)
495         {
496             case DEP_U & DEP_T:
497                 // data is already set to [0 0] here.
498                 return;
499             case DEP_U:
500                 data[0] = 1;
501                 return;
502             case DEP_T:
503                 data[1] = 1;
504                 return;
505             case DEP_U | DEP_T:
506                 data[0] = 1;
507                 data[1] = 1;
508             default:
509                 return;
510         }
511     }
512
513     update_status_t setSimDepUT(const std::vector<int>& data)
514     {
515         if (data.size() != 2)
516         {
517             return FAIL;
518         }
519
520         int dep = DEP_U & DEP_T;
521         if (data[0])
522         {
523             if (data[1])
524             {
525                 dep = DEP_U | DEP_T;
526             }
527             else
528             {
529                 dep = DEP_U;
530             }
531         }
532         else if (data[1])
533         {
534             dep = DEP_T;
535         }
536
537         if (dep == sim.dep_ut)
538         {
539             return NO_CHANGES;
540         }
541
542         sim.dep_ut = dep;
543         return SUCCESS;
544     }
545
546     void getState(std::vector<double>& data) const
547     {
548         data = state.state;
549     }
550
551     update_status_t setState(const std::vector<double>& data)
552     {
553         if (data == state.state)
554         {
555             return NO_CHANGES;
556         }
557
558         state.state = data;
559         return SUCCESS;
560     }
561
562     void getDState(std::vector<double>& data) const
563     {
564         data = state.dstate;
565     }
566
567     update_status_t setDState(const std::vector<double>& data)
568     {
569         if (data == state.dstate)
570         {
571             return NO_CHANGES;
572         }
573
574         state.dstate = data;
575         return SUCCESS;
576     }
577
578 private:
579     ScicosID parentDiagram;
580     std::string interfaceFunction;
581     Geometry geometry;
582     Angle angle;
583     std::vector<std::string> exprs;
584     std::string label;
585     std::string style;
586     int nzcross;
587     int nmode;
588     // FIXME: find an appropriate way to store 'equations'
589     std::vector<std::string> equations;
590     std::string uid;
591
592     Descriptor sim;
593
594     std::vector<ScicosID> in;
595     std::vector<ScicosID> out;
596     std::vector<ScicosID> ein;
597     std::vector<ScicosID> eout;
598
599     Parameter parameter;
600     State state;
601
602     /**
603      * SuperBlock: the blocks, links and so on contained into this block
604      */
605     ScicosID parentBlock;
606     std::vector<ScicosID> children;
607
608     /**
609      * I/O Blocks: the corresponding parent port
610      */
611     ScicosID portReference;
612 };
613
614 } /* namespace model */
615 } /* namespace org_scilab_modules_scicos */
616
617 #endif /* BLOCK_HXX_ */