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