Fix memleaks and slightly improve perfs
[scilab.git] / scilab / modules / graphic_objects / src / cpp / ScilabView.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2011-2011 - DIGITEO - Bruno JOFRET
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-en.txt
10  *
11  */
12
13 #include <iostream>
14 #include <map>
15 #include <cstring>
16 #include <limits.h>
17
18 #include "ScilabView.hxx"
19 #include "CallGraphicController.hxx"
20
21 extern "C"
22 {
23 #include "createGraphicObject.h"
24 #include "setGraphicObjectProperty.h"
25 #include "getGraphicObjectProperty.h"
26 #include "graphicObjectProperties.h"
27 #include "getScilabJavaVM.h"
28 #include "deleteGraphicObject.h"
29 }
30
31 /**
32  * C Wrapping functions
33  * \{
34  */
35 void ScilabNativeView__createObject(char const* pstId)
36 {
37     ScilabView::createObject(pstId);
38 }
39
40 void ScilabNativeView__deleteObject(char const*pstId)
41 {
42     ScilabView::deleteObject(pstId);
43 }
44
45 void ScilabNativeView__updateObject(char const* pstId, int iProperty)
46 {
47     ScilabView::updateObject(pstId, iProperty);
48 }
49
50 void ScilabNativeView__setCurrentFigure(char const* pstId)
51 {
52     ScilabView::setCurrentFigure(pstId);
53 }
54
55 void ScilabNativeView__setCurrentSubWin(char const* pstId)
56 {
57     ScilabView::setCurrentSubWin(pstId);
58 }
59
60 void ScilabNativeView__setCurrentObject(char const* pstId)
61 {
62     ScilabView::setCurrentObject(pstId);
63 }
64
65 int ScilabNativeView__getValidDefaultFigureId()
66 {
67     return ScilabView::getValidDefaultFigureId();
68 }
69
70 /**
71  * \}
72  */
73
74 int ScilabView::getValidDefaultFigureId()
75 {
76     if (m_figureList.empty())
77     {
78         return 0;
79     }
80     else
81     {
82         int max = INT_MIN;
83         for (__figureList_iterator it = m_figureList.begin(); it != m_figureList.end(); ++it)
84         {
85             if (it->second > max)
86             {
87                 max = it->second;
88             }
89         }
90
91         return max + 1;
92     }
93 }
94
95 bool ScilabView::isEmptyFigureList()
96 {
97     return m_figureList.empty();
98 }
99
100 char const* ScilabView::getFigureFromIndex(int figNum)
101 {
102     __figureList_iterator it;
103
104     for (it = m_figureList.begin(); it != m_figureList.end(); ++it)
105     {
106         if (it->second == figNum)
107         {
108             return it->first.c_str();
109         }
110     }
111     return NULL;
112 }
113
114 bool ScilabView::existsFigureId(int id)
115 {
116     __figureList_iterator it;
117
118     for (it = m_figureList.begin(); it != m_figureList.end(); ++it)
119     {
120         if (it->second == id)
121         {
122             return true;
123         }
124     }
125     return false;
126 }
127
128 void ScilabView::getFiguresId(int ids[])
129 {
130     __figureList_iterator it;
131     int i = (int)(m_figureList.size() - 1);
132
133     for (it = m_figureList.begin(); it != m_figureList.end(); ++it, --i)
134     {
135         //std::cerr << "[ScilabView] DEBUG " << it->first << " <-> " << it->second << std::endl;
136         ids[i] = it->second;
137     }
138 }
139
140 int ScilabView::getNbFigure(void)
141 {
142     return (int)m_figureList.size();
143 }
144
145 void ScilabView::createObject(char const* pstId)
146 {
147     //std::cerr << "[ScilabView] ++ createObject UID=" << pstId << std::endl;
148     int iType = -1;
149     int *piType = &iType;
150
151     getGraphicObjectProperty(pstId, __GO_TYPE__, jni_int, (void **)&piType);
152     if (iType != -1 && iType == __GO_FIGURE__)
153     {
154         m_figureList[pstId] = -1;
155         setCurrentFigure(pstId);
156     }
157
158     // Register object handle.
159     getObjectHandle(pstId);
160 }
161
162 void ScilabView::deleteObject(char const* pstId)
163 {
164     //std::cerr << "[ScilabView] -- deleteObject UID=" << pstId << std::endl;
165     int iType = -1;
166     int *piType = &iType;
167     char *pstParentUID = NULL;
168
169     /*
170     ** If deleting a figure, remove from figure list.
171     */
172     m_figureList.erase(pstId);
173
174     /*
175     ** If deleting current figure find another current one,
176     ** if there is no more figure : NULL
177     */
178     if (m_currentFigure == pstId) // Deleting current figure
179     {
180         char* pstrAxesUID = NULL;
181
182         if (getNbFigure() != 0)
183         {
184             m_currentFigure = m_figureList.rbegin()->first;
185             getGraphicObjectProperty(m_currentFigure.c_str(), __GO_SELECTED_CHILD__, jni_string,  (void**)&pstrAxesUID);
186             setCurrentSubWin(pstrAxesUID);
187         }
188         else
189         {
190             setCurrentFigure(NULL);
191             setCurrentSubWin(NULL);
192         }
193     }
194
195     /*
196     ** If deleting current entity, set parent as new current.
197     */
198     if (m_currentObject == pstId) // Deleting current object
199     {
200         getGraphicObjectProperty(pstId, __GO_PARENT__, jni_string, (void **)&pstParentUID);
201         setCurrentObject(pstParentUID);
202     }
203
204     // Remove the corresponding handle.
205     __handleList_iterator it = m_handleList.find(pstId);
206     m_uidList.erase(it->second);
207     m_handleList.erase(it);
208     
209     deleteDataObject(pstId);
210 }
211
212 void ScilabView::updateObject(char const* pstId, int iProperty)
213 {
214     //std::cerr << "[ScilabView] == updateObject UID=" << pstId << " PROPERTY=" << pstProperty << std::endl;
215
216     /*
217      ** Take care of update if the value update is ID and object type is a Figure I manage.
218      */
219     if (iProperty == __GO_ID__ && m_figureList.find(pstId) != m_figureList.end())
220     {
221         int iNewId = 0;
222         int *piNewId = &iNewId;
223
224         getGraphicObjectProperty(pstId, __GO_ID__, jni_int, (void **)&piNewId);
225
226         m_figureList[pstId] = iNewId;
227         //std::cerr << "### [ScilabView] updateMap UID=" << pstId << " id=" << iNewId << std::endl;
228     }
229 }
230
231 /*
232 ** Register ScilabView to Controller.
233 ** Must be done after Graphics models are created.
234 */
235 void ScilabView::registerToController(void)
236 {
237     org_scilab_modules_graphic_objects::CallGraphicController::registerScilabView(getScilabJavaVM());
238     m_figureList.get_allocator().allocate(4096);
239     m_handleList.get_allocator().allocate(4096);
240     m_uidList.get_allocator().allocate(4096);
241 }
242
243 /*
244 ** Reove ScilabView from Controller.
245 */
246 void ScilabView::unregisterToController(void)
247 {
248     org_scilab_modules_graphic_objects::CallGraphicController::unregisterScilabView(getScilabJavaVM());
249 }
250
251 /*
252 ** Set Current Figure UID
253 */
254 void ScilabView::setCurrentFigure(char const* UID)
255 {
256     if (UID == NULL)
257     {
258         m_currentFigure = std::string();
259     }
260     else
261     {
262         m_currentFigure = UID;
263     }
264 }
265
266 /*
267 ** Get Current Figure UID
268 */
269 char const* ScilabView::getCurrentFigure()
270 {
271     //std::cerr << "[ScilaView] currentFigure = " << (m_currentFigure == NULL ? "NULL !!" : m_currentFigure) << std::endl;
272     if (m_currentFigure.length() == 0)
273     {
274         return NULL;
275     }
276     return m_currentFigure.c_str();
277 }
278
279 /*
280 ** Set Current Object UID
281 */
282 void ScilabView::setCurrentObject(char const* UID)
283 {
284     if (UID == NULL)
285     {
286         m_currentObject = std::string();
287     }
288     else
289     {
290         m_currentObject = UID;
291     }
292 }
293
294 /*
295 ** Get Current Figure UID
296 */
297 char const* ScilabView::getCurrentObject()
298 {
299     //std::cerr << "[ScilaView] currentObject = " << m_currentObject << std::endl;
300     if (m_currentFigure.length() == 0)
301     {
302         return NULL;
303     }
304     return m_currentObject.c_str();
305 }
306
307 /*
308 ** Set Current SubWin UID
309 */
310 void ScilabView::setCurrentSubWin(char const* UID)
311 {
312     if (UID == NULL)
313     {
314         m_currentSubWin = std::string();
315     }
316     else
317     {
318         m_currentSubWin = UID;
319     }
320 }
321
322 /*
323 ** Get Current Figure UID
324 */
325 char const* ScilabView::getCurrentSubWin()
326 {
327     //std::cerr << "[ScilaView] currentSubWin = " << m_currentSubWin << std::endl;
328     if (m_currentSubWin.length() == 0)
329     {
330         return NULL;
331     }
332     return m_currentSubWin.c_str();
333 }
334
335 /*
336 ** Scilab only can store long as handle
337 */
338 long ScilabView::getObjectHandle(char const* UID)
339 {
340     /*
341      * if (UID != NULL)
342      * {
343      * std::cerr << "UID = " << UID << std::endl;
344      * }
345      * else
346      * {
347      * std::cerr << "UID is null :-S" << std::endl;
348      * }
349      * __handleList_iterator it2;
350      * std::cerr << "[DEBUG] +++ handleMap +++" << std::endl;
351      * for (it2 = m_handleList.begin() ; it2 != m_handleList.end() ; ++it2)
352      * {
353      * std::cerr << "UID " << it2->first << " <-> handle " << it2->second << std::endl;
354      * }
355      * std::cerr << "[DEBUG] +++ handleMap +++" << std::endl;
356      */
357     __handleList_iterator it = m_handleList.find(UID);
358
359     if (it != m_handleList.end())
360     {
361         return it->second;
362     }
363
364     // increase maximum value
365     // register new handle and return it.
366     m_topHandleValue++;
367     m_handleList[UID] = m_topHandleValue;
368     m_uidList[m_topHandleValue] = UID;
369
370     return m_topHandleValue;
371 }
372
373 char const* ScilabView::getObjectFromHandle(long handle)
374 {
375     __uidList_iterator it = m_uidList.find(handle);
376     if (it == m_uidList.end())
377     {
378         return NULL;
379     }
380
381     return it->second.c_str();
382 }
383
384 char const* ScilabView::getFigureModel(void)
385 {
386     //std::cerr << "[ScilabView] getFigureModel = " << (m_figureModel == NULL ? "!! NULL !!" : m_figureModel) << std::endl;
387     if (m_figureModel.length() == 0)
388     {
389         return NULL;
390     }
391     return m_figureModel.c_str();
392 }
393
394 void ScilabView::setFigureModel(char const* UID)
395 {
396     m_figureModel = UID;
397 }
398
399 char const* ScilabView::getAxesModel(void)
400 {
401     //std::cerr << "[ScilabView] getAxesModel = " << (m_axesModel == NULL ? "!! NULL !!" : m_axesModel) << std::endl;
402     if (m_axesModel.length() == 0)
403     {
404         return NULL;
405     }
406     return m_axesModel.c_str();
407 }
408
409 void ScilabView::setAxesModel(char const* UID)
410 {
411     m_axesModel = UID;
412 }
413
414 /*
415 ** Allocate static class variable.
416 */
417 ScilabView::__figureList ScilabView::m_figureList = *new __figureList();
418 ScilabView::__handleList ScilabView::m_handleList = *new __handleList();
419 ScilabView::__uidList ScilabView::m_uidList = *new __uidList();
420 long ScilabView::m_topHandleValue = 0;
421 std::string ScilabView::m_currentFigure;
422 std::string ScilabView::m_currentObject;
423 std::string ScilabView::m_currentSubWin;
424 std::string ScilabView::m_figureModel;
425 std::string ScilabView::m_axesModel;