source: flair-src/branches/mavlink/lib/FlairCore/src/Widget_impl.cpp@ 57

Last change on this file since 57 was 15, checked in by Bayard Gildas, 8 years ago

sources reformatted with flair-format-dir script

File size: 9.8 KB
Line 
1// %flair:license{
2// This file is part of the Flair framework distributed under the
3// CECILL-C License, Version 1.0.
4// %flair:license}
5// created: 2012/05/02
6// filename: Widget.cpp
7//
8// author: Guillaume Sanahuja
9// Copyright Heudiasyc UMR UTC/CNRS 7253
10//
11// version: $Id: $
12//
13// purpose: classe pour widget
14//
15//
16/*********************************************************************/
17
18#include "Widget.h"
19#include "Widget_impl.h"
20#include "Object_impl.h"
21#include "FrameworkManager.h"
22#include "FrameworkManager_impl.h"
23#include "config.h"
24#ifdef __XENO__
25#include <native/heap.h>
26#else
27#include <errno.h>
28#include <cstring>
29#endif
30
31using std::string;
32using std::vector;
33using namespace flair::core;
34using namespace flair::gui;
35
36namespace {
37#ifdef __XENO__
38RT_HEAP xml_heap;
39
40void xml2_free(void *mem) {
41 // Printf("free %x\n",mem);
42 if (mem == NULL)
43 return;
44 int status = rt_heap_free(&xml_heap, mem);
45
46 if (status != 0) {
47 printf("libxml2: rt_heap_free error (%s)\n", strerror(-status));
48 }
49}
50
51void *xml2_alloc(size_t sz) {
52 void *ptr;
53 // printf("alloc %i\n",sz);
54 int status = rt_heap_alloc(&xml_heap, sz, TM_NONBLOCK, &ptr);
55 if (status != 0) {
56 printf("libxml2: rt_heap_alloc error (%s)\n", strerror(-status));
57 }
58 // Printf("alloc %x %i\n",ptr,sz);
59
60 return ptr;
61}
62
63void *xml2_realloc(void *emem, size_t sz) {
64 // Printf("realloc %x %i -> %i\n",emem,sz,sz);
65 void *mem_re;
66
67 if (emem == NULL) {
68 return xml2_alloc(sz);
69 } else if (sz == 0) {
70 xml2_free(emem);
71 }
72
73 mem_re = xml2_alloc(sz);
74
75 memcpy(mem_re, emem, sz);
76
77 xml2_free(emem);
78
79 return mem_re;
80}
81
82char *xml2_strdup(const char *str) {
83 // printf("strdup %s\n",str);
84 char *s = (char *)xml2_alloc(strlen(str) + 1);
85 if (s == NULL)
86 return NULL;
87
88 strcpy(s, str);
89 return s;
90}
91#endif //__XENO__
92}
93
94Widget_impl::Widget_impl(Widget *self, const Widget *parent, string name,
95 string type) {
96 // Printf("Widget %s\n",name.c_str());
97 isenabled = true;
98 file_node = NULL;
99 this->self = self;
100
101 // n'est execute qu'une fois lorsqu'on construit le FrameworkManager
102 if (parent == NULL) {
103#ifdef __XENO__
104 string tmp_name;
105 tmp_name = name + "-xml";
106 int status = rt_heap_create(&xml_heap, tmp_name.c_str(), XML_HEAP, H_FIFO);
107 if (status != 0) {
108 self->Err("rt_heap_create error (%s)\n", strerror(-status));
109 }
110
111 xmlMemSetup(xml2_free, xml2_alloc, xml2_realloc, xml2_strdup);
112#endif //__XENO__
113 }
114
115 // xml init
116 if (parent == NULL) {
117 // create local doc
118 send_doc = xmlNewDoc((xmlChar *)"1.0");
119 send_node = xmlNewNode(NULL, (xmlChar *)type.c_str());
120 xmlDocSetRootElement(send_doc, send_node);
121 xmlSetProp(send_node, (xmlChar *)"name",
122 (xmlChar *)self->ObjectName().c_str());
123 } else {
124 parent->pimpl_->AddChild(self);
125
126 // get node corresponding to this widget in the xml file
127 if (parent->pimpl_->file_node != NULL) {
128 xmlChar *search = xmlCharStrdup(type.c_str());
129 file_node =
130 GetNodeByProp(parent->pimpl_->file_node->xmlChildrenNode, search,
131 (xmlChar *)"name", (xmlChar *)name.c_str());
132 xmlFree(search);
133 } else {
134 self->Err("parent->file_node is NULL\n");
135 }
136
137 if (file_node == NULL) {
138 self->Warn("%s, no match found in xml file\n", type.c_str());
139 xmlNode *node;
140 node = xmlNewNode(NULL, (xmlChar *)type.c_str());
141 xmlSetProp(node, (xmlChar *)"name", (xmlChar *)name.c_str());
142 file_node = xmlAddChild(parent->pimpl_->file_node, node);
143 //((Widget*)getFrameworkManager())->pimpl_->PrintXml();
144 }
145
146 send_doc = parent->pimpl_->CopyDoc();
147
148 // on recupere le dernier node
149 xmlNodePtr node = xmlDocGetRootElement(send_doc);
150 while (node->children != NULL)
151 node = node->children;
152
153 // on ajoute le node du widget
154 send_node = xmlNewNode(NULL, (xmlChar *)type.c_str());
155 xmlSetProp(send_node, (xmlChar *)"name", (xmlChar *)name.c_str());
156 xmlAddChild(node, send_node);
157 }
158
159 // Printf("Widget ok %s\n",name.c_str());
160}
161
162Widget_impl::~Widget_impl() {
163 // Printf("destruction widget %s\n",self->ObjectName().c_str());
164
165 if (self->Parent() != NULL)
166 ((Widget *)(self->Parent()))->pimpl_->RemoveChild(self);
167
168 // on efface les widgets enfants avant d'envoyer son propre delete au sol
169 // dans le delete child on modifie le child du parent, donc on se refere
170 // toujours au premier
171 while (childs.size() != 0) {
172 // Printf("child %i
173 // %s\n",childs.size(),childs.front()->ObjectName().c_str());
174 if (childs.front() != NULL)
175 delete childs.front();
176 }
177 childs.clear();
178
179 self->SetVolatileXmlProp("Delete", true);
180
181 if (self->Parent() != NULL)
182 SendXml();
183
184 xmlFreeDoc(send_doc);
185
186 if (self->Parent() == NULL) {
187 xmlCleanupParser();
188#ifdef __XENO__
189 int status;
190 RT_HEAP_INFO info;
191 status = rt_heap_inquire(&xml_heap, &info);
192 if (status != 0) {
193 self->Err("rt_heap_inquire error (%s)\n", strerror(-status));
194 }
195 if (info.usedmem != 0)
196 self->Err("fuite memoire xml heap (%ld)\n", info.usedmem);
197 // Printf("fin heap xml\n");
198 status = rt_heap_delete(&xml_heap);
199 if (status != 0) {
200 self->Err("rt_heap_delete error (%s)\n", strerror(-status));
201 }
202#endif
203 }
204 // Printf("destruction widget %s ok\n",self->ObjectName().c_str());
205}
206
207void Widget_impl::AddChild(const Widget *child) {
208 childs.push_back((Widget *)child);
209}
210
211void Widget_impl::RemoveChild(const Widget *child) {
212 for (vector<Widget *>::iterator it = childs.begin(); it < childs.end();
213 it++) {
214 if (*it == child) {
215 childs.erase(it);
216 break;
217 }
218 }
219}
220
221xmlDocPtr Widget_impl::CopyDoc(void) { return xmlCopyDoc(send_doc, 1); }
222
223void Widget_impl::ClearXmlProps(void) {
224 xmlUnlinkNode(send_node);
225 xmlFreeNode(send_node);
226
227 xmlNodePtr node;
228 node = xmlDocGetRootElement(send_doc);
229
230 if (node == NULL) { // il ne reste plus rien, on refait le rootelement
231 send_node = xmlNewNode(NULL, (xmlChar *)XML_ROOT_TYPE);
232 xmlSetProp(send_node, (xmlChar *)"name",
233 (xmlChar *)self->ObjectName().c_str());
234 xmlDocSetRootElement(send_doc, send_node);
235 } else {
236 while (node->children != NULL)
237 node = node->children;
238 send_node = xmlNewNode(NULL, (xmlChar *)self->ObjectType().c_str());
239 xmlSetProp(send_node, (xmlChar *)"name",
240 (xmlChar *)self->ObjectName().c_str());
241 xmlAddChild(node, send_node);
242 }
243}
244
245void Widget_impl::printSendNode() {
246
247 xmlChar *xmlbuff;
248 int buffersize;
249 xmlDocDumpFormatMemory(send_doc, &xmlbuff, &buffersize, 1);
250 Printf("xml:\n%s\n", xmlbuff);
251 xmlFree(xmlbuff);
252}
253
254void Widget_impl::SendXml(void) {
255 if (getUiCom() != NULL) {
256 xmlChar *xmlbuff;
257 int buffersize;
258 xmlDocDumpFormatMemory(send_doc, &xmlbuff, &buffersize, 0);
259 getUiCom()->Send((char *)xmlbuff, buffersize);
260 xmlFree(xmlbuff);
261
262 ClearXmlProps();
263 }
264}
265
266void Widget_impl::setEnabled(bool status) {
267 self->SetVolatileXmlProp("IsEnabled", status);
268 SendXml();
269}
270
271void Widget_impl::ProcessXML(xmlNode *node) {
272 // Printf("ProcessXML %s %s\n",xmlGetProp(send_node,
273 // (xmlChar*)"name"),send_node->name);
274 xmlNode *cur_node = NULL;
275
276 for (size_t i = 0; i < childs.size(); i++) {
277 for (cur_node = node; cur_node; cur_node = cur_node->next) {
278 if (cur_node->type == XML_ELEMENT_NODE) {
279 // Printf("recherche %s\n", xmlGetProp(cur_node, (xmlChar*)"name"));
280 xmlChar *name = NULL;
281 name = xmlGetProp(cur_node, (xmlChar *)"name");
282 if (!xmlStrcmp((xmlChar *)childs[i]->ObjectName().c_str(), name)) {
283 // Printf("correspond %s\n",childs[i]->ObjectName().c_str());
284 xmlChar *new_name = NULL;
285 new_name = xmlGetProp(cur_node, (xmlChar *)"new_name");
286 if (new_name != NULL) {
287 unsigned char *ren_name =
288 new_name; // xmlGetProp(cur_node, (xmlChar*)"new_name");
289 self->Warn(
290 "%s existe deja, renommage en %s; possiblite de problemes!!\n",
291 childs[i]->ObjectName().c_str(), new_name);
292 childs[i]->Object::pimpl_->name = ((const char *)ren_name);
293 xmlSetProp(childs[i]->pimpl_->send_node, (xmlChar *)"name",
294 xmlGetProp(cur_node, (xmlChar *)"new_name"));
295 xmlFree(new_name);
296 if (name != NULL)
297 xmlFree(name);
298 break;
299 }
300
301 if (name != NULL)
302 xmlFree(name);
303
304 // update file node
305 xmlAttr *cur_prop = NULL;
306 // xmlAttr *file_prop = NULL;
307 for (cur_prop = cur_node->properties; cur_prop;
308 cur_prop = cur_prop->next) {
309 // Printf("rcv prop %s
310 // %s\n",cur_prop->name,cur_prop->children->content);
311 xmlSetProp(childs[i]->pimpl_->file_node, cur_prop->name,
312 cur_prop->children->content);
313 }
314
315 childs[i]->XmlEvent();
316
317 childs[i]->pimpl_->ProcessXML(cur_node->children);
318 break;
319 }
320 if (name != NULL)
321 xmlFree(name);
322 }
323 }
324 }
325
326 // printf("fin ProcessXML %s %s\n",xmlGetProp(send_node,
327 // (xmlChar*)"name"),send_node->name);
328}
329
330xmlNodePtr Widget_impl::GetNodeByProp(xmlNodePtr doc, xmlChar *type,
331 xmlChar *prop, xmlChar *value) {
332 // printf("cherche keyword: %s %s %s\n", type,prop,value);
333 xmlNode *cur_node = NULL;
334 for (cur_node = doc; cur_node; cur_node = cur_node->next) {
335 if (cur_node->type == XML_ELEMENT_NODE) {
336 // printf("node %s %s\n",xmlGetProp(cur_node,
337 // (xmlChar*)"name"),cur_node->name);
338 xmlChar *test = NULL;
339 test = xmlGetProp(cur_node, prop);
340 if (!xmlStrcmp(test, value) && !xmlStrcmp(cur_node->name, type)) {
341 // printf("ok\n");
342 if (test != NULL)
343 xmlFree(test);
344 return cur_node;
345 }
346 if (test != NULL)
347 xmlFree(test);
348 }
349 }
350
351 return NULL;
352}
Note: See TracBrowser for help on using the repository browser.