de70d2a3dd2901cb6ea8c679b2525c791aaafc05
[scilab.git] / scilab / modules / scicos / sci_gateway / cpp / sci_scicos_new.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 <string>
14
15 #include "gw_scicos.hxx"
16
17 #include "types.hxx"
18 #include "string.hxx"
19 #include "mlist.hxx"
20 #include "list.hxx"
21 #include "function.hxx"
22
23 #include "view_scilab/Adapters.hxx"
24 #include "view_scilab/BaseAdapter.hxx"
25 #include "view_scilab/BlockAdapter.hxx"
26 #include "view_scilab/CprAdapter.hxx"
27 #include "view_scilab/DiagramAdapter.hxx"
28 #include "view_scilab/GraphicsAdapter.hxx"
29 #include "view_scilab/LinkAdapter.hxx"
30 #include "view_scilab/ModelAdapter.hxx"
31 #include "view_scilab/ParamsAdapter.hxx"
32 #include "view_scilab/ScsAdapter.hxx"
33 #include "view_scilab/StateAdapter.hxx"
34 #include "view_scilab/TextAdapter.hxx"
35
36 #include "utilities.hxx"
37 #include "Controller.hxx"
38 #include "model/Annotation.hxx"
39 #include "model/Block.hxx"
40 #include "model/Diagram.hxx"
41 #include "model/Link.hxx"
42
43 extern "C"
44 {
45 #include "Scierror.h"
46 #include "localization.h"
47 }
48
49 using namespace org_scilab_modules_scicos;
50
51 static const std::string funame = "scicos_new";
52
53 template<class Adaptor, class Adaptee>
54 types::InternalType * alloc_and_set(kind_t k, types::String* type_name, types::typed_list &in)
55 {
56     Controller controller = Controller();
57
58     // create the associated object
59     ScicosID o = controller.createObject(k);
60     Adaptor* adaptor = new Adaptor(std::static_pointer_cast<Adaptee>(controller.getObject(o)));
61
62     // the first header entry is the type
63     for (int i = 1; i < (int)in.size(); i++)
64     {
65         std::wstring name (type_name->get(i));
66         if (!adaptor->setProperty(name, in[i], controller))
67         {
68             Scierror(999, _("%s: Wrong value for input argument #%d: unable to set \"%ls\".\n"), funame.data(), i, name.data());
69             delete adaptor;
70             return 0;
71         }
72     }
73
74     return adaptor;
75 }
76
77 template<class Adaptor, class Adaptee>
78 types::InternalType * alloc_and_set_as_mlist(types::String* type_name, types::typed_list &in)
79 {
80     // check header
81     Adaptor adaptor(0);
82     for (int i = 1; i < (int)in.size(); i++)
83     {
84         std::wstring name(type_name->get(i));
85         if (!adaptor.hasProperty(name))
86         {
87             Scierror(999, _("%s: Wrong value for input argument #%d: unable to set \"%ls\".\n"), funame.data(), i, name.data());
88             return 0;
89         }
90     }
91
92     // copy the data
93     types::MList* mlist = new types::MList();
94     mlist->set(0, type_name->clone());
95     for (int i = 1; i < (int)in.size(); i++)
96     {
97         mlist->set(i, in[i]);
98     }
99
100     return mlist;
101 }
102
103 types::Function::ReturnValue sci_scicos_new(types::typed_list &in, int _iRetCount, types::typed_list &out)
104 {
105     if (in.size() < 1)
106     {
107         Scierror(999, _("%s: Wrong number of input arguments: At least %d expected.\n"), funame.data(), 1);
108         return types::Function::Error;
109     }
110     if (_iRetCount > 1)
111     {
112         Scierror(999, _("%s: Wrong number of output arguments: %d expected.\n"), funame.data(), 1);
113         return types::Function::Error;
114     }
115
116     types::InternalType* type = in[0];
117     if (type->getType() != types::InternalType::ScilabString)
118     {
119         Scierror(999, _("%s: Wrong type for input argument #%d: String expected.\n"), funame.data(), 1);
120         return types::Function::Error;
121     }
122
123     types::String* type_name = type->getAs<types::String>();
124     if (type_name->getRows() > 1)
125     {
126         Scierror(999, _("%s: Wrong size for input argument #%d: Row vector expected.\n"), funame.data(), 1);
127         return types::Function::Error;
128     }
129
130     if (type_name->getCols() != (int) in.size())
131     {
132         Scierror(999, _("%s: Wrong number of input argument: %d expected.\n"), funame.data(), type_name->getCols());
133         return types::Function::Error;
134     }
135
136     /*
137      * allocate the right adapter then try to set fields values
138      */
139
140     const view_scilab::Adapters::adapters_index_t adapter_index = view_scilab::Adapters::instance().lookup_by_typename(type_name->get(0));
141     types::InternalType* returnType;
142     switch (adapter_index)
143     {
144         case view_scilab::Adapters::BLOCK_ADAPTER:
145             returnType = alloc_and_set<view_scilab::BlockAdapter, model::Block>(BLOCK, type_name, in);
146             if (returnType == 0)
147             {
148                 return types::Function::Error;
149             }
150             out.push_back(returnType);
151             break;
152         case view_scilab::Adapters::CPR_ADAPTER:
153             returnType = alloc_and_set<view_scilab::CprAdapter, model::Diagram>(DIAGRAM, type_name, in);
154             if (returnType == 0)
155             {
156                 return types::Function::Error;
157             }
158             out.push_back(returnType);
159             break;
160         case view_scilab::Adapters::DELETED_ADAPTER:
161             returnType = new types::List();
162             out.push_back(returnType);
163             break;
164         case view_scilab::Adapters::DIAGRAM_ADAPTER:
165             returnType = alloc_and_set<view_scilab::DiagramAdapter, model::Diagram>(DIAGRAM, type_name, in);
166             if (returnType == 0)
167             {
168                 return types::Function::Error;
169             }
170             out.push_back(returnType);
171             break;
172         case view_scilab::Adapters::GRAPHIC_ADAPTER:
173             returnType = alloc_and_set_as_mlist<view_scilab::GraphicsAdapter, model::Block>(type_name, in);
174             if (returnType == 0)
175             {
176                 return types::Function::Error;
177             }
178             out.push_back(returnType);
179             break;
180         case view_scilab::Adapters::LINK_ADAPTER:
181             returnType = alloc_and_set<view_scilab::LinkAdapter, model::Link>(LINK, type_name, in);
182             if (returnType == 0)
183             {
184                 return types::Function::Error;
185             }
186             out.push_back(returnType);
187             break;
188         case view_scilab::Adapters::MODEL_ADAPTER:
189             returnType = alloc_and_set_as_mlist<view_scilab::ModelAdapter, model::Block>(type_name, in);
190             if (returnType == 0)
191             {
192                 return types::Function::Error;
193             }
194             out.push_back(returnType);
195             break;
196         case view_scilab::Adapters::PARAMS_ADAPTER:
197             returnType = alloc_and_set_as_mlist<view_scilab::ParamsAdapter, model::Diagram>(type_name, in);
198             if (returnType == 0)
199             {
200                 return types::Function::Error;
201             }
202             out.push_back(returnType);
203             break;
204         case view_scilab::Adapters::SCS_ADAPTER:
205             returnType = alloc_and_set<view_scilab::ScsAdapter, model::Diagram>(DIAGRAM, type_name, in);
206             if (returnType == 0)
207             {
208                 return types::Function::Error;
209             }
210             out.push_back(returnType);
211             break;
212         case view_scilab::Adapters::STATE_ADAPTER:
213             returnType = alloc_and_set<view_scilab::StateAdapter, model::Diagram>(DIAGRAM, type_name, in);
214             if (returnType == 0)
215             {
216                 return types::Function::Error;
217             }
218             out.push_back(returnType);
219             break;
220         case view_scilab::Adapters::TEXT_ADAPTER:
221             returnType = alloc_and_set<view_scilab::TextAdapter, model::Annotation>(ANNOTATION, type_name, in);
222             if (returnType == 0)
223             {
224                 return types::Function::Error;
225             }
226             out.push_back(returnType);
227             break;
228         default:
229             Scierror(999, _("%s: Wrong value for input argument #%d:  \"%ls\" type is not managed.\n"), funame.data(), 1, type_name->get(0));
230             return types::Function::Error;
231             break;
232     }
233
234     return types::Function::OK;
235 }