source: flair-src/trunk/lib/FlairCore/src/Widget_impl.cpp@ 447

Last change on this file since 447 was 213, checked in by Sanahuja Guillaume, 6 years ago

thread stack size rework
add Matrix class

File size: 10.0 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#endif
27
28using std::string;
29using std::vector;
30using namespace flair::core;
31using namespace flair::gui;
32
33namespace {
34#ifdef __XENO__
35RT_HEAP rt_xml_heap;
36
37void rt_xml2_free(void *mem) {
38 // Printf("free %x\n",mem);
39 if (mem == NULL)
40 return;
41 int status = rt_heap_free(&rt_xml_heap, mem);
42
43 if (status != 0) {
44 char errorMsg[256];
45 printf("libxml2: rt_heap_free error (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
46 }
47}
48
49void *rt_xml2_alloc(size_t sz) {
50 void *ptr;
51 // printf("alloc %i\n",sz);
52 int status = rt_heap_alloc(&rt_xml_heap, sz, TM_NONBLOCK, &ptr);
53 if (status != 0) {
54 char errorMsg[256];
55 printf("libxml2: rt_heap_alloc error (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
56 }
57 // Printf("alloc %x %i\n",ptr,sz);
58
59 return ptr;
60}
61
62void *rt_xml2_realloc(void *emem, size_t sz) {
63 // Printf("realloc %x %i -> %i\n",emem,sz,sz);
64 void *mem_re;
65
66 if (emem == NULL) {
67 return rt_xml2_alloc(sz);
68 } else if (sz == 0) {
69 rt_xml2_free(emem);
70 }
71
72 mem_re = rt_xml2_alloc(sz);
73
74 memcpy(mem_re, emem, sz);
75
76 rt_xml2_free(emem);
77
78 return mem_re;
79}
80
81char *rt_xml2_strdup(const char *str) {
82 // printf("strdup %s\n",str);
83 char *s = (char *)rt_xml2_alloc(strlen(str) + 1);
84 if (s == NULL)
85 return NULL;
86
87 strcpy(s, str);
88 return s;
89}
90#endif //__XENO__
91}
92
93Widget_impl::Widget_impl(Widget *self, const Widget *parent, string name,
94 string type) {
95 // Printf("Widget %s\n",name.c_str());
96 isenabled = true;
97 file_node = NULL;
98 this->self = self;
99
100 // n'est execute qu'une fois lorsqu'on construit le FrameworkManager
101 if (parent == NULL) {
102#ifdef __XENO__
103 string tmp_name;
104 tmp_name = name + "-xml";
105 int status = rt_heap_create(&rt_xml_heap, tmp_name.c_str(), RT_XML_HEAP, H_FIFO);
106 if (status != 0) {
107 char errorMsg[256];
108 self->Err("rt_heap_create error (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
109 }
110
111 xmlMemSetup(rt_xml2_free, rt_xml2_alloc, rt_xml2_realloc, rt_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(&rt_xml_heap, &info);
192 if (status != 0) {
193 char errorMsg[256];
194 self->Err("rt_heap_inquire error (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
195 }
196 if (info.usedmem != 0)
197 self->Err("fuite memoire xml heap (%ld)\n", info.usedmem);
198 // Printf("fin heap xml\n");
199 status = rt_heap_delete(&rt_xml_heap);
200 if (status != 0) {
201 char errorMsg[256];
202 self->Err("rt_heap_delete error (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
203 }
204#endif
205 }
206 // Printf("destruction widget %s ok\n",self->ObjectName().c_str());
207}
208
209void Widget_impl::AddChild(const Widget *child) {
210 childs.push_back((Widget *)child);
211}
212
213void Widget_impl::RemoveChild(const Widget *child) {
214 for (vector<Widget *>::iterator it = childs.begin(); it < childs.end();
215 it++) {
216 if (*it == child) {
217 childs.erase(it);
218 break;
219 }
220 }
221}
222
223xmlDocPtr Widget_impl::CopyDoc(void) { return xmlCopyDoc(send_doc, 1); }
224
225void Widget_impl::ClearXmlProps(void) {
226 xmlUnlinkNode(send_node);
227 xmlFreeNode(send_node);
228
229 xmlNodePtr node;
230 node = xmlDocGetRootElement(send_doc);
231
232 if (node == NULL) { // il ne reste plus rien, on refait le rootelement
233 send_node = xmlNewNode(NULL, (xmlChar *)XML_ROOT_TYPE);
234 xmlSetProp(send_node, (xmlChar *)"name",
235 (xmlChar *)self->ObjectName().c_str());
236 xmlDocSetRootElement(send_doc, send_node);
237 } else {
238 while (node->children != NULL)
239 node = node->children;
240 send_node = xmlNewNode(NULL, (xmlChar *)self->ObjectType().c_str());
241 xmlSetProp(send_node, (xmlChar *)"name",
242 (xmlChar *)self->ObjectName().c_str());
243 xmlAddChild(node, send_node);
244 }
245}
246
247void Widget_impl::printSendNode() {
248
249 xmlChar *xmlbuff;
250 int buffersize;
251 xmlDocDumpFormatMemory(send_doc, &xmlbuff, &buffersize, 1);
252 Printf("xml:\n%s\n", xmlbuff);
253 xmlFree(xmlbuff);
254}
255
256void Widget_impl::SendXml(void) {
257 if (getUiCom() != NULL) {
258 xmlChar *xmlbuff;
259 int buffersize;
260 xmlDocDumpFormatMemory(send_doc, &xmlbuff, &buffersize, 0);
261 getUiCom()->Send((char *)xmlbuff, buffersize);
262 xmlFree(xmlbuff);
263
264 ClearXmlProps();
265 }
266}
267
268void Widget_impl::setEnabled(bool status) {
269 self->SetVolatileXmlProp("IsEnabled", status);
270 SendXml();
271}
272
273void Widget_impl::ProcessXML(xmlNode *node) {
274 // Printf("ProcessXML %s %s\n",xmlGetProp(send_node,
275 // (xmlChar*)"name"),send_node->name);
276 xmlNode *cur_node = NULL;
277
278 for (size_t i = 0; i < childs.size(); i++) {
279 for (cur_node = node; cur_node; cur_node = cur_node->next) {
280 if (cur_node->type == XML_ELEMENT_NODE) {
281 // Printf("recherche %s\n", xmlGetProp(cur_node, (xmlChar*)"name"));
282 xmlChar *name = NULL;
283 name = xmlGetProp(cur_node, (xmlChar *)"name");
284 if (!xmlStrcmp((xmlChar *)childs[i]->ObjectName().c_str(), name)) {
285 // Printf("correspond %s\n",childs[i]->ObjectName().c_str());
286 xmlChar *new_name = NULL;
287 new_name = xmlGetProp(cur_node, (xmlChar *)"new_name");
288 if (new_name != NULL) {
289 unsigned char *ren_name =
290 new_name; // xmlGetProp(cur_node, (xmlChar*)"new_name");
291 self->Warn(
292 "%s existe deja, renommage en %s; possiblite de problemes!!\n",
293 childs[i]->ObjectName().c_str(), new_name);
294 childs[i]->Object::pimpl_->name = ((const char *)ren_name);
295 xmlSetProp(childs[i]->pimpl_->send_node, (xmlChar *)"name",
296 xmlGetProp(cur_node, (xmlChar *)"new_name"));
297 xmlFree(new_name);
298 if (name != NULL)
299 xmlFree(name);
300 break;
301 }
302
303 if (name != NULL)
304 xmlFree(name);
305
306 // update file node
307 xmlAttr *cur_prop = NULL;
308 // xmlAttr *file_prop = NULL;
309 for (cur_prop = cur_node->properties; cur_prop;
310 cur_prop = cur_prop->next) {
311 // Printf("rcv prop %s
312 // %s\n",cur_prop->name,cur_prop->children->content);
313 xmlSetProp(childs[i]->pimpl_->file_node, cur_prop->name,
314 cur_prop->children->content);
315 }
316
317 childs[i]->XmlEvent();
318
319 childs[i]->pimpl_->ProcessXML(cur_node->children);
320 break;
321 }
322 if (name != NULL)
323 xmlFree(name);
324 }
325 }
326 }
327
328 // printf("fin ProcessXML %s %s\n",xmlGetProp(send_node,
329 // (xmlChar*)"name"),send_node->name);
330}
331
332xmlNodePtr Widget_impl::GetNodeByProp(xmlNodePtr doc, xmlChar *type,
333 xmlChar *prop, xmlChar *value) {
334 // printf("cherche keyword: %s %s %s\n", type,prop,value);
335 xmlNode *cur_node = NULL;
336 for (cur_node = doc; cur_node; cur_node = cur_node->next) {
337 if (cur_node->type == XML_ELEMENT_NODE) {
338 // printf("node %s %s\n",xmlGetProp(cur_node,
339 // (xmlChar*)"name"),cur_node->name);
340 xmlChar *test = NULL;
341 test = xmlGetProp(cur_node, prop);
342 if (!xmlStrcmp(test, value) && !xmlStrcmp(cur_node->name, type)) {
343 // printf("ok\n");
344 if (test != NULL)
345 xmlFree(test);
346 return cur_node;
347 }
348 if (test != NULL)
349 xmlFree(test);
350 }
351 }
352
353 return NULL;
354}
Note: See TracBrowser for help on using the repository browser.