Xcos MVC: fix Diagrams's 'objs' property getter and setter
[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 == interfaceFunction)
239         {
240             return NO_CHANGES;
241         }
242
243         interfaceFunction = fun;
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     void getParentDiagram(ScicosID& v) const
316     {
317         v = parentDiagram;
318     }
319
320     update_status_t setParentDiagram(const ScicosID v)
321     {
322         if (v == parentDiagram)
323         {
324             return NO_CHANGES;
325         }
326
327         parentDiagram = v;
328         return SUCCESS;
329     }
330
331     ScicosID getPortReference() const
332     {
333         return portReference;
334     }
335
336     void setPortReference(ScicosID portReference)
337     {
338         this->portReference = portReference;
339     }
340
341     const Descriptor& getSim() const
342     {
343         return sim;
344     }
345
346     void setSim(const Descriptor& sim)
347     {
348         this->sim = sim;
349     }
350
351     void getStyle(std::string& data) const
352     {
353         data = style;
354     }
355
356     update_status_t setStyle(const std::string& data)
357     {
358         if (data == style)
359         {
360             return NO_CHANGES;
361         }
362
363         style = data;
364         return SUCCESS;
365     }
366
367     void getNZcross(int& data) const
368     {
369         data = nzcross;
370     }
371
372     update_status_t setNZcross(const int data)
373     {
374         if (data == nzcross)
375         {
376             return NO_CHANGES;
377         }
378
379         nzcross = data;
380         return SUCCESS;
381     }
382
383     void getNMode(int& data) const
384     {
385         data = nmode;
386     }
387
388     update_status_t setNMode(const int data)
389     {
390         if (data == nmode)
391         {
392             return NO_CHANGES;
393         }
394
395         nmode = data;
396         return SUCCESS;
397     }
398
399     void getUID(std::string& data) const
400     {
401         data = uid;
402     }
403
404     update_status_t setUID(const std::string& data)
405     {
406         if (data == uid)
407         {
408             return NO_CHANGES;
409         }
410
411         uid = data;
412         return SUCCESS;
413     }
414
415     void getRpar(std::vector<double>& data) const
416     {
417         data = parameter.rpar;
418     }
419
420     update_status_t setRpar(const std::vector<double>& data)
421     {
422         if (data == parameter.rpar)
423         {
424             return NO_CHANGES;
425         }
426
427         parameter.rpar = data;
428         return SUCCESS;
429     }
430
431     void getIpar(std::vector<int>& data) const
432     {
433         data = parameter.ipar;
434     }
435
436     update_status_t setIpar(const std::vector<int>& data)
437     {
438         if (data == parameter.ipar)
439         {
440             return NO_CHANGES;
441         }
442
443         parameter.ipar = data;
444         return SUCCESS;
445     }
446
447     void getSimFunctionName(std::string& data) const
448     {
449         data = sim.functionName;
450     }
451
452     update_status_t setSimFunctionName(const std::string& data)
453     {
454         if (data == sim.functionName)
455         {
456             return NO_CHANGES;
457         }
458
459         sim.functionName = data;
460         return SUCCESS;
461     }
462
463     void getSimFunctionApi(int& data) const
464     {
465         data = sim.functionApi;
466     }
467
468     update_status_t setSimFunctionApi(const int data)
469     {
470         if (data == sim.functionApi)
471         {
472             return NO_CHANGES;
473         }
474
475         sim.functionApi = data;
476         return SUCCESS;
477     }
478
479     void getSimBlocktype(std::string& data) const
480     {
481         data = std::string(1, sim.blocktype);
482     }
483
484     update_status_t setSimBlocktype(const std::string data)
485     {
486         if (data.size() != 1)
487         {
488             return FAIL;
489         }
490
491         char c = *(data.c_str());
492
493         if (c == sim.blocktype)
494         {
495             return NO_CHANGES;
496         }
497
498         switch (c)
499         {
500             case BLOCKTYPE_C:
501             case BLOCKTYPE_D:
502             case BLOCKTYPE_H:
503             case BLOCKTYPE_L:
504             case BLOCKTYPE_M:
505             case BLOCKTYPE_X:
506             case BLOCKTYPE_Z:
507                 sim.blocktype = c;
508                 return SUCCESS;
509             default:
510                 return FAIL;
511         }
512     }
513
514     void getSimDepUT(std::vector<int>& data) const
515     {
516         data.resize(2, 0);
517         switch (sim.dep_ut)
518         {
519             case DEP_U & DEP_T:
520                 // data is already set to [0 0] here.
521                 break;
522             case DEP_U:
523                 data[0] = 1;
524                 break;
525             case DEP_T:
526                 data[1] = 1;
527                 break;
528             case DEP_U | DEP_T:
529                 data[0] = 1;
530                 data[1] = 1;
531                 break;
532             default:
533                 break;
534         }
535     }
536
537     update_status_t setSimDepUT(const std::vector<int>& data)
538     {
539         if (data.size() != 2)
540         {
541             return FAIL;
542         }
543
544         int dep = DEP_U & DEP_T;
545         if (data[0])
546         {
547             if (data[1])
548             {
549                 dep = DEP_U | DEP_T;
550             }
551             else
552             {
553                 dep = DEP_U;
554             }
555         }
556         else if (data[1])
557         {
558             dep = DEP_T;
559         }
560
561         if (dep == sim.dep_ut)
562         {
563             return NO_CHANGES;
564         }
565
566         sim.dep_ut = dep;
567         return SUCCESS;
568     }
569
570     void getState(std::vector<double>& data) const
571     {
572         data = state.state;
573     }
574
575     update_status_t setState(const std::vector<double>& data)
576     {
577         if (data == state.state)
578         {
579             return NO_CHANGES;
580         }
581
582         state.state = data;
583         return SUCCESS;
584     }
585
586     void getDState(std::vector<double>& data) const
587     {
588         data = state.dstate;
589     }
590
591     update_status_t setDState(const std::vector<double>& data)
592     {
593         if (data == state.dstate)
594         {
595             return NO_CHANGES;
596         }
597
598         state.dstate = data;
599         return SUCCESS;
600     }
601
602 private:
603     ScicosID parentDiagram;
604     std::string interfaceFunction;
605     Geometry geometry;
606     Angle angle;
607     std::vector<std::string> exprs;
608     std::string label;
609     std::string style;
610     int nzcross;
611     int nmode;
612     // FIXME: find an appropriate way to store 'equations'
613     std::vector<std::string> equations;
614     std::string uid;
615
616     Descriptor sim;
617
618     std::vector<ScicosID> in;
619     std::vector<ScicosID> out;
620     std::vector<ScicosID> ein;
621     std::vector<ScicosID> eout;
622
623     Parameter parameter;
624     State state;
625
626     /**
627      * SuperBlock: the blocks, links and so on contained into this block
628      */
629     ScicosID parentBlock;
630     std::vector<ScicosID> children;
631
632     /**
633      * I/O Blocks: the corresponding parent port
634      */
635     ScicosID portReference;
636 };
637
638 } /* namespace model */
639 } /* namespace org_scilab_modules_scicos */
640
641 #endif /* BLOCK_HXX_ */