Xcos MVC: fix for Deleted blocks
[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 (*it == 0ll)
441         {
442             continue; // Rule out mlists (Deleted or Annotations)
443         }
444
445         if (controller.getObject(*it)->kind() == BLOCK) // Rule out Annotations and Links
446         {
447             std::string name;
448             controller.getObjectProperty(*it, BLOCK, SIM_FUNCTION_NAME, name);
449
450             // Find the "port blocks"
451             if (name == input || name == inimpl || name == output || name == outimpl)
452             {
453                 std::vector<int> ipar;
454                 controller.getObjectProperty(*it, BLOCK, IPAR, ipar);
455                 if (ipar.size() != 1)
456                 {
457                     return false;
458                 }
459                 int portIndex = ipar[0];
460
461                 // "name" is not enough to tell the event and data ports apart, so check the block's port.
462                 object_properties_t kind;
463                 std::vector<ScicosID> innerPort;
464                 if (name == input || name == inimpl)
465                 {
466                     controller.getObjectProperty(*it, BLOCK, OUTPUTS, innerPort);
467                     if (!innerPort.empty())
468                     {
469                         kind = INPUTS;
470                     }
471                     else
472                     {
473                         kind = EVENT_INPUTS;
474                     }
475                 }
476                 else
477                 {
478                     controller.getObjectProperty(*it, BLOCK, INPUTS, innerPort);
479                     if (!innerPort.empty())
480                     {
481                         kind = OUTPUTS;
482                     }
483                     else
484                     {
485                         kind = EVENT_OUTPUTS;
486                     }
487                 }
488
489                 std::vector<ScicosID> superPorts;
490                 controller.getObjectProperty(adaptee, BLOCK, kind, superPorts);
491                 if (static_cast<int>(superPorts.size()) < portIndex)
492                 {
493                     return false;
494                 }
495
496                 ScicosID port = superPorts[portIndex - 1];
497
498                 // Check consistency of the implicitness between the inner and outer ports
499                 bool isImplicit;
500                 controller.getObjectProperty(port, PORT, IMPLICIT, isImplicit);
501                 if (name == input || name == output)
502                 {
503                     if (isImplicit)
504                     {
505                         return false;
506                     }
507                 }
508                 else
509                 {
510                     if (!isImplicit)
511                     {
512                         return false;
513                     }
514                 }
515
516                 controller.setObjectProperty(*it, BLOCK, PORT_REFERENCE, port);
517             }
518         }
519     }
520     return true;
521 }
522
523 struct rpar
524 {
525
526     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
527     {
528         ScicosID adaptee = adaptor.getAdaptee()->id();
529
530         std::vector<ScicosID> diagramChildren;
531         controller.getObjectProperty(adaptee, BLOCK, CHILDREN, diagramChildren);
532
533         if (diagramChildren.empty())
534         {
535             std::vector<double> rpar;
536             controller.getObjectProperty(adaptee, BLOCK, RPAR, rpar);
537
538             double *data;
539             types::Double* o = new types::Double((int)rpar.size(), 1, &data);
540 #ifdef _MSC_VER
541             std::copy(rpar.begin(), rpar.end(), stdext::checked_array_iterator<double*>(data, rpar.size()));
542 #else
543             std::copy(rpar.begin(), rpar.end(), data);
544 #endif
545             return o;
546         }
547         else // SuperBlock, return the contained diagram (allocating it on demand)
548         {
549             DiagramAdapter* diagram = adaptor.getDiagram();
550
551             /*
552              * FIXME: Sync all diagram children as the blocks might be modified by xcos
553              */
554
555             return diagram;
556         }
557     }
558
559     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
560     {
561         ScicosID adaptee = adaptor.getAdaptee()->id();
562
563         if (v->getType() == types::InternalType::ScilabDouble)
564         {
565             types::Double* current = v->getAs<types::Double>();
566
567             std::vector<double> rpar (current->getSize());
568             for (int i = 0; i < current->getSize(); ++i)
569             {
570                 rpar[i] = current->get(i);
571             }
572
573             controller.setObjectProperty(adaptee, BLOCK, RPAR, rpar);
574             return true;
575         }
576         else if (v->getType() == types::InternalType::ScilabString)
577         {
578             // Allow Text blocks to define strings in rpar
579             return true;
580         }
581         else if (v->getType() == types::InternalType::ScilabUserType)
582         {
583             // Make sure the input describes a Diagram
584             const Adapters::adapters_index_t adapter_index = Adapters::instance().lookup_by_typename(v->getShortTypeStr());
585             if (adapter_index != Adapters::DIAGRAM_ADAPTER)
586             {
587                 return false;
588             }
589
590             // Translate 'v' to an DiagramAdapter ; copy if needed
591             DiagramAdapter* diagram;
592             if (v->getRef() > 1)
593             {
594                 diagram = v->clone()->getAs<DiagramAdapter>();
595             }
596             else
597             {
598                 diagram = v->getAs<DiagramAdapter>();
599             }
600             adaptor.setDiagram(diagram);
601
602             // set the diagram children as block children ; referencing them
603             std::vector<ScicosID> diagramChildren;
604             controller.getObjectProperty(diagram->getAdaptee()->id(), DIAGRAM, CHILDREN, diagramChildren);
605             std::vector<ScicosID> oldDiagramChildren;
606             controller.getObjectProperty(adaptor.getAdaptee()->id(), BLOCK, CHILDREN, oldDiagramChildren);
607
608             controller.setObjectProperty(adaptor.getAdaptee()->id(), BLOCK, CHILDREN, diagramChildren);
609             {
610                 std::sort(oldDiagramChildren.begin(), oldDiagramChildren.end());
611                 for (const ScicosID id : diagramChildren)
612                 {
613                     if (id != 0 && !std::binary_search(oldDiagramChildren.begin(), oldDiagramChildren.end(), id))
614                     {
615                         auto o = controller.getObject(id);
616                         controller.setObjectProperty(o->id(), o->kind(), PARENT_BLOCK, adaptor.getAdaptee()->id());
617
618                         controller.referenceObject(id);
619                     }
620                 }
621
622                 std::sort(diagramChildren.begin(), diagramChildren.end());
623                 for (const ScicosID id : oldDiagramChildren)
624                 {
625                     if (id != 0 && !std::binary_search(diagramChildren.begin(), diagramChildren.end(), id))
626                     {
627                         auto o = controller.getObject(id);
628                         controller.setObjectProperty(o->id(), o->kind(), PARENT_BLOCK, ScicosID());
629
630                         controller.deleteObject(id);
631                     }
632                 }
633             }
634
635             // Link the Superblock ports to their inner "port blocks"
636             return setInnerBlocksRefs(adaptor, diagramChildren, controller);
637         }
638         else
639         {
640             return false;
641         }
642     }
643 };
644
645 double toDouble(const int a)
646 {
647     return static_cast<double>(a);
648 }
649
650 struct ipar
651 {
652
653     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
654     {
655         ScicosID adaptee = adaptor.getAdaptee()->id();
656
657         std::vector<int> ipar;
658         controller.getObjectProperty(adaptee, BLOCK, IPAR, ipar);
659
660         double *data;
661         types::Double* o = new types::Double((int)ipar.size(), 1, &data);
662
663 #ifdef _MSC_VER
664         std::transform(ipar.begin(), ipar.end(), stdext::checked_array_iterator<double*>(data, ipar.size()), toDouble);
665 #else
666         std::transform(ipar.begin(), ipar.end(), data, toDouble);
667 #endif
668         return o;
669     }
670
671     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
672     {
673         ScicosID adaptee = adaptor.getAdaptee()->id();
674
675         if (v->getType() == types::InternalType::ScilabList)
676         {
677             std::vector<int> ipar;
678             controller.setObjectProperty(adaptee, BLOCK, IPAR, ipar);
679             return true;
680         }
681
682         if (v->getType() != types::InternalType::ScilabDouble)
683         {
684             return false;
685         }
686
687         types::Double* current = v->getAs<types::Double>();
688         if (current->getCols() != 0 && current->getCols() != 1)
689         {
690             return false;
691         }
692
693         std::vector<int> ipar (current->getSize());
694         for (int i = 0; i < current->getSize(); ++i)
695         {
696             if (floor(current->get(i)) != current->get(i))
697             {
698                 return false;
699             }
700             ipar[i] = static_cast<int>(current->get(i));
701         }
702
703         controller.setObjectProperty(adaptee, BLOCK, IPAR, ipar);
704         return true;
705     }
706 };
707
708 struct opar
709 {
710
711     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
712     {
713         ScicosID adaptee = adaptor.getAdaptee()->id();
714
715         std::vector<double> prop_content;
716         controller.getObjectProperty(adaptee, BLOCK, OPAR, prop_content);
717
718         // Corner-case, the empty content is an empty double
719         if (prop_content.empty())
720         {
721             return types::Double::Empty();
722         }
723
724         // The returned value is a list
725         types::InternalType* res;
726         if (!vec2var(prop_content, res))
727         {
728             return 0;
729         }
730
731         return res;
732     }
733
734     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
735     {
736         ScicosID adaptee = adaptor.getAdaptee()->id();
737
738         // corner-case the empty content is an empty-double
739         if (v->getType() == types::InternalType::ScilabDouble)
740         {
741             types::Double* current = v->getAs<types::Double>();
742             if (current->getSize() != 0)
743             {
744                 return false;
745             }
746
747             // prop_content should be empty
748             std::vector<double> prop_content;
749             controller.setObjectProperty(adaptee, BLOCK, OPAR, prop_content);
750             return true;
751         }
752
753         std::vector<double> prop_content;
754         if (!var2vec(v, prop_content))
755         {
756             return false;
757         }
758
759         controller.setObjectProperty(adaptee, BLOCK, OPAR, prop_content);
760         return true;
761     }
762 };
763
764 struct blocktype
765 {
766
767     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
768     {
769         ScicosID adaptee = adaptor.getAdaptee()->id();
770
771         std::string type;
772         controller.getObjectProperty(adaptee, BLOCK, SIM_BLOCKTYPE, type);
773
774         types::String* o = new types::String(type.c_str());
775         return o;
776     }
777
778     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
779     {
780         ScicosID adaptee = adaptor.getAdaptee()->id();
781
782         if (v->getType() != types::InternalType::ScilabString)
783         {
784             return false;
785         }
786
787         types::String* current = v->getAs<types::String>();
788         if (current->getSize() != 1)
789         {
790             return false;
791         }
792
793         char* c_str = wide_string_to_UTF8(current->get(0));
794         std::string type (c_str);
795         FREE(c_str);
796
797         // the value validation is performed on the model
798         return controller.setObjectProperty(adaptee, BLOCK, SIM_BLOCKTYPE, type) != FAIL;
799     }
800 };
801
802 struct firing
803 {
804
805     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
806     {
807         return get_ports_property<ModelAdapter, FIRING>(adaptor, EVENT_OUTPUTS, controller);
808     }
809
810     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
811     {
812         return set_ports_property<ModelAdapter, FIRING>(adaptor, EVENT_OUTPUTS, controller, v);
813     }
814 };
815
816 struct dep_ut
817 {
818
819     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
820     {
821         ScicosID adaptee = adaptor.getAdaptee()->id();
822
823         std::vector<int> dep_ut;
824         controller.getObjectProperty(adaptee, BLOCK, SIM_DEP_UT, dep_ut);
825
826         int* dep;
827         types::Bool* o = new types::Bool(1, 2, &dep);
828
829         dep[0] = dep_ut[0];
830         dep[1] = dep_ut[1];
831
832         return o;
833     }
834
835     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
836     {
837         ScicosID adaptee = adaptor.getAdaptee()->id();
838
839         if (v->getType() != types::InternalType::ScilabBool)
840         {
841             return false;
842         }
843
844         types::Bool* current = v->getAs<types::Bool>();
845         if (current->getRows() != 1 || current->getCols() != 2)
846         {
847             return false;
848         }
849
850         std::vector<int> dep_ut (2);
851         dep_ut[0] = current->get(0);
852         dep_ut[1] = current->get(1);
853
854         controller.setObjectProperty(adaptee, BLOCK, SIM_DEP_UT, dep_ut);
855         return true;
856     }
857 };
858
859 struct label
860 {
861
862     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
863     {
864         ScicosID adaptee = adaptor.getAdaptee()->id();
865
866         std::string label;
867         controller.getObjectProperty(adaptee, BLOCK, LABEL, label);
868
869         types::String* o = new types::String(1, 1);
870         o->set(0, label.data());
871
872         return o;
873     }
874
875     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
876     {
877         if (v->getType() != types::InternalType::ScilabString)
878         {
879             return false;
880         }
881
882         types::String* current = v->getAs<types::String>();
883         if (current->getSize() != 1)
884         {
885             return false;
886         }
887
888         ScicosID adaptee = adaptor.getAdaptee()->id();
889
890         char* c_str = wide_string_to_UTF8(current->get(0));
891         std::string label(c_str);
892         FREE(c_str);
893
894         controller.setObjectProperty(adaptee, BLOCK, LABEL, label);
895         return true;
896     }
897 };
898
899 struct nzcross
900 {
901
902     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
903     {
904         ScicosID adaptee = adaptor.getAdaptee()->id();
905
906         std::vector<int> nzcross;
907         controller.getObjectProperty(adaptee, BLOCK, NZCROSS, nzcross);
908
909         double *data;
910         types::Double* o = new types::Double((int)nzcross.size(), 1, &data);
911
912 #ifdef _MSC_VER
913         std::transform(nzcross.begin(), nzcross.end(), stdext::checked_array_iterator<double*>(data, nzcross.size()), toDouble);
914 #else
915         std::transform(nzcross.begin(), nzcross.end(), data, toDouble);
916 #endif
917         return o;
918     }
919
920     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
921     {
922         ScicosID adaptee = adaptor.getAdaptee()->id();
923
924         if (v->getType() != types::InternalType::ScilabDouble)
925         {
926             return false;
927         }
928
929         types::Double* current = v->getAs<types::Double>();
930         // Only allow vectors and empty matrices
931         if (!current->isVector() && current->getSize() != 0)
932         {
933             return false;
934         }
935
936         std::vector<int> nzcross (current->getSize());
937         for (int i = 0; i < current->getSize(); ++i)
938         {
939             if (floor(current->get(i)) != current->get(i))
940             {
941                 return false;
942             }
943             nzcross[i] = static_cast<int>(current->get(i));
944         }
945
946         controller.setObjectProperty(adaptee, BLOCK, NZCROSS, nzcross);
947         return true;
948     }
949 };
950
951 struct nmode
952 {
953
954     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
955     {
956         ScicosID adaptee = adaptor.getAdaptee()->id();
957
958         std::vector<int> nmode;
959         controller.getObjectProperty(adaptee, BLOCK, NMODE, nmode);
960
961         double *data;
962         types::Double* o = new types::Double((int)nmode.size(), 1, &data);
963
964 #ifdef _MSC_VER
965         std::transform(nmode.begin(), nmode.end(), stdext::checked_array_iterator<double*>(data, nmode.size()), toDouble);
966 #else
967         std::transform(nmode.begin(), nmode.end(), data, toDouble);
968 #endif
969         return o;
970     }
971
972     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
973     {
974         ScicosID adaptee = adaptor.getAdaptee()->id();
975
976         if (v->getType() != types::InternalType::ScilabDouble)
977         {
978             return false;
979         }
980
981         types::Double* current = v->getAs<types::Double>();
982         // Only allow vectors and empty matrices
983         if (!current->isVector() && current->getSize() != 0)
984         {
985             return false;
986         }
987
988         std::vector<int> nmode (current->getSize());
989         for (int i = 0; i < current->getSize(); ++i)
990         {
991             if (floor(current->get(i)) != current->get(i))
992             {
993                 return false;
994             }
995             nmode[i] = static_cast<int>(current->get(i));
996         }
997
998         controller.setObjectProperty(adaptee, BLOCK, NMODE, nmode);
999         return true;
1000     }
1001 };
1002
1003 struct equations
1004 {
1005
1006     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
1007     {
1008         ScicosID adaptee = adaptor.getAdaptee()->id();
1009
1010         std::vector<std::string> equations;
1011         controller.getObjectProperty(adaptee, BLOCK, EQUATIONS, equations);
1012
1013         if (equations.size() == 0)
1014         {
1015             return new types::List();
1016         }
1017
1018         types::TList* o = new types::TList();
1019
1020         // Header, starting with "modelica"
1021         types::String* header = new types::String(1, 5);
1022         header->set(0, modelica.c_str());
1023         header->set(1, model.c_str());
1024         header->set(2, inputs.c_str());
1025         header->set(3, outputs.c_str());
1026         header->set(4, parameters.c_str());
1027         o->set(0, header);
1028
1029         // 'model'
1030         if (equations[0].c_str() == std::string())
1031         {
1032             o->set(1, types::Double::Empty());
1033         }
1034         else
1035         {
1036             types::String* modelField = new types::String(1, 1);
1037             modelField->set(0, equations[0].c_str());
1038             o->set(1, modelField);
1039         }
1040
1041         // 'inputs'
1042         std::istringstream inputsSizeStr (equations[1]);
1043         int inputsSize;
1044         inputsSizeStr >> inputsSize;
1045         if (inputsSize == 0)
1046         {
1047             types::Double* inputsField = types::Double::Empty();
1048             o->set(2, inputsField);
1049         }
1050         else
1051         {
1052             types::String* inputsField = new types::String(inputsSize, 1);
1053             for (int i = 0; i < inputsSize; ++i)
1054             {
1055                 inputsField->set(i, equations[i + 2].c_str());
1056             }
1057             o->set(2, inputsField);
1058         }
1059
1060         // 'outputs'
1061         std::istringstream outputsSizeStr (equations[2 + inputsSize]);
1062         int outputsSize;
1063         outputsSizeStr >> outputsSize;
1064         if (outputsSize == 0)
1065         {
1066             types::Double* outputsField = types::Double::Empty();
1067             o->set(3, outputsField);
1068         }
1069         else
1070         {
1071             types::String* outputsField = new types::String(outputsSize, 1);
1072             for (int i = 0; i < outputsSize; ++i)
1073             {
1074                 outputsField->set(i, equations[i + 3 + inputsSize].c_str());
1075             }
1076             o->set(3, outputsField);
1077         }
1078
1079         // 'parameters'
1080         types::List* parametersField = new types::List();
1081
1082         // 'parameters' names
1083         std::istringstream parametersSizeStr (equations[3 + inputsSize + outputsSize]);
1084         int parametersSize;
1085         parametersSizeStr >> parametersSize;
1086         if (parametersSize == 0)
1087         {
1088             types::Double* parametersNames = types::Double::Empty();
1089             parametersField->set(0, parametersNames);
1090         }
1091         else
1092         {
1093             types::String* parametersNames = new types::String(parametersSize, 1);
1094             for (int i = 0; i < parametersSize; ++i)
1095             {
1096                 parametersNames->set(i, equations[i + 4 + inputsSize + outputsSize].c_str());
1097             }
1098             parametersField->set(0, parametersNames);
1099         }
1100
1101         // 'parameters' values
1102         types::List* parametersValues = new types::List();
1103         for (int i = 0; i < parametersSize; ++i)
1104         {
1105             std::istringstream parametersValueStr (equations[i + 4 + inputsSize + outputsSize + parametersSize]);
1106             double parametersVal;
1107             parametersValueStr >> parametersVal;
1108             types::Double* parametersValue = new types::Double(parametersVal);
1109             parametersValues->set(i, parametersValue);
1110         }
1111         parametersField->set(1, parametersValues);
1112
1113         // 'parameters' states (optional, only check its presence if at least one parameter is present)
1114         if (parametersSize != 0)
1115         {
1116             std::string parametersStatesBool (equations[4 + inputsSize + outputsSize + 2 * parametersSize]);
1117             if (strcmp(parametersStatesBool.c_str(), "T") == 0) // Check the presence of the "states" field
1118             {
1119                 types::Double* parametersStates = new types::Double(parametersSize, 1);
1120                 for (int i = 0; i < parametersSize; ++i)
1121                 {
1122                     std::istringstream parametersStateStr (equations[i + 5 + inputsSize + outputsSize + 2 * parametersSize]);
1123                     double parametersState;
1124                     parametersStateStr >> parametersState;
1125                     parametersStates->set(i, parametersState);
1126                 }
1127                 parametersField->set(2, parametersStates);
1128             }
1129         }
1130
1131         o->set(4, parametersField);
1132
1133         return o;
1134     }
1135
1136     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
1137     {
1138         ScicosID adaptee = adaptor.getAdaptee()->id();
1139
1140         if (v->getType() == types::InternalType::ScilabList)
1141         {
1142             types::List* current = v->getAs<types::List>();
1143             if (current->getSize() != 0)
1144             {
1145                 return false;
1146             }
1147             return true;
1148         }
1149
1150         if (v->getType() != types::InternalType::ScilabTList)
1151         {
1152             return false;
1153         }
1154
1155         types::TList* current = v->getAs<types::TList>();
1156
1157         // Check the header
1158         types::String* header = current->getFieldNames();
1159         if (header->getSize() != 5)
1160         {
1161             return false;
1162         }
1163         if (header->get(0) != modelica)
1164         {
1165             return false;
1166         }
1167         if (header->get(1) != model)
1168         {
1169             return false;
1170         }
1171         if (header->get(2) != inputs)
1172         {
1173             return false;
1174         }
1175         if (header->get(3) != outputs)
1176         {
1177             return false;
1178         }
1179         if (header->get(4) != parameters)
1180         {
1181             return false;
1182         }
1183
1184         char* c_str; // Temporary buffer used for conversions
1185
1186         // 'model'
1187         std::vector<std::string> equations;
1188         if (current->get(1)->getType() == types::InternalType::ScilabString)
1189         {
1190             types::String* modelField = current->get(1)->getAs<types::String>();
1191             if (modelField->getSize() != 1)
1192             {
1193                 return false;
1194             }
1195
1196             c_str = wide_string_to_UTF8(modelField->get(0));
1197             std::string modelFieldStored(c_str);
1198             FREE(c_str);
1199             equations.push_back(modelFieldStored);
1200         }
1201         else if (current->get(1)->getType() == types::InternalType::ScilabDouble)
1202         {
1203             types::Double* modelFieldDouble = current->get(1)->getAs<types::Double>();
1204             if (modelFieldDouble->getSize() != 0)
1205             {
1206                 return false;
1207             }
1208
1209             // An empty matrix stores an empty string, which will later be translated back to an empty matrix
1210             equations.push_back(std::string());
1211         }
1212         else
1213         {
1214             return false;
1215         }
1216
1217         // 'inputs'
1218         size_t inputsSize;
1219         if (current->get(2)->getType() == types::InternalType::ScilabDouble)
1220         {
1221             types::Double* inputsField = current->get(2)->getAs<types::Double>();
1222             if (inputsField->getSize() != 0)
1223             {
1224                 return false;
1225             }
1226
1227             inputsSize = 0;
1228             std::ostringstream strInputs;
1229             strInputs << inputsSize;
1230             std::string inputsSizeStr = strInputs.str();
1231             equations.push_back(inputsSizeStr); // When 'inputs'=[], just insert "0" in 'equations'
1232         }
1233         else
1234         {
1235             if (current->get(2)->getType() != types::InternalType::ScilabString)
1236             {
1237                 return false;
1238             }
1239
1240             types::String* inputsField = current->get(2)->getAs<types::String>();
1241             inputsSize = inputsField->getSize();
1242             equations.resize(equations.size() + 1 + inputsSize);
1243             std::ostringstream strInputs;
1244             strInputs << inputsSize;
1245             std::string inputsSizeStr = strInputs.str();
1246             equations[1] = inputsSizeStr; // Saving the size of the 'inputs' field'
1247             for (size_t i = 0; i < inputsSize; ++i)
1248             {
1249                 c_str = wide_string_to_UTF8(inputsField->get(static_cast<int>(i)));
1250                 std::string inputsFieldStored(c_str);
1251                 FREE(c_str);
1252                 equations[i + 2] = inputsFieldStored;
1253             }
1254         }
1255
1256         // 'outputs'
1257         size_t outputsSize;
1258         if (current->get(3)->getType() == types::InternalType::ScilabDouble)
1259         {
1260             types::Double* outputsField = current->get(3)->getAs<types::Double>();
1261             if (outputsField->getSize() != 0)
1262             {
1263                 return false;
1264             }
1265
1266             outputsSize = 0;
1267             std::ostringstream strOutputs;
1268             strOutputs << outputsSize;
1269             std::string outputsSizeStr = strOutputs.str();
1270             equations.push_back(outputsSizeStr); // When 'outputs'=[], just insert "0" in 'equations'
1271         }
1272         else
1273         {
1274             if (current->get(3)->getType() != types::InternalType::ScilabString)
1275             {
1276                 return false;
1277             }
1278
1279             types::String* outputsField = current->get(3)->getAs<types::String>();
1280             outputsSize = outputsField->getSize();
1281             equations.resize(equations.size() + 1 + outputsSize);
1282             std::ostringstream strOutputs;
1283             strOutputs << outputsSize;
1284             std::string outputsSizeStr = strOutputs.str();
1285             equations[2 + inputsSize] = outputsSizeStr; // Saving the size of the 'outputs' field'
1286             for (size_t i = 0; i < outputsSize; ++i)
1287             {
1288                 c_str = wide_string_to_UTF8(outputsField->get(static_cast<int>(i)));
1289                 std::string outputsFieldStored(c_str);
1290                 FREE(c_str);
1291                 equations[i + 3 + inputsSize] = outputsFieldStored;
1292             }
1293         }
1294
1295         // 'parameters'
1296         int parametersIndex = 4;
1297         if (current->get(parametersIndex)->getType() == types::InternalType::ScilabDouble)
1298         {
1299             // For backward compatibility sake, allow the presence of an empty matrix here
1300             types::Double* emptyMatrix = current->get(parametersIndex)->getAs<types::Double>();
1301             if (emptyMatrix->getSize() != 0)
1302             {
1303                 return false;
1304             }
1305
1306             parametersIndex++;
1307         }
1308
1309         if (current->get(parametersIndex)->getType() != types::InternalType::ScilabList)
1310         {
1311             return false;
1312         }
1313
1314         types::List* list = current->get(parametersIndex)->getAs<types::List>();
1315         if (list->getSize() != 2 && list->getSize() != 3)
1316         {
1317             return false;
1318         }
1319
1320         // 'parameters' names
1321         size_t parametersSize;
1322         if (list->get(0)->getType() == types::InternalType::ScilabDouble)
1323         {
1324             types::Double* parametersNames = list->get(0)->getAs<types::Double>();
1325             if (parametersNames->getSize() != 0)
1326             {
1327                 return false;
1328             }
1329
1330             // When 'parameters(1)'=[], just insert "0" in 'equations', set in the model and return
1331             parametersSize = 0;
1332             std::ostringstream strParameters;
1333             strParameters << parametersSize;
1334             std::string parametersSizeStr = strParameters.str();
1335             equations.push_back(parametersSizeStr);
1336
1337             controller.setObjectProperty(adaptee, BLOCK, EQUATIONS, equations);
1338             return true;
1339         }
1340         else
1341         {
1342             if (list->get(0)->getType() != types::InternalType::ScilabString)
1343             {
1344                 return false;
1345             }
1346
1347             types::String* parametersNames = list->get(0)->getAs<types::String>();
1348             parametersSize = parametersNames->getSize();
1349             equations.resize(equations.size() + 1 + parametersSize);
1350             std::ostringstream strParameters;
1351             strParameters << parametersSize;
1352             std::string parametersSizeStr = strParameters.str();
1353             equations[3 + inputsSize + outputsSize] = parametersSizeStr; // Saving the size of the 'parameters' field'
1354             for (size_t i = 0; i < parametersSize; ++i)
1355             {
1356                 c_str = wide_string_to_UTF8(parametersNames->get(static_cast<int>(i)));
1357                 std::string parametersName(c_str);
1358                 FREE(c_str);
1359                 equations[i + 4 + inputsSize + outputsSize] = parametersName;
1360             }
1361         }
1362
1363         // 'parameters' values
1364         if (list->get(1)->getType() == types::InternalType::ScilabDouble)
1365         {
1366             types::Double* parameterVal = list->get(1)->getAs<types::Double>();
1367             if (parameterVal->getSize() != static_cast<int>(parametersSize))
1368             {
1369                 return false;
1370             }
1371
1372             for (size_t i = 0; i < parametersSize; ++i)
1373             {
1374                 std::ostringstream strParameterVal;
1375                 strParameterVal << parameterVal->get(static_cast<int>(i));
1376                 std::string parameterValStr = strParameterVal.str();
1377                 equations.push_back(parameterValStr);
1378             }
1379         }
1380         else
1381         {
1382             if (list->get(1)->getType() != types::InternalType::ScilabList)
1383             {
1384                 return false;
1385             }
1386
1387             types::List* list2 = list->get(1)->getAs<types::List>();
1388             if (list2->getSize() != static_cast<int>(parametersSize))
1389             {
1390                 return false;
1391             }
1392
1393             equations.resize(equations.size() + parametersSize);
1394             for (size_t i = 0; i < parametersSize; ++i)
1395             {
1396                 if (list2->get(static_cast<int>(i))->getType() != types::InternalType::ScilabDouble)
1397                 {
1398                     return false;
1399                 }
1400
1401                 types::Double* parametersVal = list2->get(static_cast<int>(i))->getAs<types::Double>();
1402                 if (parametersVal->getSize() != 1)
1403                 {
1404                     return false;
1405                 }
1406
1407                 std::ostringstream strParametersVal;
1408                 strParametersVal << parametersVal->get(0);
1409                 std::string parametersValStr = strParametersVal.str();
1410                 equations[i + 4 + inputsSize + outputsSize + parametersSize] = parametersValStr;
1411             }
1412         }
1413
1414         // 'parameters' states (optional)
1415         equations.push_back("F"); // String boolean to indicate the presence, or not, of a "states" field
1416         if (list->getSize() == 3)
1417         {
1418             equations.back() = "T";
1419             if (list->get(2)->getType() != types::InternalType::ScilabDouble)
1420             {
1421                 return false;
1422             }
1423
1424             types::Double* parameterStates = list->get(2)->getAs<types::Double>();
1425             if (parameterStates->getSize() != static_cast<int>(parametersSize))
1426             {
1427                 return false;
1428             }
1429
1430             for (size_t i = 0; i < parametersSize; ++i)
1431             {
1432                 std::ostringstream strParameterStates;
1433                 strParameterStates << parameterStates->get(static_cast<int>(i));
1434                 std::string parameterStatesStr = strParameterStates.str();
1435                 equations.push_back(parameterStatesStr);
1436             }
1437         }
1438
1439         controller.setObjectProperty(adaptee, BLOCK, EQUATIONS, equations);
1440         return true;
1441     }
1442 };
1443
1444 struct uid
1445 {
1446
1447     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
1448     {
1449         ScicosID adaptee = adaptor.getAdaptee()->id();
1450
1451         std::string uid;
1452         controller.getObjectProperty(adaptee, BLOCK, UID, uid);
1453
1454         types::String* o = new types::String(1, 1);
1455         o->set(0, uid.data());
1456
1457         return o;
1458     }
1459
1460     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
1461     {
1462         if (v->getType() != types::InternalType::ScilabString)
1463         {
1464             return false;
1465         }
1466
1467         types::String* current = v->getAs<types::String>();
1468         if (current->getSize() != 1)
1469         {
1470             return false;
1471         }
1472
1473         ScicosID adaptee = adaptor.getAdaptee()->id();
1474
1475         char* c_str = wide_string_to_UTF8(current->get(0));
1476         std::string uid(c_str);
1477         FREE(c_str);
1478
1479         controller.setObjectProperty(adaptee, BLOCK, UID, uid);
1480         return true;
1481     }
1482 };
1483
1484 } /* namespace */
1485
1486 template<> property<ModelAdapter>::props_t property<ModelAdapter>::fields = property<ModelAdapter>::props_t();
1487 static void initialize_fields()
1488 {
1489     if (property<ModelAdapter>::properties_have_not_been_set())
1490     {
1491         property<ModelAdapter>::fields.reserve(23);
1492         property<ModelAdapter>::add_property(L"sim", &sim::get, &sim::set);
1493         property<ModelAdapter>::add_property(L"in", &in::get, &in::set);
1494         property<ModelAdapter>::add_property(L"in2", &in2::get, &in2::set);
1495         property<ModelAdapter>::add_property(L"intyp", &intyp::get, &intyp::set);
1496         property<ModelAdapter>::add_property(L"out", &out::get, &out::set);
1497         property<ModelAdapter>::add_property(L"out2", &out2::get, &out2::set);
1498         property<ModelAdapter>::add_property(L"outtyp", &outtyp::get, &outtyp::set);
1499         property<ModelAdapter>::add_property(L"evtin", &evtin::get, &evtin::set);
1500         property<ModelAdapter>::add_property(L"evtout", &evtout::get, &evtout::set);
1501         property<ModelAdapter>::add_property(L"state", &state::get, &state::set);
1502         property<ModelAdapter>::add_property(L"dstate", &dstate::get, &dstate::set);
1503         property<ModelAdapter>::add_property(L"odstate", &odstate::get, &odstate::set);
1504         property<ModelAdapter>::add_property(L"rpar", &rpar::get, &rpar::set);
1505         property<ModelAdapter>::add_property(L"ipar", &ipar::get, &ipar::set);
1506         property<ModelAdapter>::add_property(L"opar", &opar::get, &opar::set);
1507         property<ModelAdapter>::add_property(L"blocktype", &blocktype::get, &blocktype::set);
1508         property<ModelAdapter>::add_property(L"firing", &firing::get, &firing::set);
1509         property<ModelAdapter>::add_property(L"dep_ut", &dep_ut::get, &dep_ut::set);
1510         property<ModelAdapter>::add_property(L"label", &label::get, &label::set);
1511         property<ModelAdapter>::add_property(L"nzcross", &nzcross::get, &nzcross::set);
1512         property<ModelAdapter>::add_property(L"nmode", &nmode::get, &nmode::set);
1513         property<ModelAdapter>::add_property(L"equations", &equations::get, &equations::set);
1514         property<ModelAdapter>::add_property(L"uid", &uid::get, &uid::set);
1515     }
1516 }
1517
1518 ModelAdapter::ModelAdapter() :
1519     BaseAdapter<ModelAdapter, org_scilab_modules_scicos::model::Block>(),
1520     m_diagramAdapter(nullptr)
1521 {
1522     initialize_fields();
1523 }
1524 ModelAdapter::ModelAdapter(const Controller& c, model::Block* adaptee, DiagramAdapter* diagramAdapter) :
1525     BaseAdapter<ModelAdapter, org_scilab_modules_scicos::model::Block>(c, adaptee),
1526     m_diagramAdapter(diagramAdapter)
1527 {
1528     initialize_fields();
1529 }
1530
1531 ModelAdapter::~ModelAdapter()
1532 {
1533 }
1534
1535 std::wstring ModelAdapter::getTypeStr()
1536 {
1537     return getSharedTypeStr();
1538 }
1539
1540 std::wstring ModelAdapter::getShortTypeStr()
1541 {
1542     return getSharedTypeStr();
1543 }
1544
1545 DiagramAdapter* ModelAdapter::getDiagram() const
1546 {
1547     return m_diagramAdapter;
1548 }
1549
1550 void ModelAdapter::setDiagram(DiagramAdapter* diagramAdapter)
1551 {
1552     // does not increment reference as this adapter does not own the DiagramAdapter
1553     m_diagramAdapter = diagramAdapter;
1554 }
1555
1556 } /* namespace view_scilab */
1557 } /* namespace org_scilab_modules_scicos */