src/model.c: iteration on siblings of a given node
This commit is contained in:
parent
e70154923f
commit
256fa60f13
407
src/model.c
407
src/model.c
|
@ -202,6 +202,38 @@ xmlNodePtr model_copy_node(struct model_t *self,
|
||||||
|
|
||||||
return copiedNode;
|
return copiedNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterates over all sibling nodes of a given node, typically used to process
|
||||||
|
* each child of a specific parent node.
|
||||||
|
*
|
||||||
|
* This function takes a starting node (expected to be a parent node like <states>)
|
||||||
|
* and iterates through all of its child nodes.
|
||||||
|
* It calls a user-provided callback function for each child node that is an
|
||||||
|
* element node (ignores text and other types of nodes).
|
||||||
|
*
|
||||||
|
* @param node The starting node whose siblings (children) will be iterated
|
||||||
|
* over. This node is not processed by the callback, only its siblings are.
|
||||||
|
* @param processNode A callback function that will be called for each sibling
|
||||||
|
* node. This function should have a signature of
|
||||||
|
* void functionName(xmlNodePtr node, void* userData), where
|
||||||
|
* 'node' is the current sibling element node, and
|
||||||
|
* 'userData' is a pointer to user-defined data passed
|
||||||
|
* through iterateSiblings.
|
||||||
|
* @param userData A void pointer to user-defined data. This can be used to pass
|
||||||
|
* additional information to the callback function. It is passed
|
||||||
|
* directly through to the callback function as its second argument.
|
||||||
|
*/
|
||||||
|
void model_iterate_node(xmlNodePtr node,
|
||||||
|
void (*processNode)(xmlNodePtr node, void* userData), void* userData)
|
||||||
|
{
|
||||||
|
for (xmlNodePtr curNode = node->children; curNode; curNode = curNode->next) {
|
||||||
|
if (curNode->type == XML_ELEMENT_NODE) {
|
||||||
|
processNode (curNode, userData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
char model_get_dim (struct model_t *self)
|
char model_get_dim (struct model_t *self)
|
||||||
|
@ -242,381 +274,6 @@ char model_get_multiplicity (struct model_t *self)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool model_get_next_state (struct model_t *self, char *new_state_id)
|
|
||||||
{
|
|
||||||
static xmlNodePtr cur_node = NULL;
|
|
||||||
xmlAttr *attribute;
|
|
||||||
xmlChar *value;
|
|
||||||
|
|
||||||
if (cur_node == NULL) {
|
|
||||||
// Get first state
|
|
||||||
cur_node = model_get_node(self, (xmlChar *)"savedstates/state");
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// Get next state
|
|
||||||
if (cur_node->next)
|
|
||||||
cur_node = cur_node->next;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lookup in properties
|
|
||||||
if (model_get_node_str_attrib(cur_node, "id", new_state_id))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
cur_node = NULL;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
long model_get_state_arrows_count (struct model_t *self, const char *state_id)
|
|
||||||
{
|
|
||||||
xmlNodePtr cur_node = NULL;
|
|
||||||
xmlAttr *attribute;
|
|
||||||
long value = 0;
|
|
||||||
bool found = false;
|
|
||||||
char temp_char[25];
|
|
||||||
uint check = 0; // bit field checker
|
|
||||||
|
|
||||||
//printf("NEW CALL : cur_node = %p\n", cur_node);
|
|
||||||
|
|
||||||
assert(state_id);
|
|
||||||
|
|
||||||
// Get first state node
|
|
||||||
cur_node = model_get_node(self, (xmlChar *)"savedstates/state");
|
|
||||||
|
|
||||||
// Lookup in properties
|
|
||||||
while (cur_node && cur_node->properties) {
|
|
||||||
attribute = cur_node->properties;
|
|
||||||
|
|
||||||
// Look for the id attribute
|
|
||||||
if (model_get_node_str_attrib(cur_node, "id", &temp_char)) {
|
|
||||||
if (!xmlStrcmp(temp_char, (const xmlChar *)state_id)) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cur_node = cur_node->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the state has been found
|
|
||||||
if (!found) {
|
|
||||||
cur_node = NULL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Count arrows
|
|
||||||
if (cur_node->children) {
|
|
||||||
cur_node = cur_node->children;
|
|
||||||
while (cur_node) {
|
|
||||||
if (!xmlStrcmp(cur_node->name, (const xmlChar *)"arrow"))
|
|
||||||
value++;
|
|
||||||
cur_node = cur_node->next;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool model_get_next_arrow (struct model_t *self,
|
|
||||||
struct arrow_t *new_arrow,
|
|
||||||
const char *state_id,
|
|
||||||
char dimension)
|
|
||||||
{
|
|
||||||
static xmlNodePtr cur_node = NULL;
|
|
||||||
xmlAttr *attribute;
|
|
||||||
xmlChar *value;
|
|
||||||
bool found = false;
|
|
||||||
char temp_char[25];
|
|
||||||
uint check = 0; // bit field checker
|
|
||||||
|
|
||||||
//printf("NEW CALL : cur_node = %p\n", cur_node);
|
|
||||||
|
|
||||||
assert(new_arrow);
|
|
||||||
assert(state_id);
|
|
||||||
|
|
||||||
if (cur_node == NULL) {
|
|
||||||
// Get first state node
|
|
||||||
cur_node = model_get_node(self, (xmlChar *)"savedstates/state");
|
|
||||||
|
|
||||||
// Lookup in properties
|
|
||||||
while (cur_node && cur_node->properties) {
|
|
||||||
attribute = cur_node->properties;
|
|
||||||
|
|
||||||
// Look for the id attribute
|
|
||||||
if (model_get_node_str_attrib(cur_node, "id", &temp_char)) {
|
|
||||||
if (!xmlStrcmp(temp_char, (const xmlChar *)state_id)) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cur_node = cur_node->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the state has been found
|
|
||||||
if (!found) {
|
|
||||||
cur_node = NULL;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get first arrow
|
|
||||||
if (cur_node->children) {
|
|
||||||
cur_node = cur_node->children;
|
|
||||||
|
|
||||||
found = false;
|
|
||||||
while (cur_node && cur_node->name) {
|
|
||||||
if (!xmlStrcmp(cur_node->name, (const xmlChar *)"arrow")) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
cur_node = cur_node->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the state has been found
|
|
||||||
if (!found) {
|
|
||||||
cur_node = NULL;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// Get next arrow
|
|
||||||
found = false;
|
|
||||||
while (cur_node->next) {
|
|
||||||
cur_node = cur_node->next;
|
|
||||||
if (!xmlStrcmp(cur_node->name, (const xmlChar *)"arrow")) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the state has been found
|
|
||||||
if (!found) {
|
|
||||||
cur_node = NULL;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//printf("DURING CALL : cur_node = %p\n", cur_node);
|
|
||||||
//printf("DURING CALL : cur_node->name = %s\n", cur_node->name);
|
|
||||||
|
|
||||||
// Lookup in properties
|
|
||||||
if (cur_node && cur_node->properties) {
|
|
||||||
attribute = cur_node->properties;
|
|
||||||
|
|
||||||
while(attribute && attribute->name && attribute->children) {
|
|
||||||
//printf("attr name : %s\n", attribute->name);
|
|
||||||
if (!xmlStrcmp(attribute->name, (const xmlChar *)"site")) {
|
|
||||||
value = xmlNodeListGetString(cur_node->doc, attribute->children, 1);
|
|
||||||
new_arrow->site = strtol((char *)value, NULL, 0);
|
|
||||||
xmlFree(value);
|
|
||||||
check |= READ_SITE;
|
|
||||||
}
|
|
||||||
if (!xmlStrcmp(attribute->name, (const xmlChar *)"weight")) {
|
|
||||||
value = xmlNodeListGetString(cur_node->doc, attribute->children, 1);
|
|
||||||
new_arrow->load = strtol((char *)value, NULL, 0);
|
|
||||||
xmlFree(value);
|
|
||||||
check |= READ_WEIGHT;
|
|
||||||
}
|
|
||||||
if (!xmlStrcmp(attribute->name, (const xmlChar *)"x")) {
|
|
||||||
value = xmlNodeListGetString(cur_node->doc, attribute->children, 1);
|
|
||||||
new_arrow->x = strtol((char *)value, NULL, 0);
|
|
||||||
xmlFree(value);
|
|
||||||
check |= READ_X;
|
|
||||||
}
|
|
||||||
if (!xmlStrcmp(attribute->name, (const xmlChar *)"y")) {
|
|
||||||
value = xmlNodeListGetString(cur_node->doc, attribute->children, 1);
|
|
||||||
new_arrow->y = strtol((char *)value, NULL, 0);
|
|
||||||
xmlFree(value);
|
|
||||||
check |= READ_Y;
|
|
||||||
}
|
|
||||||
if (!xmlStrcmp(attribute->name, (const xmlChar *)"z")) {
|
|
||||||
value = xmlNodeListGetString(cur_node->doc, attribute->children, 1);
|
|
||||||
new_arrow->z = strtol((char *)value, NULL, 0);
|
|
||||||
xmlFree(value);
|
|
||||||
check |= READ_Z;
|
|
||||||
}
|
|
||||||
attribute = attribute->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(dimension) {
|
|
||||||
case 3:
|
|
||||||
return (bool)(check & SUCCESSFUL_READ_ARROW_XYZ);
|
|
||||||
case 2:
|
|
||||||
return (bool)(check & SUCCESSFUL_READ_ARROW_XY);
|
|
||||||
case 1:
|
|
||||||
return (bool)(check & SUCCESSFUL_READ_ARROW_X);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cur_node = NULL;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool model_get_next_conditions (struct model_t *self, char *new_cond_id)
|
|
||||||
{
|
|
||||||
static xmlNodePtr cur_node = NULL;
|
|
||||||
xmlAttr *attribute;
|
|
||||||
xmlChar *value;
|
|
||||||
|
|
||||||
printlog("NEW CALL : cur_node = %p\n", cur_node);
|
|
||||||
|
|
||||||
if (cur_node == NULL) {
|
|
||||||
// Get first state
|
|
||||||
cur_node = model_get_node(self, (xmlChar *)"conditions");
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// Get next state
|
|
||||||
if (cur_node->next)
|
|
||||||
cur_node = cur_node->next;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
printlog("END CALL : cur_node = %p\n", cur_node);
|
|
||||||
|
|
||||||
// Lookup in properties
|
|
||||||
if (model_get_node_str_attrib(cur_node, "id", new_cond_id))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
cur_node = NULL;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool model_get_next_condition (struct model_t *self,
|
|
||||||
struct condition_t *new_condition,
|
|
||||||
const char *cond_id,
|
|
||||||
char dimension)
|
|
||||||
{
|
|
||||||
static xmlNodePtr cur_node = NULL;
|
|
||||||
xmlAttr *attribute;
|
|
||||||
xmlChar *value;
|
|
||||||
bool found = false;
|
|
||||||
char temp_char[25];
|
|
||||||
uint check = 0; // bit field checker
|
|
||||||
|
|
||||||
printlog("NEW CALL : cur_node = %p\n", cur_node);
|
|
||||||
|
|
||||||
assert(new_condition);
|
|
||||||
assert(cond_id);
|
|
||||||
|
|
||||||
if (cur_node == NULL) {
|
|
||||||
// Get first state node
|
|
||||||
cur_node = model_get_node(self, (xmlChar *)"conditions");
|
|
||||||
|
|
||||||
// Lookup in properties
|
|
||||||
while (cur_node && cur_node->properties) {
|
|
||||||
attribute = cur_node->properties;
|
|
||||||
|
|
||||||
// Look for the id attribute
|
|
||||||
if (model_get_node_str_attrib(cur_node, "id", &temp_char)) {
|
|
||||||
if (!xmlStrcmp(temp_char, (const xmlChar *)cond_id)) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cur_node = cur_node->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the state has been found
|
|
||||||
if (!found) {
|
|
||||||
cur_node = NULL;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get first arrow
|
|
||||||
if (cur_node->children) {
|
|
||||||
cur_node = cur_node->children;
|
|
||||||
|
|
||||||
found = false;
|
|
||||||
while (cur_node && cur_node->name) {
|
|
||||||
if (!xmlStrcmp(cur_node->name, (const xmlChar *)"arrow")) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
cur_node = cur_node->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the state has been found
|
|
||||||
if (!found) {
|
|
||||||
cur_node = NULL;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// Get next condition
|
|
||||||
found = false;
|
|
||||||
while (cur_node->next) {
|
|
||||||
cur_node = cur_node->next;
|
|
||||||
if (!xmlStrcmp(cur_node->name, (const xmlChar *)"arrow")) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the state has been found
|
|
||||||
if (!found) {
|
|
||||||
cur_node = NULL;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printlog("DURING CALL : cur_node = %p\n", cur_node);
|
|
||||||
printlog("DURING CALL : cur_node->name = %s\n", cur_node->name);
|
|
||||||
|
|
||||||
// Lookup in properties
|
|
||||||
if (cur_node && cur_node->properties) {
|
|
||||||
attribute = cur_node->properties;
|
|
||||||
|
|
||||||
while(attribute && attribute->name && attribute->children) {
|
|
||||||
//printf("attr name : %s\n", attribute->name);
|
|
||||||
if (!xmlStrcmp(attribute->name, (const xmlChar *)"site")) {
|
|
||||||
value = xmlNodeListGetString(cur_node->doc, attribute->children, 1);
|
|
||||||
new_condition->site = strtol((char *)value, NULL, 0);
|
|
||||||
xmlFree(value);
|
|
||||||
check |= READ_SITE;
|
|
||||||
}
|
|
||||||
if (!xmlStrcmp(attribute->name, (const xmlChar *)"weight")) {
|
|
||||||
value = xmlNodeListGetString(cur_node->doc, attribute->children, 1);
|
|
||||||
new_condition->load = strtol((char *)value, NULL, 0);
|
|
||||||
xmlFree(value);
|
|
||||||
check |= READ_WEIGHT;
|
|
||||||
}
|
|
||||||
if (!xmlStrcmp(attribute->name, (const xmlChar *)"x")) {
|
|
||||||
value = xmlNodeListGetString(cur_node->doc, attribute->children, 1);
|
|
||||||
new_condition->x = strtol((char *)value, NULL, 0);
|
|
||||||
xmlFree(value);
|
|
||||||
check |= READ_X;
|
|
||||||
}
|
|
||||||
if (!xmlStrcmp(attribute->name, (const xmlChar *)"y")) {
|
|
||||||
value = xmlNodeListGetString(cur_node->doc, attribute->children, 1);
|
|
||||||
new_condition->y = strtol((char *)value, NULL, 0);
|
|
||||||
xmlFree(value);
|
|
||||||
check |= READ_Y;
|
|
||||||
}
|
|
||||||
if (!xmlStrcmp(attribute->name, (const xmlChar *)"z")) {
|
|
||||||
value = xmlNodeListGetString(cur_node->doc, attribute->children, 1);
|
|
||||||
new_condition->z = strtol((char *)value, NULL, 0);
|
|
||||||
xmlFree(value);
|
|
||||||
check |= READ_Z;
|
|
||||||
}
|
|
||||||
attribute = attribute->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(dimension) {
|
|
||||||
case 3:
|
|
||||||
return (bool)(check & SUCCESSFUL_READ_ARROW_XYZ);
|
|
||||||
case 2:
|
|
||||||
return (bool)(check & SUCCESSFUL_READ_ARROW_XY);
|
|
||||||
case 1:
|
|
||||||
return (bool)(check & SUCCESSFUL_READ_ARROW_X);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cur_node = NULL;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static bool model_init(struct model_t *self)
|
static bool model_init(struct model_t *self)
|
||||||
|
|
Loading…
Reference in New Issue