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