acf7f7355d742df1714e40b9aee6d7d6db8f69f4
[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-en.txt
10  *
11  */
12
13 #ifndef BLOCK_HXX_
14 #define BLOCK_HXX_
15
16 #include <string>
17 #include <vector>
18 #include <bitset>
19 #include <utility>
20
21 #include "Model.hxx"
22 #include "model/BaseObject.hxx"
23
24 namespace org_scilab_modules_scicos
25 {
26 namespace model
27 {
28
29 /**
30  * Scilab data that can be passed to the simulator and simulation functions.
31  *
32  * This used the raw scicos-sim encoding to avoid any conversion out of the model.
33  */
34 struct list_t
35 {
36     // re-use the scicos sim encoding
37     int n;
38     int* sz;
39     int* typ;
40     void** data;
41 };
42
43 struct Parameter
44 {
45     std::vector<double> rpar;
46     std::vector<int> ipar;
47     list_t opar;
48 };
49
50 struct State
51 {
52     std::vector<double> state;
53     std::vector<double> dstate;
54     list_t odstate;
55 };
56
57 /**
58  * Mask list for all possible block scheduling descriptor from the simulator point of view.
59  *
60  * Examples:
61  *  * CONST_m == 0
62  *  * SUMMATION == DEP_U
63  *  * CLR == DEP_T
64  *  * SWITCH_f == DEP_U & DEP_T
65  */
66 enum dep_ut_t
67 {
68     DEP_U       = 1 << 0, //!< y=f(u)
69     DEP_T       = 1 << 1, //!< y=f(x)
70 };
71
72 enum blocktype_t
73 {
74     BLOCKTYPE_C = 'c', //!< N/A ; dummy value used to represent a 'c' blocktype (eg. not 'd')
75     BLOCKTYPE_D = 'd', //!< N/A ; dummy value used to represent a 'd' blocktype (eg. not 'c')
76     BLOCKTYPE_H = 'h', //!< N/A ; used to represent blocks composed by blocks
77     BLOCKTYPE_L = 'l', //!< synchronization block ; ifthenelse and eselect
78     BLOCKTYPE_M = 'm', //!< memorization block ; see the Scicos original paper
79     BLOCKTYPE_X = 'x', //!< derivable block without state ; these blocks will be treated as if they contain a state.
80     BLOCKTYPE_Z = 'z', //!< zero-crossing block ; see the Scicos original paper.
81 };
82
83 struct Descriptor
84 {
85     std::string functionName;
86     int functionApi;
87
88     char dep_ut;            //!< dep_ut_t masked value
89     char blocktype;         //!< one of blocktype_t value
90 };
91
92 /*
93  * Flip and theta
94  */
95 struct Angle
96 {
97     bool flip;
98     double theta;
99
100     Angle() : flip(0), theta(0) {};
101     Angle(const Angle& a) : flip(a.flip), theta(a.theta) {};
102     Angle(const std::vector<double>& a) : flip((a[0] == 0) ? false : true), theta(a[1]) {};
103
104     void fill(std::vector<double>& a) const
105     {
106         a.resize(2);
107         a[0] = (flip == false) ? 0 : 1;
108         a[1] = theta;
109     }
110     bool operator==(const Angle& a) const
111     {
112         return flip == a.flip && theta == a.theta;
113     }
114 };
115
116 class Block: public BaseObject
117 {
118 private:
119     friend class ::org_scilab_modules_scicos::Model;
120
121 private:
122     Block() : BaseObject(BLOCK), parentDiagram(0), interfaceFunction(), geometry(),
123         angle(), exprs(), label(), style(), sim(), in(), out(), ein(), eout(),
124         parameter(), state(), parentBlock(0), children(), portReference(0) {};
125     Block(const Block& o) : BaseObject(BLOCK), parentDiagram(o.parentDiagram), interfaceFunction(o.interfaceFunction), geometry(o.geometry),
126         angle(o.angle), exprs(o.exprs), label(o.label), style(o.style), sim(o.sim), in(o.in), out(o.out), ein(o.ein), eout(o.eout),
127         parameter(o.parameter), state(o.state), parentBlock(o.parentBlock), children(o.children), portReference(o.portReference) {};
128     ~Block() {}
129
130     const std::vector<ScicosID>& getChildren() const
131     {
132         return children;
133     }
134
135     void setChildren(const std::vector<ScicosID>& children)
136     {
137         this->children = children;
138     }
139
140     void getGeometry(std::vector<double>& v) const
141     {
142         geometry.fill(v);
143     }
144
145     update_status_t setGeometry(const std::vector<double>& v)
146     {
147         if (v.size() != 4)
148         {
149             return FAIL;
150         }
151
152         Geometry g = Geometry(v);
153         if (g == geometry)
154         {
155             return NO_CHANGES;
156         }
157
158         geometry = g;
159         return SUCCESS;
160     }
161
162     void getAngle(std::vector<double>& data) const
163     {
164         angle.fill(data);
165     }
166
167     update_status_t setAngle(const std::vector<double>& data)
168     {
169         if (data.size() != 2)
170         {
171             return FAIL;
172         }
173
174         Angle a = Angle(data);
175         if (a == angle)
176         {
177             return NO_CHANGES;
178         }
179
180         angle = a;
181         return SUCCESS;
182     }
183
184     void getExprs(std::vector<std::string>& data) const
185     {
186         data = exprs;
187     }
188
189     update_status_t setExprs(const std::vector<std::string>& data)
190     {
191         if (data == exprs)
192         {
193             return NO_CHANGES;
194         }
195
196         exprs = data;
197         return SUCCESS;
198     }
199
200     void getLabel(std::string& data) const
201     {
202         data = label;
203     }
204
205     update_status_t setLabel(const std::string& data)
206     {
207         if (data == label)
208         {
209             return NO_CHANGES;
210         }
211
212         label = data;
213         return SUCCESS;
214     }
215
216     void getIn(std::vector<ScicosID>& v) const
217     {
218         v = in;
219     }
220
221     update_status_t setIn(const std::vector<ScicosID>& in)
222     {
223         if (in == this->in)
224         {
225             return NO_CHANGES;
226         }
227         this->in = in;
228         return SUCCESS;
229     }
230
231     const std::string& getInterfaceFunction() const
232     {
233         return interfaceFunction;
234     }
235
236     void setInterfaceFunction(const std::string& interfaceFunction)
237     {
238         this->interfaceFunction = interfaceFunction;
239     }
240
241     void getOut(std::vector<ScicosID>& v) const
242     {
243         v = out;
244     }
245
246     update_status_t setOut(const std::vector<ScicosID>& out)
247     {
248         if (out == this->out)
249         {
250             return NO_CHANGES;
251         }
252         this->out = out;
253         return SUCCESS;
254     }
255
256     void getEin(std::vector<ScicosID>& v) const
257     {
258         v = ein;
259     }
260
261     update_status_t setEin(const std::vector<ScicosID>& ein)
262     {
263         if (ein == this->ein)
264         {
265             return NO_CHANGES;
266         }
267         this->ein = ein;
268         return SUCCESS;
269     }
270
271     void getEout(std::vector<ScicosID>& v) const
272     {
273         v = eout;
274     }
275
276     update_status_t setEout(const std::vector<ScicosID>& eout)
277     {
278         if (eout == this->eout)
279         {
280             return NO_CHANGES;
281         }
282         this->eout = eout;
283         return SUCCESS;
284     }
285
286     const Parameter& getParameter() const
287     {
288         return parameter;
289     }
290
291     void setParameter(const Parameter& parameter)
292     {
293         this->parameter = parameter;
294     }
295
296     ScicosID getParentBlock() const
297     {
298         return parentBlock;
299     }
300
301     void setParentBlock(ScicosID parentBlock)
302     {
303         this->parentBlock = parentBlock;
304     }
305
306     ScicosID getParentDiagram() const
307     {
308         return parentDiagram;
309     }
310
311     void setParentDiagram(ScicosID parentDiagram)
312     {
313         this->parentDiagram = parentDiagram;
314     }
315
316     ScicosID getPortReference() const
317     {
318         return portReference;
319     }
320
321     void setPortReference(ScicosID portReference)
322     {
323         this->portReference = portReference;
324     }
325
326     const Descriptor& getSim() const
327     {
328         return sim;
329     }
330
331     void setSim(const Descriptor& sim)
332     {
333         this->sim = sim;
334     }
335
336     void getStyle(std::string& data) const
337     {
338         data = style;
339     }
340
341     update_status_t setStyle(const std::string& data)
342     {
343         if (data == style)
344         {
345             return NO_CHANGES;
346         }
347
348         style = data;
349         return SUCCESS;
350     }
351
352     void getSimFunctionName(std::string& data) const
353     {
354         data = sim.functionName;
355     }
356
357     update_status_t setSimFunctionName(const std::string& data)
358     {
359         if (data == sim.functionName)
360         {
361             return NO_CHANGES;
362         }
363
364         sim.functionName = data;
365         return SUCCESS;
366     }
367
368     void getSimFunctionApi(int& data) const
369     {
370         data = sim.functionApi;
371     }
372
373     update_status_t setSimFunctionApi(const int data)
374     {
375         if (data == sim.functionApi)
376         {
377             return NO_CHANGES;
378         }
379
380         sim.functionApi = data;
381         return SUCCESS;
382     }
383
384     void getSimBlocktype(int& data) const
385     {
386         data = sim.blocktype;
387     }
388
389     update_status_t setSimBlocktype(const int data)
390     {
391         if (data == sim.blocktype)
392         {
393             return NO_CHANGES;
394         }
395
396         switch (data)
397         {
398             case BLOCKTYPE_C:
399             case BLOCKTYPE_D:
400             case BLOCKTYPE_H:
401             case BLOCKTYPE_L:
402             case BLOCKTYPE_M:
403             case BLOCKTYPE_X:
404             case BLOCKTYPE_Z:
405                 sim.blocktype = data;
406                 break;
407             default:
408                 return FAIL;
409         }
410         return SUCCESS;
411     }
412
413     void getState(std::vector<double>& data) const
414     {
415         data = state.state;
416     }
417
418     update_status_t setState(const std::vector<double>& data)
419     {
420         if (data == state.state)
421         {
422             return NO_CHANGES;
423         }
424
425         state.state = data;
426         return SUCCESS;
427     }
428
429     void getDState(std::vector<double>& data) const
430     {
431         data = state.dstate;
432     }
433
434     update_status_t setDState(const std::vector<double>& data)
435     {
436         if (data == state.dstate)
437         {
438             return NO_CHANGES;
439         }
440
441         state.dstate = data;
442         return SUCCESS;
443     }
444
445 private:
446     ScicosID parentDiagram;
447     std::string interfaceFunction;
448     Geometry geometry;
449     Angle angle;
450     std::vector<std::string> exprs;
451     std::string label;
452     std::string style;
453
454     Descriptor sim;
455
456     std::vector<ScicosID> in;
457     std::vector<ScicosID> out;
458     std::vector<ScicosID> ein;
459     std::vector<ScicosID> eout;
460
461     Parameter parameter;
462     State state;
463
464     /**
465      * SuperBlock: the blocks, links and so on contained into this block
466      */
467     ScicosID parentBlock;
468     std::vector<ScicosID> children;
469
470     /**
471      * I/O Blocks: the corresponding parent port
472      */
473     ScicosID portReference;
474 };
475
476 } /* namespace model */
477 } /* namespace org_scilab_modules_scicos */
478
479 #endif /* BLOCK_HXX_ */