3d931e927c389d9a4fb274f515bcc08b00775c4f
[scilab.git] / scilab / modules / scicos / src / cpp / view_scilab / ModelAdapter.cpp
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 #include <cwchar>
14 #include <cstring>
15
16 #include <string>
17 #include <vector>
18 #include <algorithm>
19 #include <sstream>
20
21 #include "bool.hxx"
22 #include "double.hxx"
23 #include "string.hxx"
24 #include "list.hxx"
25 #include "tlist.hxx"
26 #include "user.hxx"
27
28 #include "Controller.hxx"
29 #include "Adapters.hxx"
30 #include "ModelAdapter.hxx"
31 #include "DiagramAdapter.hxx"
32 #include "ports_management.hxx"
33 #include "utilities.hxx"
34
35 #include "var2vec.hxx"
36 #include "vec2var.hxx"
37
38 extern "C" {
39 #include "sci_malloc.h"
40 #include "charEncoding.h"
41 }
42
43 namespace org_scilab_modules_scicos
44 {
45 namespace view_scilab
46 {
47 namespace
48 {
49
50 const std::string input ("input");
51 const std::string output ("output");
52 const std::string inimpl ("inimpl");
53 const std::string outimpl ("outimpl");
54
55 const std::wstring modelica (L"modelica");
56 const std::wstring model (L"model");
57 const std::wstring inputs (L"inputs");
58 const std::wstring outputs (L"outputs");
59 const std::wstring parameters (L"parameters");
60
61 struct sim
62 {
63
64     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
65     {
66         ScicosID adaptee = adaptor.getAdaptee()->id();
67
68         // First, extract the function Name
69         std::string name;
70         controller.getObjectProperty(adaptee, BLOCK, SIM_FUNCTION_NAME, name);
71         types::String* Name = new types::String(1, 1);
72         Name->set(0, name.data());
73
74         // Then the Api. If it is zero, then just return the Name. Otherwise, return a list containing both.
75         int api;
76         controller.getObjectProperty(adaptee, BLOCK, SIM_FUNCTION_API, api);
77
78         if (api == 0)
79         {
80             return Name;
81         }
82         else
83         {
84             types::Double* Api = new types::Double(static_cast<double>(api));
85             types::List* o = new types::List();
86             o->set(0, Name);
87             o->set(1, Api);
88             return o;
89         }
90     }
91
92     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
93     {
94         ScicosID adaptee = adaptor.getAdaptee()->id();
95
96         if (v->getType() == types::InternalType::ScilabString)
97         {
98             types::String* current = v->getAs<types::String>();
99             if (current->getSize() != 1)
100             {
101                 return false;
102             }
103
104             char* c_str = wide_string_to_UTF8(current->get(0));
105             std::string name(c_str);
106             FREE(c_str);
107
108             // If the input is a scalar string, then the functionApi is 0.
109             int api = 0;
110
111             controller.setObjectProperty(adaptee, BLOCK, SIM_FUNCTION_NAME, name);
112             controller.setObjectProperty(adaptee, BLOCK, SIM_FUNCTION_API, api);
113         }
114         else if (v->getType() == types::InternalType::ScilabList)
115         {
116             // If the input is a 2-sized list, then it must be string and positive integer.
117             types::List* current = v->getAs<types::List>();
118             if (current->getSize() != 2)
119             {
120                 return false;
121             }
122             if (current->get(0)->getType() != types::InternalType::ScilabString || current->get(1)->getType() != types::InternalType::ScilabDouble)
123             {
124                 return false;
125             }
126
127             types::String* Name = current->get(0)->getAs<types::String>();
128             if (Name->getSize() != 1)
129             {
130                 return false;
131             }
132             char* c_str = wide_string_to_UTF8(Name->get(0));
133             std::string name(c_str);
134             FREE(c_str);
135
136             types::Double* Api = current->get(1)->getAs<types::Double>();
137             if (Api->getSize() != 1)
138             {
139                 return false;
140             }
141             double api = Api->get(0);
142             if (floor(api) != api)
143             {
144                 return false;
145             }
146             int api_int = static_cast<int>(api);
147
148             controller.setObjectProperty(adaptee, BLOCK, SIM_FUNCTION_NAME, name);
149             controller.setObjectProperty(adaptee, BLOCK, SIM_FUNCTION_API, api_int);
150         }
151         else
152         {
153             return false;
154         }
155         return true;
156     }
157 };
158
159 struct in
160 {
161
162     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
163     {
164         return get_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, INPUTS, controller);
165     }
166
167     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
168     {
169         return update_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, INPUTS, controller, v);
170     }
171 };
172
173 struct in2
174 {
175
176     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
177     {
178         return get_ports_property<ModelAdapter, DATATYPE_COLS>(adaptor, INPUTS, controller);
179     }
180
181     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
182     {
183         return set_ports_property<ModelAdapter, DATATYPE_COLS>(adaptor, INPUTS, controller, v);
184     }
185 };
186
187 struct intyp
188 {
189
190     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
191     {
192         return get_ports_property<ModelAdapter, DATATYPE_TYPE>(adaptor, INPUTS, controller);
193     }
194
195     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
196     {
197         return set_ports_property<ModelAdapter, DATATYPE_TYPE>(adaptor, INPUTS, controller, v);
198     }
199 };
200
201 struct out
202 {
203
204     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
205     {
206         return get_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, OUTPUTS, controller);
207     }
208
209     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
210     {
211         return update_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, OUTPUTS, controller, v);
212     }
213 };
214
215 struct out2
216 {
217
218     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
219     {
220         return get_ports_property<ModelAdapter, DATATYPE_COLS>(adaptor, OUTPUTS, controller);
221     }
222
223     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
224     {
225         return set_ports_property<ModelAdapter, DATATYPE_COLS>(adaptor, OUTPUTS, controller, v);
226     }
227 };
228
229 struct outtyp
230 {
231
232     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
233     {
234         return get_ports_property<ModelAdapter, DATATYPE_TYPE>(adaptor, OUTPUTS, controller);
235     }
236
237     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
238     {
239         return set_ports_property<ModelAdapter, DATATYPE_TYPE>(adaptor, OUTPUTS, controller, v);
240     }
241 };
242
243 struct evtin
244 {
245
246     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
247     {
248         return get_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, EVENT_INPUTS, controller);
249     }
250
251     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
252     {
253         return update_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, EVENT_INPUTS, controller, v);
254     }
255 };
256
257 struct evtout
258 {
259
260     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
261     {
262         return get_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, EVENT_OUTPUTS, controller);
263     }
264
265     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
266     {
267         return update_ports_property<ModelAdapter, DATATYPE_ROWS>(adaptor, EVENT_OUTPUTS, controller, v);
268     }
269 };
270
271 struct state
272 {
273
274     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
275     {
276         ScicosID adaptee = adaptor.getAdaptee()->id();
277
278         std::vector<double> state;
279         controller.getObjectProperty(adaptee, BLOCK, STATE, state);
280
281         double* data;
282         types::Double* o = new types::Double((int)state.size(), 1, &data);
283
284 #ifdef _MSC_VER
285         std::copy(state.begin(), state.end(), stdext::checked_array_iterator<double*>(data, state.size()));
286 #else
287         std::copy(state.begin(), state.end(), data);
288 #endif
289         return o;
290     }
291
292     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
293     {
294
295         if (v->getType() != types::InternalType::ScilabDouble)
296         {
297             return false;
298         }
299
300         types::Double* current = v->getAs<types::Double>();
301         // Only allow vectors and empty matrices
302         if (!current->isVector() && current->getSize() != 0)
303         {
304             return false;
305         }
306
307         ScicosID adaptee = adaptor.getAdaptee()->id();
308
309         std::vector<double> state (current->getSize());
310         std::copy(current->getReal(), current->getReal() + current->getSize(), state.begin());
311
312         controller.setObjectProperty(adaptee, BLOCK, STATE, state);
313         return true;
314     }
315 };
316
317 struct dstate
318 {
319
320     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
321     {
322         ScicosID adaptee = adaptor.getAdaptee()->id();
323
324         std::vector<double> dstate;
325         controller.getObjectProperty(adaptee, BLOCK, DSTATE, dstate);
326
327         double* data;
328         types::Double* o = new types::Double((int)dstate.size(), 1, &data);
329
330 #ifdef _MSC_VER
331         std::copy(dstate.begin(), dstate.end(), stdext::checked_array_iterator<double*>(data, dstate.size()));
332 #else
333         std::copy(dstate.begin(), dstate.end(), data);
334 #endif
335         return o;
336     }
337
338     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
339     {
340         ScicosID adaptee = adaptor.getAdaptee()->id();
341
342         if (v->getType() == types::InternalType::ScilabString)
343         {
344             types::String* current = v->getAs<types::String>();
345             if (current->getSize() != 1)
346             {
347                 return false;
348             }
349
350             std::vector<double> dstate;
351             controller.setObjectProperty(adaptee, BLOCK, DSTATE, dstate);
352             return true;
353         }
354
355         if (v->getType() != types::InternalType::ScilabDouble)
356         {
357             return false;
358         }
359         types::Double* current = v->getAs<types::Double>();
360         // Only allow vectors and empty matrices
361         if (!current->isVector() && current->getSize() != 0)
362         {
363             return false;
364         }
365
366         std::vector<double> dstate (current->getSize());
367         std::copy(current->getReal(), current->getReal() + current->getSize(), dstate.begin());
368
369         controller.setObjectProperty(adaptee, BLOCK, DSTATE, dstate);
370         return true;
371     }
372 };
373
374 struct odstate
375 {
376
377     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
378     {
379         ScicosID adaptee = adaptor.getAdaptee()->id();
380
381         std::vector<double> prop_content;
382         controller.getObjectProperty(adaptee, BLOCK, ODSTATE, prop_content);
383
384         // Corner-case, the empty content is an empty double
385         if (prop_content.empty())
386         {
387             return types::Double::Empty();
388         }
389
390         // The returned value is a list
391         types::InternalType* res;
392         if (!vec2var(prop_content, res))
393         {
394             return 0;
395         }
396
397         return res;
398     }
399
400     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
401     {
402         ScicosID adaptee = adaptor.getAdaptee()->id();
403
404         // corner-case the empty content is an empty-double
405         if (v->getType() == types::InternalType::ScilabDouble)
406         {
407             types::Double* current = v->getAs<types::Double>();
408             if (current->getSize() != 0)
409             {
410                 return false;
411             }
412
413             // prop_content is empty
414             std::vector<double> prop_content;
415             controller.setObjectProperty(adaptee, BLOCK, ODSTATE, prop_content);
416             return true;
417         }
418
419         std::vector<double> prop_content;
420         if (!var2vec(v, prop_content))
421         {
422             return false;
423         }
424
425         controller.setObjectProperty(adaptee, BLOCK, ODSTATE, prop_content);
426         return true;
427     }
428 };
429
430 /*
431  * When setting a diagram in 'rpar', the Superblock's ports must be consistent with the "port blocks" inside it.
432  * By "port blocks", we mean IN_f, OUT_f, CLKIN_f, CLKOUT_f, CLKINV_f, CLKOUTV_f, INIMPL_f and OUTIMPL_f.
433  */
434 bool setInnerBlocksRefs(ModelAdapter& adaptor, const std::vector<ScicosID>& children, Controller& controller)
435 {
436     ScicosID adaptee = adaptor.getAdaptee()->id();
437
438     for (std::vector<ScicosID>::const_iterator it = children.begin(); it != children.end(); ++it)
439     {
440         if (controller.getObject(*it)->kind() == BLOCK) // Rule out Annotations and Links
441         {
442             std::string name;
443             controller.getObjectProperty(*it, BLOCK, SIM_FUNCTION_NAME, name);
444
445             // Find the "port blocks"
446             if (name == input || name == inimpl || name == output || name == outimpl)
447             {
448                 std::vector<int> ipar;
449                 controller.getObjectProperty(*it, BLOCK, IPAR, ipar);
450                 if (ipar.size() != 1)
451                 {
452                     return false;
453                 }
454                 int portIndex = ipar[0];
455
456                 // "name" is not enough to tell the event and data ports apart, so check the block's port.
457                 object_properties_t kind;
458                 std::vector<ScicosID> innerPort;
459                 if (name == input || name == inimpl)
460                 {
461                     controller.getObjectProperty(*it, BLOCK, OUTPUTS, innerPort);
462                     if (!innerPort.empty())
463                     {
464                         kind = INPUTS;
465                     }
466                     else
467                     {
468                         kind = EVENT_INPUTS;
469                     }
470                 }
471                 else
472                 {
473                     controller.getObjectProperty(*it, BLOCK, INPUTS, innerPort);
474                     if (!innerPort.empty())
475                     {
476                         kind = OUTPUTS;
477                     }
478                     else
479                     {
480                         kind = EVENT_OUTPUTS;
481                     }
482                 }
483
484                 std::vector<ScicosID> superPorts;
485                 controller.getObjectProperty(adaptee, BLOCK, kind, superPorts);
486                 if (static_cast<int>(superPorts.size()) < portIndex)
487                 {
488                     return false;
489                 }
490
491                 ScicosID port = superPorts[portIndex - 1];
492
493                 // Check consistency of the implicitness between the inner and outer ports
494                 bool isImplicit;
495                 controller.getObjectProperty(port, PORT, IMPLICIT, isImplicit);
496                 if (name == input || name == output)
497                 {
498                     if (isImplicit)
499                     {
500                         return false;
501                     }
502                 }
503                 else
504                 {
505                     if (!isImplicit)
506                     {
507                         return false;
508                     }
509                 }
510
511                 controller.setObjectProperty(*it, BLOCK, PORT_REFERENCE, port);
512             }
513         }
514     }
515     return true;
516 }
517
518 struct rpar
519 {
520
521     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
522     {
523         ScicosID adaptee = adaptor.getAdaptee()->id();
524
525         std::vector<ScicosID> diagramChildren;
526         controller.getObjectProperty(adaptee, BLOCK, CHILDREN, diagramChildren);
527
528         if (diagramChildren.empty())
529         {
530             std::vector<double> rpar;
531             controller.getObjectProperty(adaptee, BLOCK, RPAR, rpar);
532
533             double *data;
534             types::Double* o = new types::Double((int)rpar.size(), 1, &data);
535 #ifdef _MSC_VER
536             std::copy(rpar.begin(), rpar.end(), stdext::checked_array_iterator<double*>(data, rpar.size()));
537 #else
538             std::copy(rpar.begin(), rpar.end(), data);
539 #endif
540             return o;
541         }
542         else // SuperBlock, return the contained diagram (allocating it on demand)
543         {
544             DiagramAdapter* diagram = adaptor.getDiagram();
545
546             /*
547              * FIXME: Sync all diagram children as the blocks might be modified by xcos
548              */
549
550             return diagram;
551         }
552     }
553
554     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
555     {
556         ScicosID adaptee = adaptor.getAdaptee()->id();
557
558         if (v->getType() == types::InternalType::ScilabDouble)
559         {
560             types::Double* current = v->getAs<types::Double>();
561
562             std::vector<double> rpar (current->getSize());
563             for (int i = 0; i < current->getSize(); ++i)
564             {
565                 rpar[i] = current->get(i);
566             }
567
568             controller.setObjectProperty(adaptee, BLOCK, RPAR, rpar);
569             return true;
570         }
571         else if (v->getType() == types::InternalType::ScilabString)
572         {
573             // Allow Text blocks to define strings in rpar
574             return true;
575         }
576         else if (v->getType() == types::InternalType::ScilabUserType)
577         {
578             // Make sure the input describes a Diagram
579             const Adapters::adapters_index_t adapter_index = Adapters::instance().lookup_by_typename(v->getShortTypeStr());
580             if (adapter_index != Adapters::DIAGRAM_ADAPTER)
581             {
582                 return false;
583             }
584
585             // Translate 'v' to an DiagramAdapter ; copy if needed
586             DiagramAdapter* diagram;
587             if (v->getRef() > 1)
588             {
589                 diagram = v->clone()->getAs<DiagramAdapter>();
590             }
591             else
592             {
593                 diagram = v->getAs<DiagramAdapter>();
594             }
595             adaptor.setDiagram(diagram);
596
597             // set the diagram children as block children ; referencing them
598             std::vector<ScicosID> diagramChildren;
599             controller.getObjectProperty(diagram->getAdaptee()->id(), DIAGRAM, CHILDREN, diagramChildren);
600             std::vector<ScicosID> oldDiagramChildren;
601             controller.getObjectProperty(adaptor.getAdaptee()->id(), BLOCK, CHILDREN, oldDiagramChildren);
602
603             controller.setObjectProperty(adaptor.getAdaptee()->id(), BLOCK, CHILDREN, diagramChildren);
604             {
605                 std::sort(oldDiagramChildren.begin(), oldDiagramChildren.end());
606                 for (const ScicosID id : diagramChildren)
607                 {
608                     if (id != 0 && !std::binary_search(oldDiagramChildren.begin(), oldDiagramChildren.end(), id))
609                     {
610                         auto o = controller.getObject(id);
611                         controller.setObjectProperty(o->id(), o->kind(), PARENT_BLOCK, adaptor.getAdaptee()->id());
612
613                         controller.referenceObject(id);
614                     }
615                 }
616
617                 std::sort(diagramChildren.begin(), diagramChildren.end());
618                 for (const ScicosID id : oldDiagramChildren)
619                 {
620                     if (id != 0 && !std::binary_search(diagramChildren.begin(), diagramChildren.end(), id))
621                     {
622                         auto o = controller.getObject(id);
623                         controller.setObjectProperty(o->id(), o->kind(), PARENT_BLOCK, ScicosID());
624
625                         controller.deleteObject(id);
626                     }
627                 }
628             }
629
630             // Link the Superblock ports to their inner "port blocks"
631             return setInnerBlocksRefs(adaptor, diagramChildren, controller);
632         }
633         else
634         {
635             return false;
636         }
637     }
638 };
639
640 double toDouble(const int a)
641 {
642     return static_cast<double>(a);
643 }
644
645 struct ipar
646 {
647
648     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
649     {
650         ScicosID adaptee = adaptor.getAdaptee()->id();
651
652         std::vector<int> ipar;
653         controller.getObjectProperty(adaptee, BLOCK, IPAR, ipar);
654
655         double *data;
656         types::Double* o = new types::Double((int)ipar.size(), 1, &data);
657
658 #ifdef _MSC_VER
659         std::transform(ipar.begin(), ipar.end(), stdext::checked_array_iterator<double*>(data, ipar.size()), toDouble);
660 #else
661         std::transform(ipar.begin(), ipar.end(), data, toDouble);
662 #endif
663         return o;
664     }
665
666     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
667     {
668         ScicosID adaptee = adaptor.getAdaptee()->id();
669
670         if (v->getType() == types::InternalType::ScilabList)
671         {
672             std::vector<int> ipar;
673             controller.setObjectProperty(adaptee, BLOCK, IPAR, ipar);
674             return true;
675         }
676
677         if (v->getType() != types::InternalType::ScilabDouble)
678         {
679             return false;
680         }
681
682         types::Double* current = v->getAs<types::Double>();
683         if (current->getCols() != 0 && current->getCols() != 1)
684         {
685             return false;
686         }
687
688         std::vector<int> ipar (current->getSize());
689         for (int i = 0; i < current->getSize(); ++i)
690         {
691             if (floor(current->get(i)) != current->get(i))
692             {
693                 return false;
694             }
695             ipar[i] = static_cast<int>(current->get(i));
696         }
697
698         controller.setObjectProperty(adaptee, BLOCK, IPAR, ipar);
699         return true;
700     }
701 };
702
703 struct opar
704 {
705
706     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
707     {
708         ScicosID adaptee = adaptor.getAdaptee()->id();
709
710         std::vector<double> prop_content;
711         controller.getObjectProperty(adaptee, BLOCK, OPAR, prop_content);
712
713         // Corner-case, the empty content is an empty double
714         if (prop_content.empty())
715         {
716             return types::Double::Empty();
717         }
718
719         // The returned value is a list
720         types::InternalType* res;
721         if (!vec2var(prop_content, res))
722         {
723             return 0;
724         }
725
726         return res;
727     }
728
729     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
730     {
731         ScicosID adaptee = adaptor.getAdaptee()->id();
732
733         // corner-case the empty content is an empty-double
734         if (v->getType() == types::InternalType::ScilabDouble)
735         {
736             types::Double* current = v->getAs<types::Double>();
737             if (current->getSize() != 0)
738             {
739                 return false;
740             }
741
742             // prop_content should be empty
743             std::vector<double> prop_content;
744             controller.setObjectProperty(adaptee, BLOCK, OPAR, prop_content);
745             return true;
746         }
747
748         std::vector<double> prop_content;
749         if (!var2vec(v, prop_content))
750         {
751             return false;
752         }
753
754         controller.setObjectProperty(adaptee, BLOCK, OPAR, prop_content);
755         return true;
756     }
757 };
758
759 struct blocktype
760 {
761
762     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
763     {
764         ScicosID adaptee = adaptor.getAdaptee()->id();
765
766         std::string type;
767         controller.getObjectProperty(adaptee, BLOCK, SIM_BLOCKTYPE, type);
768
769         types::String* o = new types::String(type.c_str());
770         return o;
771     }
772
773     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
774     {
775         ScicosID adaptee = adaptor.getAdaptee()->id();
776
777         if (v->getType() != types::InternalType::ScilabString)
778         {
779             return false;
780         }
781
782         types::String* current = v->getAs<types::String>();
783         if (current->getSize() != 1)
784         {
785             return false;
786         }
787
788         char* c_str = wide_string_to_UTF8(current->get(0));
789         std::string type (c_str);
790         FREE(c_str);
791
792         // the value validation is performed on the model
793         return controller.setObjectProperty(adaptee, BLOCK, SIM_BLOCKTYPE, type) != FAIL;
794     }
795 };
796
797 struct firing
798 {
799
800     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
801     {
802         return get_ports_property<ModelAdapter, FIRING>(adaptor, EVENT_OUTPUTS, controller);
803     }
804
805     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
806     {
807         return set_ports_property<ModelAdapter, FIRING>(adaptor, EVENT_OUTPUTS, controller, v);
808     }
809 };
810
811 struct dep_ut
812 {
813
814     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
815     {
816         ScicosID adaptee = adaptor.getAdaptee()->id();
817
818         std::vector<int> dep_ut;
819         controller.getObjectProperty(adaptee, BLOCK, SIM_DEP_UT, dep_ut);
820
821         int* dep;
822         types::Bool* o = new types::Bool(1, 2, &dep);
823
824         dep[0] = dep_ut[0];
825         dep[1] = dep_ut[1];
826
827         return o;
828     }
829
830     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
831     {
832         ScicosID adaptee = adaptor.getAdaptee()->id();
833
834         if (v->getType() != types::InternalType::ScilabBool)
835         {
836             return false;
837         }
838
839         types::Bool* current = v->getAs<types::Bool>();
840         if (current->getRows() != 1 || current->getCols() != 2)
841         {
842             return false;
843         }
844
845         std::vector<int> dep_ut (2);
846         dep_ut[0] = current->get(0);
847         dep_ut[1] = current->get(1);
848
849         controller.setObjectProperty(adaptee, BLOCK, SIM_DEP_UT, dep_ut);
850         return true;
851     }
852 };
853
854 struct label
855 {
856
857     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
858     {
859         ScicosID adaptee = adaptor.getAdaptee()->id();
860
861         std::string label;
862         controller.getObjectProperty(adaptee, BLOCK, LABEL, label);
863
864         types::String* o = new types::String(1, 1);
865         o->set(0, label.data());
866
867         return o;
868     }
869
870     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
871     {
872         if (v->getType() != types::InternalType::ScilabString)
873         {
874             return false;
875         }
876
877         types::String* current = v->getAs<types::String>();
878         if (current->getSize() != 1)
879         {
880             return false;
881         }
882
883         ScicosID adaptee = adaptor.getAdaptee()->id();
884
885         char* c_str = wide_string_to_UTF8(current->get(0));
886         std::string label(c_str);
887         FREE(c_str);
888
889         controller.setObjectProperty(adaptee, BLOCK, LABEL, label);
890         return true;
891     }
892 };
893
894 struct nzcross
895 {
896
897     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
898     {
899         ScicosID adaptee = adaptor.getAdaptee()->id();
900
901         std::vector<int> nzcross;
902         controller.getObjectProperty(adaptee, BLOCK, NZCROSS, nzcross);
903
904         double *data;
905         types::Double* o = new types::Double((int)nzcross.size(), 1, &data);
906
907 #ifdef _MSC_VER
908         std::transform(nzcross.begin(), nzcross.end(), stdext::checked_array_iterator<double*>(data, nzcross.size()), toDouble);
909 #else
910         std::transform(nzcross.begin(), nzcross.end(), data, toDouble);
911 #endif
912         return o;
913     }
914
915     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
916     {
917         ScicosID adaptee = adaptor.getAdaptee()->id();
918
919         if (v->getType() != types::InternalType::ScilabDouble)
920         {
921             return false;
922         }
923
924         types::Double* current = v->getAs<types::Double>();
925         // Only allow vectors and empty matrices
926         if (!current->isVector() && current->getSize() != 0)
927         {
928             return false;
929         }
930
931         std::vector<int> nzcross (current->getSize());
932         for (int i = 0; i < current->getSize(); ++i)
933         {
934             if (floor(current->get(i)) != current->get(i))
935             {
936                 return false;
937             }
938             nzcross[i] = static_cast<int>(current->get(i));
939         }
940
941         controller.setObjectProperty(adaptee, BLOCK, NZCROSS, nzcross);
942         return true;
943     }
944 };
945
946 struct nmode
947 {
948
949     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
950     {
951         ScicosID adaptee = adaptor.getAdaptee()->id();
952
953         std::vector<int> nmode;
954         controller.getObjectProperty(adaptee, BLOCK, NMODE, nmode);
955
956         double *data;
957         types::Double* o = new types::Double((int)nmode.size(), 1, &data);
958
959 #ifdef _MSC_VER
960         std::transform(nmode.begin(), nmode.end(), stdext::checked_array_iterator<double*>(data, nmode.size()), toDouble);
961 #else
962         std::transform(nmode.begin(), nmode.end(), data, toDouble);
963 #endif
964         return o;
965     }
966
967     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
968     {
969         ScicosID adaptee = adaptor.getAdaptee()->id();
970
971         if (v->getType() != types::InternalType::ScilabDouble)
972         {
973             return false;
974         }
975
976         types::Double* current = v->getAs<types::Double>();
977         // Only allow vectors and empty matrices
978         if (!current->isVector() && current->getSize() != 0)
979         {
980             return false;
981         }
982
983         std::vector<int> nmode (current->getSize());
984         for (int i = 0; i < current->getSize(); ++i)
985         {
986             if (floor(current->get(i)) != current->get(i))
987             {
988                 return false;
989             }
990             nmode[i] = static_cast<int>(current->get(i));
991         }
992
993         controller.setObjectProperty(adaptee, BLOCK, NMODE, nmode);
994         return true;
995     }
996 };
997
998 struct equations
999 {
1000
1001     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
1002     {
1003         ScicosID adaptee = adaptor.getAdaptee()->id();
1004
1005         std::vector<std::string> equations;
1006         controller.getObjectProperty(adaptee, BLOCK, EQUATIONS, equations);
1007
1008         if (equations.size() == 0)
1009         {
1010             return new types::List();
1011         }
1012
1013         types::TList* o = new types::TList();
1014
1015         // Header, starting with "modelica"
1016         types::String* header = new types::String(1, 5);
1017         header->set(0, modelica.c_str());
1018         header->set(1, model.c_str());
1019         header->set(2, inputs.c_str());
1020         header->set(3, outputs.c_str());
1021         header->set(4, parameters.c_str());
1022         o->set(0, header);
1023
1024         // 'model'
1025         if (equations[0].c_str() == std::string())
1026         {
1027             o->set(1, types::Double::Empty());
1028         }
1029         else
1030         {
1031             types::String* modelField = new types::String(1, 1);
1032             modelField->set(0, equations[0].c_str());
1033             o->set(1, modelField);
1034         }
1035
1036         // 'inputs'
1037         std::istringstream inputsSizeStr (equations[1]);
1038         int inputsSize;
1039         inputsSizeStr >> inputsSize;
1040         if (inputsSize == 0)
1041         {
1042             types::Double* inputsField = types::Double::Empty();
1043             o->set(2, inputsField);
1044         }
1045         else
1046         {
1047             types::String* inputsField = new types::String(inputsSize, 1);
1048             for (int i = 0; i < inputsSize; ++i)
1049             {
1050                 inputsField->set(i, equations[i + 2].c_str());
1051             }
1052             o->set(2, inputsField);
1053         }
1054
1055         // 'outputs'
1056         std::istringstream outputsSizeStr (equations[2 + inputsSize]);
1057         int outputsSize;
1058         outputsSizeStr >> outputsSize;
1059         if (outputsSize == 0)
1060         {
1061             types::Double* outputsField = types::Double::Empty();
1062             o->set(3, outputsField);
1063         }
1064         else
1065         {
1066             types::String* outputsField = new types::String(outputsSize, 1);
1067             for (int i = 0; i < outputsSize; ++i)
1068             {
1069                 outputsField->set(i, equations[i + 3 + inputsSize].c_str());
1070             }
1071             o->set(3, outputsField);
1072         }
1073
1074         // 'parameters'
1075         types::List* parametersField = new types::List();
1076
1077         // 'parameters' names
1078         std::istringstream parametersSizeStr (equations[3 + inputsSize + outputsSize]);
1079         int parametersSize;
1080         parametersSizeStr >> parametersSize;
1081         if (parametersSize == 0)
1082         {
1083             types::Double* parametersNames = types::Double::Empty();
1084             parametersField->set(0, parametersNames);
1085         }
1086         else
1087         {
1088             types::String* parametersNames = new types::String(parametersSize, 1);
1089             for (int i = 0; i < parametersSize; ++i)
1090             {
1091                 parametersNames->set(i, equations[i + 4 + inputsSize + outputsSize].c_str());
1092             }
1093             parametersField->set(0, parametersNames);
1094         }
1095
1096         // 'parameters' values
1097         types::List* parametersValues = new types::List();
1098         for (int i = 0; i < parametersSize; ++i)
1099         {
1100             std::istringstream parametersValueStr (equations[i + 4 + inputsSize + outputsSize + parametersSize]);
1101             double parametersVal;
1102             parametersValueStr >> parametersVal;
1103             types::Double* parametersValue = new types::Double(parametersVal);
1104             parametersValues->set(i, parametersValue);
1105         }
1106         parametersField->set(1, parametersValues);
1107
1108         // 'parameters' states (optional, only check its presence if at least one parameter is present)
1109         if (parametersSize != 0)
1110         {
1111             std::string parametersStatesBool (equations[4 + inputsSize + outputsSize + 2 * parametersSize]);
1112             if (strcmp(parametersStatesBool.c_str(), "T") == 0) // Check the presence of the "states" field
1113             {
1114                 types::Double* parametersStates = new types::Double(parametersSize, 1);
1115                 for (int i = 0; i < parametersSize; ++i)
1116                 {
1117                     std::istringstream parametersStateStr (equations[i + 5 + inputsSize + outputsSize + 2 * parametersSize]);
1118                     double parametersState;
1119                     parametersStateStr >> parametersState;
1120                     parametersStates->set(i, parametersState);
1121                 }
1122                 parametersField->set(2, parametersStates);
1123             }
1124         }
1125
1126         o->set(4, parametersField);
1127
1128         return o;
1129     }
1130
1131     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
1132     {
1133         ScicosID adaptee = adaptor.getAdaptee()->id();
1134
1135         if (v->getType() == types::InternalType::ScilabList)
1136         {
1137             types::List* current = v->getAs<types::List>();
1138             if (current->getSize() != 0)
1139             {
1140                 return false;
1141             }
1142             return true;
1143         }
1144
1145         if (v->getType() != types::InternalType::ScilabTList)
1146         {
1147             return false;
1148         }
1149
1150         types::TList* current = v->getAs<types::TList>();
1151
1152         // Check the header
1153         types::String* header = current->getFieldNames();
1154         if (header->getSize() != 5)
1155         {
1156             return false;
1157         }
1158         if (header->get(0) != modelica)
1159         {
1160             return false;
1161         }
1162         if (header->get(1) != model)
1163         {
1164             return false;
1165         }
1166         if (header->get(2) != inputs)
1167         {
1168             return false;
1169         }
1170         if (header->get(3) != outputs)
1171         {
1172             return false;
1173         }
1174         if (header->get(4) != parameters)
1175         {
1176             return false;
1177         }
1178
1179         char* c_str; // Temporary buffer used for conversions
1180
1181         // 'model'
1182         std::vector<std::string> equations;
1183         if (current->get(1)->getType() == types::InternalType::ScilabString)
1184         {
1185             types::String* modelField = current->get(1)->getAs<types::String>();
1186             if (modelField->getSize() != 1)
1187             {
1188                 return false;
1189             }
1190
1191             c_str = wide_string_to_UTF8(modelField->get(0));
1192             std::string modelFieldStored(c_str);
1193             FREE(c_str);
1194             equations.push_back(modelFieldStored);
1195         }
1196         else if (current->get(1)->getType() == types::InternalType::ScilabDouble)
1197         {
1198             types::Double* modelFieldDouble = current->get(1)->getAs<types::Double>();
1199             if (modelFieldDouble->getSize() != 0)
1200             {
1201                 return false;
1202             }
1203
1204             // An empty matrix stores an empty string, which will later be translated back to an empty matrix
1205             equations.push_back(std::string());
1206         }
1207         else
1208         {
1209             return false;
1210         }
1211
1212         // 'inputs'
1213         size_t inputsSize;
1214         if (current->get(2)->getType() == types::InternalType::ScilabDouble)
1215         {
1216             types::Double* inputsField = current->get(2)->getAs<types::Double>();
1217             if (inputsField->getSize() != 0)
1218             {
1219                 return false;
1220             }
1221
1222             inputsSize = 0;
1223             std::ostringstream strInputs;
1224             strInputs << inputsSize;
1225             std::string inputsSizeStr = strInputs.str();
1226             equations.push_back(inputsSizeStr); // When 'inputs'=[], just insert "0" in 'equations'
1227         }
1228         else
1229         {
1230             if (current->get(2)->getType() != types::InternalType::ScilabString)
1231             {
1232                 return false;
1233             }
1234
1235             types::String* inputsField = current->get(2)->getAs<types::String>();
1236             inputsSize = inputsField->getSize();
1237             equations.resize(equations.size() + 1 + inputsSize);
1238             std::ostringstream strInputs;
1239             strInputs << inputsSize;
1240             std::string inputsSizeStr = strInputs.str();
1241             equations[1] = inputsSizeStr; // Saving the size of the 'inputs' field'
1242             for (size_t i = 0; i < inputsSize; ++i)
1243             {
1244                 c_str = wide_string_to_UTF8(inputsField->get(static_cast<int>(i)));
1245                 std::string inputsFieldStored(c_str);
1246                 FREE(c_str);
1247                 equations[i + 2] = inputsFieldStored;
1248             }
1249         }
1250
1251         // 'outputs'
1252         size_t outputsSize;
1253         if (current->get(3)->getType() == types::InternalType::ScilabDouble)
1254         {
1255             types::Double* outputsField = current->get(3)->getAs<types::Double>();
1256             if (outputsField->getSize() != 0)
1257             {
1258                 return false;
1259             }
1260
1261             outputsSize = 0;
1262             std::ostringstream strOutputs;
1263             strOutputs << outputsSize;
1264             std::string outputsSizeStr = strOutputs.str();
1265             equations.push_back(outputsSizeStr); // When 'outputs'=[], just insert "0" in 'equations'
1266         }
1267         else
1268         {
1269             if (current->get(3)->getType() != types::InternalType::ScilabString)
1270             {
1271                 return false;
1272             }
1273
1274             types::String* outputsField = current->get(3)->getAs<types::String>();
1275             outputsSize = outputsField->getSize();
1276             equations.resize(equations.size() + 1 + outputsSize);
1277             std::ostringstream strOutputs;
1278             strOutputs << outputsSize;
1279             std::string outputsSizeStr = strOutputs.str();
1280             equations[2 + inputsSize] = outputsSizeStr; // Saving the size of the 'outputs' field'
1281             for (size_t i = 0; i < outputsSize; ++i)
1282             {
1283                 c_str = wide_string_to_UTF8(outputsField->get(static_cast<int>(i)));
1284                 std::string outputsFieldStored(c_str);
1285                 FREE(c_str);
1286                 equations[i + 3 + inputsSize] = outputsFieldStored;
1287             }
1288         }
1289
1290         // 'parameters'
1291         int parametersIndex = 4;
1292         if (current->get(parametersIndex)->getType() == types::InternalType::ScilabDouble)
1293         {
1294             // For backward compatibility sake, allow the presence of an empty matrix here
1295             types::Double* emptyMatrix = current->get(parametersIndex)->getAs<types::Double>();
1296             if (emptyMatrix->getSize() != 0)
1297             {
1298                 return false;
1299             }
1300
1301             parametersIndex++;
1302         }
1303
1304         if (current->get(parametersIndex)->getType() != types::InternalType::ScilabList)
1305         {
1306             return false;
1307         }
1308
1309         types::List* list = current->get(parametersIndex)->getAs<types::List>();
1310         if (list->getSize() != 2 && list->getSize() != 3)
1311         {
1312             return false;
1313         }
1314
1315         // 'parameters' names
1316         size_t parametersSize;
1317         if (list->get(0)->getType() == types::InternalType::ScilabDouble)
1318         {
1319             types::Double* parametersNames = list->get(0)->getAs<types::Double>();
1320             if (parametersNames->getSize() != 0)
1321             {
1322                 return false;
1323             }
1324
1325             // When 'parameters(1)'=[], just insert "0" in 'equations', set in the model and return
1326             parametersSize = 0;
1327             std::ostringstream strParameters;
1328             strParameters << parametersSize;
1329             std::string parametersSizeStr = strParameters.str();
1330             equations.push_back(parametersSizeStr);
1331
1332             controller.setObjectProperty(adaptee, BLOCK, EQUATIONS, equations);
1333             return true;
1334         }
1335         else
1336         {
1337             if (list->get(0)->getType() != types::InternalType::ScilabString)
1338             {
1339                 return false;
1340             }
1341
1342             types::String* parametersNames = list->get(0)->getAs<types::String>();
1343             parametersSize = parametersNames->getSize();
1344             equations.resize(equations.size() + 1 + parametersSize);
1345             std::ostringstream strParameters;
1346             strParameters << parametersSize;
1347             std::string parametersSizeStr = strParameters.str();
1348             equations[3 + inputsSize + outputsSize] = parametersSizeStr; // Saving the size of the 'parameters' field'
1349             for (size_t i = 0; i < parametersSize; ++i)
1350             {
1351                 c_str = wide_string_to_UTF8(parametersNames->get(static_cast<int>(i)));
1352                 std::string parametersName(c_str);
1353                 FREE(c_str);
1354                 equations[i + 4 + inputsSize + outputsSize] = parametersName;
1355             }
1356         }
1357
1358         // 'parameters' values
1359         if (list->get(1)->getType() == types::InternalType::ScilabDouble)
1360         {
1361             types::Double* parameterVal = list->get(1)->getAs<types::Double>();
1362             if (parameterVal->getSize() != static_cast<int>(parametersSize))
1363             {
1364                 return false;
1365             }
1366
1367             for (size_t i = 0; i < parametersSize; ++i)
1368             {
1369                 std::ostringstream strParameterVal;
1370                 strParameterVal << parameterVal->get(static_cast<int>(i));
1371                 std::string parameterValStr = strParameterVal.str();
1372                 equations.push_back(parameterValStr);
1373             }
1374         }
1375         else
1376         {
1377             if (list->get(1)->getType() != types::InternalType::ScilabList)
1378             {
1379                 return false;
1380             }
1381
1382             types::List* list2 = list->get(1)->getAs<types::List>();
1383             if (list2->getSize() != static_cast<int>(parametersSize))
1384             {
1385                 return false;
1386             }
1387
1388             equations.resize(equations.size() + parametersSize);
1389             for (size_t i = 0; i < parametersSize; ++i)
1390             {
1391                 if (list2->get(static_cast<int>(i))->getType() != types::InternalType::ScilabDouble)
1392                 {
1393                     return false;
1394                 }
1395
1396                 types::Double* parametersVal = list2->get(static_cast<int>(i))->getAs<types::Double>();
1397                 if (parametersVal->getSize() != 1)
1398                 {
1399                     return false;
1400                 }
1401
1402                 std::ostringstream strParametersVal;
1403                 strParametersVal << parametersVal->get(0);
1404                 std::string parametersValStr = strParametersVal.str();
1405                 equations[i + 4 + inputsSize + outputsSize + parametersSize] = parametersValStr;
1406             }
1407         }
1408
1409         // 'parameters' states (optional)
1410         equations.push_back("F"); // String boolean to indicate the presence, or not, of a "states" field
1411         if (list->getSize() == 3)
1412         {
1413             equations.back() = "T";
1414             if (list->get(2)->getType() != types::InternalType::ScilabDouble)
1415             {
1416                 return false;
1417             }
1418
1419             types::Double* parameterStates = list->get(2)->getAs<types::Double>();
1420             if (parameterStates->getSize() != static_cast<int>(parametersSize))
1421             {
1422                 return false;
1423             }
1424
1425             for (size_t i = 0; i < parametersSize; ++i)
1426             {
1427                 std::ostringstream strParameterStates;
1428                 strParameterStates << parameterStates->get(static_cast<int>(i));
1429                 std::string parameterStatesStr = strParameterStates.str();
1430                 equations.push_back(parameterStatesStr);
1431             }
1432         }
1433
1434         controller.setObjectProperty(adaptee, BLOCK, EQUATIONS, equations);
1435         return true;
1436     }
1437 };
1438
1439 struct uid
1440 {
1441
1442     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
1443     {
1444         ScicosID adaptee = adaptor.getAdaptee()->id();
1445
1446         std::string uid;
1447         controller.getObjectProperty(adaptee, BLOCK, UID, uid);
1448
1449         types::String* o = new types::String(1, 1);
1450         o->set(0, uid.data());
1451
1452         return o;
1453     }
1454
1455     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
1456     {
1457         if (v->getType() != types::InternalType::ScilabString)
1458         {
1459             return false;
1460         }
1461
1462         types::String* current = v->getAs<types::String>();
1463         if (current->getSize() != 1)
1464         {
1465             return false;
1466         }
1467
1468         ScicosID adaptee = adaptor.getAdaptee()->id();
1469
1470         char* c_str = wide_string_to_UTF8(current->get(0));
1471         std::string uid(c_str);
1472         FREE(c_str);
1473
1474         controller.setObjectProperty(adaptee, BLOCK, UID, uid);
1475         return true;
1476     }
1477 };
1478
1479 } /* namespace */
1480
1481 template<> property<ModelAdapter>::props_t property<ModelAdapter>::fields = property<ModelAdapter>::props_t();
1482 static void initialize_fields()
1483 {
1484     if (property<ModelAdapter>::properties_have_not_been_set())
1485     {
1486         property<ModelAdapter>::fields.reserve(23);
1487         property<ModelAdapter>::add_property(L"sim", &sim::get, &sim::set);
1488         property<ModelAdapter>::add_property(L"in", &in::get, &in::set);
1489         property<ModelAdapter>::add_property(L"in2", &in2::get, &in2::set);
1490         property<ModelAdapter>::add_property(L"intyp", &intyp::get, &intyp::set);
1491         property<ModelAdapter>::add_property(L"out", &out::get, &out::set);
1492         property<ModelAdapter>::add_property(L"out2", &out2::get, &out2::set);
1493         property<ModelAdapter>::add_property(L"outtyp", &outtyp::get, &outtyp::set);
1494         property<ModelAdapter>::add_property(L"evtin", &evtin::get, &evtin::set);
1495         property<ModelAdapter>::add_property(L"evtout", &evtout::get, &evtout::set);
1496         property<ModelAdapter>::add_property(L"state", &state::get, &state::set);
1497         property<ModelAdapter>::add_property(L"dstate", &dstate::get, &dstate::set);
1498         property<ModelAdapter>::add_property(L"odstate", &odstate::get, &odstate::set);
1499         property<ModelAdapter>::add_property(L"rpar", &rpar::get, &rpar::set);
1500         property<ModelAdapter>::add_property(L"ipar", &ipar::get, &ipar::set);
1501         property<ModelAdapter>::add_property(L"opar", &opar::get, &opar::set);
1502         property<ModelAdapter>::add_property(L"blocktype", &blocktype::get, &blocktype::set);
1503         property<ModelAdapter>::add_property(L"firing", &firing::get, &firing::set);
1504         property<ModelAdapter>::add_property(L"dep_ut", &dep_ut::get, &dep_ut::set);
1505         property<ModelAdapter>::add_property(L"label", &label::get, &label::set);
1506         property<ModelAdapter>::add_property(L"nzcross", &nzcross::get, &nzcross::set);
1507         property<ModelAdapter>::add_property(L"nmode", &nmode::get, &nmode::set);
1508         property<ModelAdapter>::add_property(L"equations", &equations::get, &equations::set);
1509         property<ModelAdapter>::add_property(L"uid", &uid::get, &uid::set);
1510     }
1511 }
1512
1513 ModelAdapter::ModelAdapter() :
1514     BaseAdapter<ModelAdapter, org_scilab_modules_scicos::model::Block>(),
1515     m_diagramAdapter(nullptr)
1516 {
1517     initialize_fields();
1518 }
1519 ModelAdapter::ModelAdapter(const Controller& c, model::Block* adaptee, DiagramAdapter* diagramAdapter) :
1520     BaseAdapter<ModelAdapter, org_scilab_modules_scicos::model::Block>(c, adaptee),
1521     m_diagramAdapter(diagramAdapter)
1522 {
1523     initialize_fields();
1524 }
1525
1526 ModelAdapter::~ModelAdapter()
1527 {
1528 }
1529
1530 std::wstring ModelAdapter::getTypeStr()
1531 {
1532     return getSharedTypeStr();
1533 }
1534
1535 std::wstring ModelAdapter::getShortTypeStr()
1536 {
1537     return getSharedTypeStr();
1538 }
1539
1540 DiagramAdapter* ModelAdapter::getDiagram() const
1541 {
1542     return m_diagramAdapter;
1543 }
1544
1545 void ModelAdapter::setDiagram(DiagramAdapter* diagramAdapter)
1546 {
1547     // does not increment reference as this adapter does not own the DiagramAdapter
1548     m_diagramAdapter = diagramAdapter;
1549 }
1550
1551 } /* namespace view_scilab */
1552 } /* namespace org_scilab_modules_scicos */