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