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

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

thread stack size rework
add Matrix class

File size: 10.0 KB
RevLine 
[2]1// %flair:license{
[15]2// This file is part of the Flair framework distributed under the
3// CECILL-C License, Version 1.0.
[2]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
[15]33namespace {
[2]34#ifdef __XENO__
[213]35RT_HEAP rt_xml_heap;
[2]36
[213]37void rt_xml2_free(void *mem) {
[15]38 // Printf("free %x\n",mem);
39 if (mem == NULL)
40 return;
[213]41 int status = rt_heap_free(&rt_xml_heap, mem);
[2]42
[15]43 if (status != 0) {
[133]44 char errorMsg[256];
45 printf("libxml2: rt_heap_free error (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
[15]46 }
47}
[2]48
[213]49void *rt_xml2_alloc(size_t sz) {
[15]50 void *ptr;
51 // printf("alloc %i\n",sz);
[213]52 int status = rt_heap_alloc(&rt_xml_heap, sz, TM_NONBLOCK, &ptr);
[15]53 if (status != 0) {
[133]54 char errorMsg[256];
55 printf("libxml2: rt_heap_alloc error (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
[15]56 }
57 // Printf("alloc %x %i\n",ptr,sz);
[2]58
[15]59 return ptr;
60}
[2]61
[213]62void *rt_xml2_realloc(void *emem, size_t sz) {
[15]63 // Printf("realloc %x %i -> %i\n",emem,sz,sz);
64 void *mem_re;
[2]65
[15]66 if (emem == NULL) {
[213]67 return rt_xml2_alloc(sz);
[15]68 } else if (sz == 0) {
[213]69 rt_xml2_free(emem);
[15]70 }
[2]71
[213]72 mem_re = rt_xml2_alloc(sz);
[2]73
[15]74 memcpy(mem_re, emem, sz);
[2]75
[213]76 rt_xml2_free(emem);
[2]77
[15]78 return mem_re;
79}
[2]80
[213]81char *rt_xml2_strdup(const char *str) {
[15]82 // printf("strdup %s\n",str);
[213]83 char *s = (char *)rt_xml2_alloc(strlen(str) + 1);
[15]84 if (s == NULL)
85 return NULL;
[2]86
[15]87 strcpy(s, str);
88 return s;
89}
[2]90#endif //__XENO__
91}
92
[15]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;
[2]99
[15]100 // n'est execute qu'une fois lorsqu'on construit le FrameworkManager
101 if (parent == NULL) {
[2]102#ifdef __XENO__
[15]103 string tmp_name;
104 tmp_name = name + "-xml";
[213]105 int status = rt_heap_create(&rt_xml_heap, tmp_name.c_str(), RT_XML_HEAP, H_FIFO);
[15]106 if (status != 0) {
[133]107 char errorMsg[256];
108 self->Err("rt_heap_create error (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
[15]109 }
[2]110
[213]111 xmlMemSetup(rt_xml2_free, rt_xml2_alloc, rt_xml2_realloc, rt_xml2_strdup);
[2]112#endif //__XENO__
[15]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");
[2]135 }
136
[15]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();
[2]144 }
145
[15]146 send_doc = parent->pimpl_->CopyDoc();
[2]147
[15]148 // on recupere le dernier node
149 xmlNodePtr node = xmlDocGetRootElement(send_doc);
150 while (node->children != NULL)
151 node = node->children;
[2]152
[15]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 }
[2]158
[15]159 // Printf("Widget ok %s\n",name.c_str());
[2]160}
161
[15]162Widget_impl::~Widget_impl() {
163 // Printf("destruction widget %s\n",self->ObjectName().c_str());
[2]164
[15]165 if (self->Parent() != NULL)
166 ((Widget *)(self->Parent()))->pimpl_->RemoveChild(self);
[2]167
[15]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();
[2]178
[15]179 self->SetVolatileXmlProp("Delete", true);
[2]180
[15]181 if (self->Parent() != NULL)
182 SendXml();
[2]183
[15]184 xmlFreeDoc(send_doc);
[2]185
[15]186 if (self->Parent() == NULL) {
187 xmlCleanupParser();
[2]188#ifdef __XENO__
[15]189 int status;
190 RT_HEAP_INFO info;
[213]191 status = rt_heap_inquire(&rt_xml_heap, &info);
[15]192 if (status != 0) {
[213]193 char errorMsg[256];
[133]194 self->Err("rt_heap_inquire error (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
[15]195 }
196 if (info.usedmem != 0)
197 self->Err("fuite memoire xml heap (%ld)\n", info.usedmem);
198 // Printf("fin heap xml\n");
[213]199 status = rt_heap_delete(&rt_xml_heap);
[15]200 if (status != 0) {
[213]201 char errorMsg[256];
[133]202 self->Err("rt_heap_delete error (%s)\n", strerror_r(-status, errorMsg, sizeof(errorMsg)));
[15]203 }
[2]204#endif
[15]205 }
206 // Printf("destruction widget %s ok\n",self->ObjectName().c_str());
[2]207}
208
[15]209void Widget_impl::AddChild(const Widget *child) {
210 childs.push_back((Widget *)child);
[2]211}
212
[15]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;
[2]219 }
[15]220 }
[2]221}
222
[15]223xmlDocPtr Widget_impl::CopyDoc(void) { return xmlCopyDoc(send_doc, 1); }
[2]224
225void Widget_impl::ClearXmlProps(void) {
[15]226 xmlUnlinkNode(send_node);
227 xmlFreeNode(send_node);
[2]228
[15]229 xmlNodePtr node;
230 node = xmlDocGetRootElement(send_doc);
[2]231
[15]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 }
[2]245}
246
247void Widget_impl::printSendNode() {
248
[15]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) {
[2]258 xmlChar *xmlbuff;
259 int buffersize;
[15]260 xmlDocDumpFormatMemory(send_doc, &xmlbuff, &buffersize, 0);
261 getUiCom()->Send((char *)xmlbuff, buffersize);
[2]262 xmlFree(xmlbuff);
263
[15]264 ClearXmlProps();
265 }
[2]266}
267
268void Widget_impl::setEnabled(bool status) {
[15]269 self->SetVolatileXmlProp("IsEnabled", status);
270 SendXml();
[2]271}
272
[15]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;
[2]277
[15]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 }
[2]302
[15]303 if (name != NULL)
304 xmlFree(name);
[2]305
[15]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 }
[2]316
[15]317 childs[i]->XmlEvent();
[2]318
[15]319 childs[i]->pimpl_->ProcessXML(cur_node->children);
320 break;
[2]321 }
[15]322 if (name != NULL)
323 xmlFree(name);
324 }
[2]325 }
[15]326 }
[2]327
[15]328 // printf("fin ProcessXML %s %s\n",xmlGetProp(send_node,
329 // (xmlChar*)"name"),send_node->name);
[2]330}
331
[15]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);
[2]350 }
[15]351 }
[2]352
[15]353 return NULL;
[2]354}
Note: See TracBrowser for help on using the repository browser.