b06da4a9da1106975cda2a8c369a96b38ac44039
[scilab.git] / scilab / modules / xcos / src / jni / JavaController.i
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2014 - Scilab Enterprises - Clement DAVID
4  *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13  *
14  */
15
16 /*
17  * swig -java -c++ -directors -package org.scilab.modules.xcos -outdir src/java/org/scilab/modules/xcos/ src/jni/JavaController.i
18  * or make swig
19  */
20
21 %module(director="1") JavaController;
22
23 %{
24 #include <iterator>
25 #include <algorithm>
26 #include <vector>
27 #include <string>
28
29 #include "utilities.hxx"
30 #include "View.hxx"
31 #include "Controller.hxx"
32 %}
33
34 %include <enums.swg>
35 %include <std_common.i>
36 %include <typemaps.i>
37 %include <std_string.i>
38
39 /*
40  * Inline std_vector.i and add insert and remove methods
41  */
42 namespace std {
43
44     template<class T> class vector {
45       public:
46         typedef size_t size_type;
47         typedef T value_type;
48         typedef const value_type& const_reference;
49         vector();
50         vector(size_type n);
51         %rename(ensureCapacity) reserve;
52         void reserve(size_type n);
53         void resize(size_type n);
54         int size() const;
55         %rename(isEmpty) empty;
56         bool empty() const;
57         void clear();
58         %rename(add) push_back;
59         void push_back(const value_type& x);
60         %extend {
61             bool contains(const T& o) {
62                return std::find(self->begin(), self->end(), o) != self->end();
63             }
64             int indexOf(const T& o) {
65                auto it = std::find(self->begin(), self->end(), o);
66                if (it != self->end())
67                    return std::distance(self->begin(), it);
68                else
69                    return -1;
70             }
71             const_reference get(int i) throw (std::out_of_range) {
72                 int size = int(self->size());
73                 if (i>=0 && i<size)
74                     return (*self)[i];
75                 else
76                     throw std::out_of_range("vector index out of range");
77             }
78             void set(int i, const value_type& val) throw (std::out_of_range) {
79                 int size = int(self->size());
80                 if (i>=0 && i<size)
81                     (*self)[i] = val;
82                 else
83                     throw std::out_of_range("vector index out of range");
84             }
85             void add(int i, const value_type& val) throw (std::out_of_range) {
86                 int size = int(self->size());
87                 if (i>=0 && i<=size)
88                     self->insert(self->begin() + i, val);
89                 else
90                     throw std::out_of_range("vector index out of range");
91             }
92             bool remove(const value_type& val) {
93                 auto it = std::find(self->begin(), self->end(), val);
94                 if (it == self->end())
95                     return false;
96                 else
97                     self->erase(it);
98                 return true;
99             }
100             void* asByteBuffer(int i, int capacity) {
101                 (void) capacity;
102                 void* buffer = nullptr;
103                 int size = int(self->size()) ;
104                 if (i>=0 && i<size) {
105                     buffer = self->data() + i;
106                 } else if (i==0 && size == 0) {
107                     buffer = self->data();
108                 } else {
109                     throw std::out_of_range("vector index out of range");
110                 }
111                 return buffer;
112             }
113         }
114     };
115
116     // bool specialization
117     template<> class vector<bool> {
118       public:
119         typedef size_t size_type;
120         typedef bool value_type;
121         typedef bool const_reference;
122         vector();
123         vector(size_type n);
124         %rename(ensureCapacity) reserve;
125         void reserve(size_type n);
126         void resize(size_type n);
127         int size() const;
128         %rename(isEmpty) empty;
129         bool empty() const;
130         void clear();
131         %rename(add) push_back;
132         void push_back(const value_type& x);
133         %extend {
134             bool get(int i) throw (std::out_of_range) {
135                 int size = int(self->size());
136                 if (i>=0 && i<size)
137                     return (*self)[i];
138                 else
139                     throw std::out_of_range("vector index out of range");
140             }
141             void set(int i, const value_type& val) throw (std::out_of_range) {
142                 int size = int(self->size());
143                 if (i>=0 && i<size)
144                     (*self)[i] = val;
145                 else
146                     throw std::out_of_range("vector index out of range");
147             }
148             void add(int i, const value_type& val) throw (std::out_of_range) {
149                 int size = int(self->size());
150                 if (i>=0 && i<=size)
151                     self->insert(self->begin() + i, val);
152                 else
153                     throw std::out_of_range("vector index out of range");
154             }
155             bool remove(const value_type& val) {
156                 auto it = std::find(self->begin(), self->end(), val);
157                 if (it == self->end())
158                     return false;
159                 else
160                     self->erase(it);
161                 return true;
162             }
163         }
164
165     };
166 }
167
168 /*
169  * Map as simple Java enum, see "25.10.1 Simpler Java enums"
170  */
171 %typemap(javain) enum SWIGTYPE "$javainput.ordinal()"
172 %typemap(javaout) enum SWIGTYPE {
173     return $javaclassname.class.getEnumConstants()[$jnicall];
174   }
175 %typemap(javadirectorin) enum SWIGTYPE "$javaclassname.class.getEnumConstants()[$jniinput]"
176 %typemap(javadirectorout) enum SWIGTYPE "($javacall).ordinal()"
177 %typemap(javabody) enum SWIGTYPE ""
178 %javaconst(1);
179
180 // Rename the enums
181 %rename(Kind) kind_t;
182 %rename(ObjectProperties) object_properties_t;
183 %rename(UpdateStatus) update_status_t;
184 %rename(PortKind) portKind;
185
186 %include "../scicos/includes/utilities.hxx";
187
188 // define scicos symbol visibility
189 #define SCICOS_IMPEXP
190
191 /*
192  * Custom typemap definition
193  */
194
195 // std::string &
196 %typemap(jni)           std::string &           "jobjectArray"
197 %typemap(jtype)         std::string &           "String[]"
198 %typemap(jstype)        std::string &           "String[]"
199 %typemap(javain)        std::string &           "$javainput"
200
201 %typemap(in) std::string & ($*1_ltype temp) {
202   if (!$input) {
203     SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null");
204     return $null;
205   }
206   if (JCALL1(GetArrayLength, jenv, $input) == 0) {
207     SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element");
208     return $null;
209   }
210   $1 = &temp;
211   *$1 = "";
212 }
213
214 %typemap(argout) std::string &OUTPUT {
215   jstring jnewstring = NULL;
216   if ($1) {
217      jnewstring = JCALL1(NewStringUTF, jenv, $1->c_str());
218   }
219   JCALL3(SetObjectArrayElement, jenv, $input, 0, jnewstring);
220 }
221
222 // const std::string &
223 %typemap(jni)           const std::string &     "jstring"
224 %typemap(jtype)         const std::string &     "String"
225 %typemap(jstype)        const std::string &     "String"
226 %typemap(javain)        const std::string &     "$javainput"
227
228 %typemap(in,noblock=1) const std::string & {
229   Swig::JavaString javaString(jenv, $input);
230   *$1 = std::string(javaString.c_str());
231 }
232
233 %typemap(argout,noblock=1) const std::string & { }
234
235 // apply the typemaps to manage outputs arguments
236 %apply double &OUTPUT { double &v };
237 %apply int &OUTPUT { int &v };
238 %apply bool &OUTPUT { bool &v };
239 %apply long long &OUTPUT { long long &v }; // ScicosID
240 %apply std::string &OUTPUT { std::string &v };
241
242 /*
243  * Custom typemap to retrieve a view of the memory as a ByteBuffer
244  */
245 %typemap(jni)     void* "jobject"
246 %typemap(jtype)   void* "java.nio.ByteBuffer"
247 %typemap(jstype)  void* "java.nio.ByteBuffer"
248
249 %typemap(out) void* {
250     if (arg3 <= 0) {
251         arg3 = arg1->size() - arg2;
252     } else if (arg1->size() < arg3) {
253         throw std::out_of_range("vector index out of range");
254     }
255     $result = JCALL2(NewDirectByteBuffer, jenv, $1, arg3 * sizeof(decltype(arg1->back())));
256 }
257 %typemap(javaout) void* {
258     java.nio.ByteBuffer buffer = $jnicall;
259     buffer.order(java.nio.ByteOrder.nativeOrder());
260     return buffer;
261   }
262
263 /*
264  * Generate the View interface
265  */
266 %feature("director", assumeoverride=0) org_scilab_modules_scicos::View;
267 %include "../scicos/includes/View.hxx";
268
269
270 /*
271  * Generate a Controller class
272  */
273 // Ignore not applicable methods
274 %ignore org_scilab_modules_scicos::Controller::getObject;
275 %ignore org_scilab_modules_scicos::Controller::unregister_view;
276 %ignore org_scilab_modules_scicos::Controller::register_view;
277 %include "../scicos/includes/Controller.hxx";
278
279 /*
280  * Template instanciation
281  */
282 %template(VectorOfInt)      std::vector<int>;
283 %template(VectorOfBool)     std::vector<bool>;
284 %template(VectorOfDouble)   std::vector<double>;
285 %template(VectorOfString)   std::vector<std::string>;
286 %template(VectorOfScicosID) std::vector<ScicosID>;
287
288 /*
289  * Fill the main module by needed methods
290  */
291 %{
292 static void register_view(const std::string& name, org_scilab_modules_scicos::View* view) {
293   org_scilab_modules_scicos::Controller::register_view(name, view);
294 };
295 static void unregister_view(org_scilab_modules_scicos::View* view) {
296   org_scilab_modules_scicos::Controller::unregister_view(view);
297 };
298 %}
299
300 %pragma(java) moduleimports=%{
301 import java.util.Map;
302 import java.util.TreeMap;
303 %}
304
305 %pragma(java) modulebase="Controller"
306
307 %pragma(java) modulecode=%{
308   // will contain all registered JavaViews to prevent garbage-collection
309   private static Map<String, View> references = new TreeMap<String, View>();
310
311   private static long add_reference(String name, View v) {
312     references.put(name, v);
313     return View.getCPtr(v);
314   }
315
316   private static View remove_reference(View v) {
317     references.values().remove(v);
318     return v;
319   }
320
321   public static View lookup_view(String name) {
322     return references.get(name);
323   }
324 %}
325
326 /* Quick 'n dirty but works fine */
327 %typemap(javain) org_scilab_modules_scicos::View* "add_reference(name, $javainput)"
328 void register_view(const std::string& name, org_scilab_modules_scicos::View* view);
329 %typemap(javaout) void "{
330     JavaControllerJNI.unregister_view(View.getCPtr(view), view);
331     remove_reference(view);
332   }"
333 void unregister_view(org_scilab_modules_scicos::View* view);
334
335 /*
336  * Static load of library
337  */
338 %pragma(java) jniclasscode=%{
339   static {
340     try {
341         System.loadLibrary("scixcos");
342     } catch (SecurityException e) {
343         System.err.println("A security manager exists and does not allow the loading of the specified dynamic library.");
344         System.err.println(e.getLocalizedMessage());
345         System.exit(-1);
346     } catch (UnsatisfiedLinkError e)    {
347            System.err.println("The native library scicommons does not exist or cannot be found.");
348         if (System.getenv("CONTINUE_ON_JNI_ERROR") == null) {
349            System.err.println(e.getLocalizedMessage());
350            System.err.println("Current java.library.path is : "+System.getProperty("java.library.path"));
351            System.exit(-1);
352         }else{
353            System.err.println("Continuing anyway because of CONTINUE_ON_JNI_ERROR");
354         }
355     }
356   }
357 %}